summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/gdb_machdep.c4
-rw-r--r--sys/amd64/amd64/trap.c4
-rw-r--r--sys/amd64/conf/NOTES17
-rw-r--r--sys/amd64/include/vmm.h35
-rw-r--r--sys/amd64/include/vmm_dev.h38
-rw-r--r--sys/amd64/linux/linux_machdep.c2
-rw-r--r--sys/amd64/linux32/linux32_machdep.c2
-rw-r--r--sys/amd64/vmm/amd/svm.c2
-rw-r--r--sys/amd64/vmm/intel/vmx.c2
-rw-r--r--sys/amd64/vmm/io/ppt.c16
-rw-r--r--sys/amd64/vmm/vmm.c471
-rw-r--r--sys/amd64/vmm/vmm_dev.c398
-rw-r--r--sys/amd64/vmm/vmm_instruction_emul.c12
-rw-r--r--sys/amd64/vmm/vmm_mem.c32
-rw-r--r--sys/amd64/vmm/vmm_mem.h2
-rw-r--r--sys/arm/arm/bcopyinout.S3
-rw-r--r--sys/arm/arm/bcopyinout_xscale.S4
-rw-r--r--sys/arm/arm/copystr.S3
-rw-r--r--sys/arm/arm/generic_timer.c112
-rw-r--r--sys/arm/arm/locore-v4.S3
-rw-r--r--sys/arm/arm/locore-v6.S2
-rw-r--r--sys/arm/arm/machdep.c2
-rw-r--r--sys/arm/arm/trap-v6.c4
-rw-r--r--sys/arm/arm/trap.c19
-rw-r--r--sys/arm/conf/BEAGLEBONE8
-rw-r--r--sys/arm/conf/NOTES23
-rw-r--r--sys/arm/include/pcpu.h6
-rw-r--r--sys/arm/ti/am335x/am335x_lcd.c579
-rw-r--r--sys/arm/ti/am335x/am335x_lcd.h8
-rw-r--r--sys/arm/ti/am335x/am335x_pmic.c2
-rw-r--r--sys/arm/ti/am335x/am335x_prcm.c88
-rw-r--r--sys/arm/ti/am335x/files.am335x3
-rw-r--r--sys/arm/ti/am335x/hdmi.h38
-rw-r--r--sys/arm/ti/am335x/hdmi_if.m50
-rw-r--r--sys/arm/ti/am335x/tda19988.c810
-rw-r--r--sys/arm/ti/am335x/tps65217x.h2
-rw-r--r--sys/arm/ti/omap4/omap4_prcm_clks.c14
-rw-r--r--sys/arm/ti/ti_prcm.c37
-rw-r--r--sys/arm/ti/ti_prcm.h3
-rw-r--r--sys/arm64/acpica/OsdEnvironment.c76
-rw-r--r--sys/arm64/acpica/acpi_machdep.c217
-rw-r--r--sys/arm64/acpica/acpi_wakeup.c61
-rw-r--r--sys/arm64/arm64/db_interface.c4
-rw-r--r--sys/arm64/arm64/db_trace.c25
-rw-r--r--sys/arm64/arm64/gic.c58
-rw-r--r--sys/arm64/arm64/gic.h54
-rw-r--r--sys/arm64/arm64/gic_acpi.c161
-rw-r--r--sys/arm64/arm64/gic_fdt.c87
-rw-r--r--sys/arm64/arm64/machdep.c2
-rw-r--r--sys/arm64/arm64/nexus.c166
-rw-r--r--sys/arm64/arm64/unwind.c52
-rw-r--r--sys/arm64/arm64/vfp.c2
-rw-r--r--sys/arm64/conf/GENERIC1
-rw-r--r--sys/arm64/include/acpica_machdep.h55
-rw-r--r--sys/arm64/include/atomic.h28
-rw-r--r--sys/arm64/include/iodev.h65
-rw-r--r--sys/arm64/include/pci_cfgreg.h1
-rw-r--r--sys/arm64/include/pcpu.h3
-rw-r--r--sys/arm64/include/stack.h8
-rw-r--r--sys/boot/Makefile2
-rw-r--r--sys/boot/common/Makefile10
-rw-r--r--sys/boot/common/Makefile.inc5
-rw-r--r--sys/boot/efi/libefi/Makefile.depend17
-rw-r--r--sys/boot/efi/loader/arch/arm64/exec.c40
-rw-r--r--sys/boot/fdt/dts/arm/beaglebone-black.dts22
-rw-r--r--sys/boot/ficl/Makefile.depend21
-rw-r--r--sys/boot/i386/boot0/Makefile.depend15
-rw-r--r--sys/boot/i386/boot0sio/Makefile.depend15
-rw-r--r--sys/boot/i386/boot2/Makefile.depend15
-rw-r--r--sys/boot/i386/loader/Makefile1
-rw-r--r--sys/boot/i386/loader/Makefile.depend15
-rw-r--r--sys/boot/i386/zfsloader/Makefile.depend15
-rw-r--r--sys/boot/mips/beri/loader/Makefile1
-rw-r--r--sys/boot/pc98/loader/Makefile1
-rw-r--r--sys/boot/powerpc/kboot/Makefile1
-rw-r--r--sys/boot/powerpc/ofw/Makefile1
-rw-r--r--sys/boot/powerpc/ps3/Makefile1
-rw-r--r--sys/boot/sparc64/loader/Makefile1
-rw-r--r--sys/boot/uboot/lib/copy.c7
-rw-r--r--sys/boot/uboot/lib/glue.c2
-rw-r--r--sys/cam/cam.c50
-rw-r--r--sys/cam/cam.h12
-rw-r--r--sys/cam/ctl/ctl.c200
-rw-r--r--sys/cam/ctl/ctl_frontend.c28
-rw-r--r--sys/cam/ctl/ctl_frontend.h6
-rw-r--r--sys/cam/ctl/ctl_frontend_cam_sim.c8
-rw-r--r--sys/cam/ctl/ctl_frontend_internal.c24
-rw-r--r--sys/cam/ctl/ctl_frontend_iscsi.c10
-rw-r--r--sys/cam/ctl/ctl_private.h4
-rw-r--r--sys/cam/ctl/ctl_tpc.c31
-rw-r--r--sys/cam/ctl/ctl_tpc_local.c8
-rw-r--r--sys/cam/ctl/scsi_ctl.c123
-rw-r--r--sys/cam/scsi/scsi_all.c892
-rw-r--r--sys/cam/scsi/scsi_all.h283
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c6
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c34
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c76
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c5
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dbuf.h4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c18
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c25
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c33
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c24
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/sysmacros.h11
-rw-r--r--sys/cddl/dev/dtrace/arm/dtrace_asm.S1
-rw-r--r--sys/compat/linux/linux_event.c4
-rw-r--r--sys/compat/linux/linux_event.h2
-rw-r--r--sys/compat/linux/linux_file.c3
-rw-r--r--sys/compat/linux/linux_fork.c2
-rw-r--r--sys/compat/linux/linux_misc.c14
-rw-r--r--sys/compat/svr4/imgact_svr4.c2
-rw-r--r--sys/compat/svr4/svr4_misc.c30
-rw-r--r--sys/compat/svr4/svr4_resource.c16
-rw-r--r--sys/conf/NOTES2
-rw-r--r--sys/conf/files24
-rw-r--r--sys/conf/files.amd647
-rw-r--r--sys/conf/files.arm5
-rw-r--r--sys/conf/files.arm648
-rw-r--r--sys/conf/files.i3867
-rw-r--r--sys/conf/files.mips2
-rw-r--r--sys/conf/files.powerpc7
-rw-r--r--sys/conf/kern.post.mk20
-rw-r--r--sys/conf/kern.pre.mk25
-rw-r--r--sys/conf/kmod.mk11
-rwxr-xr-xsys/contrib/dev/acpica/acpica_prep.sh24
-rw-r--r--sys/contrib/dev/acpica/changes.txt129
-rw-r--r--sys/contrib/dev/acpica/common/adisasm.c2
-rw-r--r--sys/contrib/dev/acpica/common/ahids.c2
-rw-r--r--sys/contrib/dev/acpica/common/ahpredef.c2
-rw-r--r--sys/contrib/dev/acpica/common/ahuuids.c2
-rw-r--r--sys/contrib/dev/acpica/common/dmextern.c16
-rw-r--r--sys/contrib/dev/acpica/common/dmrestag.c8
-rw-r--r--sys/contrib/dev/acpica/common/dmtable.c4
-rw-r--r--sys/contrib/dev/acpica/common/dmtbdump.c6
-rw-r--r--sys/contrib/dev/acpica/common/dmtbinfo.c13
-rw-r--r--sys/contrib/dev/acpica/common/getopt.c4
-rw-r--r--sys/contrib/dev/acpica/compiler/aslanalyze.c10
-rw-r--r--sys/contrib/dev/acpica/compiler/aslascii.c2
-rw-r--r--sys/contrib/dev/acpica/compiler/aslcodegen.c11
-rw-r--r--sys/contrib/dev/acpica/compiler/aslcompile.c13
-rw-r--r--sys/contrib/dev/acpica/compiler/aslcompiler.h2
-rw-r--r--sys/contrib/dev/acpica/compiler/aslcompiler.l2
-rw-r--r--sys/contrib/dev/acpica/compiler/asldefine.h5
-rw-r--r--sys/contrib/dev/acpica/compiler/aslerror.c6
-rw-r--r--sys/contrib/dev/acpica/compiler/aslfileio.c38
-rw-r--r--sys/contrib/dev/acpica/compiler/aslfiles.c55
-rw-r--r--sys/contrib/dev/acpica/compiler/aslfold.c59
-rw-r--r--sys/contrib/dev/acpica/compiler/aslglobal.h4
-rw-r--r--sys/contrib/dev/acpica/compiler/aslmain.c2
-rw-r--r--sys/contrib/dev/acpica/compiler/aslmapenter.c8
-rw-r--r--sys/contrib/dev/acpica/compiler/aslmapoutput.c4
-rw-r--r--sys/contrib/dev/acpica/compiler/aslmethod.c4
-rw-r--r--sys/contrib/dev/acpica/compiler/aslopcodes.c6
-rw-r--r--sys/contrib/dev/acpica/compiler/asloperands.c6
-rw-r--r--sys/contrib/dev/acpica/compiler/aslopt.c22
-rw-r--r--sys/contrib/dev/acpica/compiler/asloptions.c1
-rw-r--r--sys/contrib/dev/acpica/compiler/aslprintf.c4
-rw-r--r--sys/contrib/dev/acpica/compiler/aslstartup.c2
-rw-r--r--sys/contrib/dev/acpica/compiler/aslsupport.l9
-rw-r--r--sys/contrib/dev/acpica/compiler/asltypes.h54
-rw-r--r--sys/contrib/dev/acpica/compiler/aslutils.c25
-rw-r--r--sys/contrib/dev/acpica/compiler/asluuid.c2
-rw-r--r--sys/contrib/dev/acpica/compiler/dtcompile.c8
-rw-r--r--sys/contrib/dev/acpica/compiler/dtcompiler.h8
-rw-r--r--sys/contrib/dev/acpica/compiler/dtexpress.c2
-rw-r--r--sys/contrib/dev/acpica/compiler/dtfield.c12
-rw-r--r--sys/contrib/dev/acpica/compiler/dtio.c30
-rw-r--r--sys/contrib/dev/acpica/compiler/dtparser.y15
-rw-r--r--sys/contrib/dev/acpica/compiler/dtsubtable.c4
-rw-r--r--sys/contrib/dev/acpica/compiler/dttable.c6
-rw-r--r--sys/contrib/dev/acpica/compiler/dttemplate.c28
-rw-r--r--sys/contrib/dev/acpica/compiler/dttemplate.h11
-rw-r--r--sys/contrib/dev/acpica/compiler/dtutils.c10
-rw-r--r--sys/contrib/dev/acpica/compiler/prparser.y11
-rw-r--r--sys/contrib/dev/acpica/compiler/prscan.c160
-rw-r--r--sys/contrib/dev/acpica/compiler/prutils.c9
-rw-r--r--sys/contrib/dev/acpica/components/debugger/dbcmds.c16
-rw-r--r--sys/contrib/dev/acpica/components/debugger/dbconvert.c8
-rw-r--r--sys/contrib/dev/acpica/components/debugger/dbdisply.c2
-rw-r--r--sys/contrib/dev/acpica/components/debugger/dbexec.c14
-rw-r--r--sys/contrib/dev/acpica/components/debugger/dbfileio.c2
-rw-r--r--sys/contrib/dev/acpica/components/debugger/dbhistry.c8
-rw-r--r--sys/contrib/dev/acpica/components/debugger/dbinput.c10
-rw-r--r--sys/contrib/dev/acpica/components/debugger/dbmethod.c8
-rw-r--r--sys/contrib/dev/acpica/components/debugger/dbnames.c10
-rw-r--r--sys/contrib/dev/acpica/components/debugger/dbtest.c20
-rw-r--r--sys/contrib/dev/acpica/components/debugger/dbutils.c4
-rw-r--r--sys/contrib/dev/acpica/components/debugger/dbxface.c2
-rw-r--r--sys/contrib/dev/acpica/components/disassembler/dmbuffer.c8
-rw-r--r--sys/contrib/dev/acpica/components/disassembler/dmcstyle.c89
-rw-r--r--sys/contrib/dev/acpica/components/disassembler/dmopcode.c6
-rw-r--r--sys/contrib/dev/acpica/components/dispatcher/dsfield.c2
-rw-r--r--sys/contrib/dev/acpica/components/dispatcher/dsinit.c2
-rw-r--r--sys/contrib/dev/acpica/components/dispatcher/dsobject.c4
-rw-r--r--sys/contrib/dev/acpica/components/dispatcher/dsutils.c2
-rw-r--r--sys/contrib/dev/acpica/components/dispatcher/dswload.c15
-rw-r--r--sys/contrib/dev/acpica/components/events/evgpe.c5
-rw-r--r--sys/contrib/dev/acpica/components/events/evgpeinit.c2
-rw-r--r--sys/contrib/dev/acpica/components/executer/exconfig.c2
-rw-r--r--sys/contrib/dev/acpica/components/executer/exconvrt.c4
-rw-r--r--sys/contrib/dev/acpica/components/executer/exdebug.c35
-rw-r--r--sys/contrib/dev/acpica/components/executer/exdump.c13
-rw-r--r--sys/contrib/dev/acpica/components/executer/exfield.c2
-rw-r--r--sys/contrib/dev/acpica/components/executer/exfldio.c18
-rw-r--r--sys/contrib/dev/acpica/components/executer/exmisc.c18
-rw-r--r--sys/contrib/dev/acpica/components/executer/exnames.c2
-rw-r--r--sys/contrib/dev/acpica/components/executer/exoparg2.c9
-rw-r--r--sys/contrib/dev/acpica/components/executer/exoparg3.c2
-rw-r--r--sys/contrib/dev/acpica/components/executer/exregion.c4
-rw-r--r--sys/contrib/dev/acpica/components/executer/exstorob.c12
-rw-r--r--sys/contrib/dev/acpica/components/executer/exutils.c37
-rw-r--r--sys/contrib/dev/acpica/components/hardware/hwgpe.c13
-rw-r--r--sys/contrib/dev/acpica/components/hardware/hwxfsleep.c93
-rw-r--r--sys/contrib/dev/acpica/components/namespace/nsaccess.c17
-rw-r--r--sys/contrib/dev/acpica/components/namespace/nsconvert.c4
-rw-r--r--sys/contrib/dev/acpica/components/namespace/nsdump.c2
-rw-r--r--sys/contrib/dev/acpica/components/namespace/nseval.c7
-rw-r--r--sys/contrib/dev/acpica/components/namespace/nsinit.c4
-rw-r--r--sys/contrib/dev/acpica/components/namespace/nsparse.c8
-rw-r--r--sys/contrib/dev/acpica/components/namespace/nsrepair2.c2
-rw-r--r--sys/contrib/dev/acpica/components/namespace/nssearch.c38
-rw-r--r--sys/contrib/dev/acpica/components/namespace/nsutils.c2
-rw-r--r--sys/contrib/dev/acpica/components/namespace/nsxfeval.c4
-rw-r--r--sys/contrib/dev/acpica/components/namespace/nsxfname.c32
-rw-r--r--sys/contrib/dev/acpica/components/parser/psutils.c2
-rw-r--r--sys/contrib/dev/acpica/components/resources/rscreate.c4
-rw-r--r--sys/contrib/dev/acpica/components/resources/rsmisc.c8
-rw-r--r--sys/contrib/dev/acpica/components/resources/rsutils.c8
-rw-r--r--sys/contrib/dev/acpica/components/resources/rsxface.c6
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbdata.c4
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbfadt.c21
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbfind.c14
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbinstal.c4
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbprint.c6
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbutils.c34
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbxface.c6
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbxfload.c13
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utalloc.c6
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utbuffer.c4
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utcache.c6
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utcopy.c16
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utids.c104
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utmisc.c7
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utosi.c8
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utpredef.c4
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utprint.c6
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utstring.c32
-rw-r--r--sys/contrib/dev/acpica/components/utilities/uttrack.c8
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utxface.c6
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utxfinit.c11
-rw-r--r--sys/contrib/dev/acpica/include/acclib.h167
-rw-r--r--sys/contrib/dev/acpica/include/accommon.h3
-rw-r--r--sys/contrib/dev/acpica/include/acglobal.h2
-rw-r--r--sys/contrib/dev/acpica/include/acinterp.h5
-rw-r--r--sys/contrib/dev/acpica/include/aclocal.h1
-rw-r--r--sys/contrib/dev/acpica/include/acnames.h1
-rw-r--r--sys/contrib/dev/acpica/include/acnamesp.h1
-rw-r--r--sys/contrib/dev/acpica/include/acobject.h15
-rw-r--r--sys/contrib/dev/acpica/include/acoutput.h13
-rw-r--r--sys/contrib/dev/acpica/include/acpixf.h26
-rw-r--r--sys/contrib/dev/acpica/include/acstruct.h1
-rw-r--r--sys/contrib/dev/acpica/include/actbl.h1
-rw-r--r--sys/contrib/dev/acpica/include/actbl1.h14
-rw-r--r--sys/contrib/dev/acpica/include/actbl2.h87
-rw-r--r--sys/contrib/dev/acpica/include/actbl3.h39
-rw-r--r--sys/contrib/dev/acpica/include/actypes.h37
-rw-r--r--sys/contrib/dev/acpica/include/acutils.h113
-rw-r--r--sys/contrib/dev/acpica/include/platform/acenv.h38
-rw-r--r--sys/contrib/dev/acpica/include/platform/acenvex.h6
-rw-r--r--sys/contrib/dev/acpica/include/platform/acgcc.h4
-rw-r--r--sys/ddb/db_sym.c2
-rw-r--r--sys/dev/acpi_support/acpi_ibm.c5
-rw-r--r--sys/dev/acpica/Osd/OsdHardware.c10
-rw-r--r--sys/dev/acpica/acpi_cpu.c18
-rw-r--r--sys/dev/atkbdc/psm.c146
-rw-r--r--sys/dev/bxe/bxe.c123
-rw-r--r--sys/dev/bxe/bxe.h6
-rw-r--r--sys/dev/bxe/ecore_reg.h1
-rw-r--r--sys/dev/bxe/ecore_sp.c2
-rw-r--r--sys/dev/cxgbe/adapter.h22
-rw-r--r--sys/dev/cxgbe/common/t4_hw.c4
-rw-r--r--sys/dev/cxgbe/t4_main.c6
-rw-r--r--sys/dev/drm2/i915/i915_gem.c5
-rw-r--r--sys/dev/drm2/ttm/ttm_page_alloc.c109
-rw-r--r--sys/dev/filemon/filemon.h2
-rw-r--r--sys/dev/filemon/filemon_wrapper.c78
-rw-r--r--sys/dev/gpio/ofw_gpiobus.c8
-rw-r--r--sys/dev/hwpmc/hwpmc_armv7.c90
-rw-r--r--sys/dev/hwpmc/hwpmc_armv7.h5
-rw-r--r--sys/dev/hwpmc/pmc_events.h369
-rw-r--r--sys/dev/ichsmb/ichsmb_pci.c8
-rw-r--r--sys/dev/isp/isp_freebsd.c8
-rw-r--r--sys/dev/iwn/if_iwn.c140
-rw-r--r--sys/dev/iwn/if_iwnvar.h11
-rw-r--r--sys/dev/ixl/if_ixl.c2
-rw-r--r--sys/dev/mii/mii.h43
-rw-r--r--sys/dev/ofw/ofw_bus_subr.c41
-rw-r--r--sys/dev/ofw/ofw_bus_subr.h3
-rw-r--r--sys/dev/pci/pci_host_generic.c626
-rw-r--r--sys/dev/proto/proto_bus_pci.c19
-rw-r--r--sys/dev/proto/proto_busdma.c22
-rw-r--r--sys/dev/proto/proto_dev.h6
-rw-r--r--sys/dev/uart/uart_bus_pci.c7
-rw-r--r--sys/dev/usb/misc/ugold.c405
-rw-r--r--sys/dev/usb/usbdevs7
-rw-r--r--sys/dev/videomode/videomode.h1
-rw-r--r--sys/dev/virtio/mmio/virtio_mmio.h4
-rw-r--r--sys/dev/virtio/network/if_vtnet.c10
-rw-r--r--sys/dev/xen/blkback/blkback.c222
-rw-r--r--sys/dev/xen/blkfront/blkfront.c212
-rw-r--r--sys/dev/xen/blkfront/block.h20
-rw-r--r--sys/fs/fdescfs/fdesc_vfsops.c4
-rw-r--r--sys/fs/fdescfs/fdesc_vnops.c2
-rw-r--r--sys/fs/nfsclient/nfs_clbio.c6
-rw-r--r--sys/fs/tmpfs/tmpfs_subr.c11
-rw-r--r--sys/geom/label/g_label.c15
-rw-r--r--sys/geom/label/g_label.h2
-rw-r--r--sys/geom/label/g_label_iso9660.c10
-rw-r--r--sys/geom/label/g_label_msdosfs.c10
-rw-r--r--sys/i386/conf/NOTES17
-rw-r--r--sys/i386/i386/exception.s36
-rw-r--r--sys/i386/i386/gdb_machdep.c16
-rw-r--r--sys/i386/i386/machdep.c1
-rw-r--r--sys/i386/i386/trap.c4
-rw-r--r--sys/i386/ibcs2/ibcs2_misc.c34
-rw-r--r--sys/i386/include/asmacros.h9
-rw-r--r--sys/i386/include/gdb_machdep.h2
-rw-r--r--sys/i386/linux/imgact_linux.c2
-rw-r--r--sys/i386/linux/linux_machdep.c2
-rw-r--r--sys/kern/imgact_aout.c2
-rw-r--r--sys/kern/imgact_binmisc.c87
-rw-r--r--sys/kern/imgact_elf.c8
-rw-r--r--sys/kern/imgact_gzip.c2
-rw-r--r--sys/kern/init_main.c8
-rw-r--r--sys/kern/kern_descrip.c145
-rw-r--r--sys/kern/kern_event.c6
-rw-r--r--sys/kern/kern_exec.c13
-rw-r--r--sys/kern/kern_fork.c7
-rw-r--r--sys/kern/kern_jail.c2
-rw-r--r--sys/kern/kern_kthread.c2
-rw-r--r--sys/kern/kern_mutex.c34
-rw-r--r--sys/kern/kern_proc.c2
-rw-r--r--sys/kern/kern_prot.c5
-rw-r--r--sys/kern/kern_racct.c24
-rw-r--r--sys/kern/kern_resource.c92
-rw-r--r--sys/kern/kern_rwlock.c56
-rw-r--r--sys/kern/kern_sig.c2
-rw-r--r--sys/kern/kern_sx.c51
-rw-r--r--sys/kern/kern_syscalls.c3
-rw-r--r--sys/kern/kern_tc.c5
-rw-r--r--sys/kern/kern_thr.c6
-rw-r--r--sys/kern/kern_thread.c49
-rw-r--r--sys/kern/stack_protector.c5
-rw-r--r--sys/kern/subr_prf.c63
-rw-r--r--sys/kern/subr_syscall.c4
-rw-r--r--sys/kern/subr_trap.c4
-rw-r--r--sys/kern/subr_uio.c4
-rw-r--r--sys/kern/sysv_shm.c2
-rw-r--r--sys/kern/tty_pts.c4
-rw-r--r--sys/kern/uipc_shm.c18
-rw-r--r--sys/kern/uipc_sockbuf.c4
-rw-r--r--sys/kern/uipc_syscalls.c5
-rw-r--r--sys/kern/uipc_usrreq.c15
-rw-r--r--sys/kern/vfs_acl.c8
-rw-r--r--sys/kern/vfs_extattr.c8
-rw-r--r--sys/kern/vfs_subr.c46
-rw-r--r--sys/kern/vfs_syscalls.c30
-rw-r--r--sys/kern/vfs_vnops.c7
-rw-r--r--sys/mips/conf/AR934X_BASE2
-rw-r--r--sys/modules/usb/Makefile2
-rw-r--r--sys/modules/usb/ugold/Makefile13
-rw-r--r--sys/net/if_bridge.c11
-rw-r--r--sys/netinet/if_ether.c15
-rw-r--r--sys/netinet/ip_encap.c49
-rw-r--r--sys/netinet/sctp_asconf.c28
-rw-r--r--sys/netinet/sctp_input.c42
-rw-r--r--sys/netinet/sctp_input.h2
-rw-r--r--sys/netinet/sctp_os_bsd.h9
-rw-r--r--sys/netinet/sctp_output.c151
-rw-r--r--sys/netinet/sctp_output.h6
-rw-r--r--sys/netinet/sctp_pcb.c5
-rw-r--r--sys/netinet/sctp_pcb.h1
-rw-r--r--sys/netinet/sctp_syscalls.c8
-rw-r--r--sys/netinet/sctp_usrreq.c42
-rw-r--r--sys/netinet/sctp_var.h1
-rw-r--r--sys/netinet/sctputil.c8
-rw-r--r--sys/netinet/sctputil.h2
-rw-r--r--sys/netinet/tcp_timer.c55
-rw-r--r--sys/netinet/tcp_timer.h6
-rw-r--r--sys/netinet6/sctp6_usrreq.c4
-rw-r--r--sys/netipsec/key.c8
-rw-r--r--sys/netipsec/key.h1
-rw-r--r--sys/netpfil/pf/pf_norm.c12
-rw-r--r--sys/ofed/drivers/infiniband/core/umem.c2
-rw-r--r--sys/ofed/drivers/infiniband/hw/mthca/mthca_memfree.c3
-rw-r--r--sys/ofed/include/linux/file.h16
-rw-r--r--sys/opencrypto/crypto.c2
-rw-r--r--sys/powerpc/conf/NOTES22
-rw-r--r--sys/powerpc/powerpc/trap.c4
-rw-r--r--sys/security/audit/audit_arg.c4
-rw-r--r--sys/sparc64/sparc64/trap.c4
-rw-r--r--sys/sys/filedesc.h10
-rw-r--r--sys/sys/lockstat.h3
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/pmc.h7
-rw-r--r--sys/sys/proc.h14
-rw-r--r--sys/sys/resourcevar.h11
-rw-r--r--sys/sys/sbuf.h10
-rw-r--r--sys/sys/vnode.h2
-rw-r--r--sys/ufs/ffs/ffs_alloc.c4
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c14
-rw-r--r--sys/vm/swap_pager.c8
-rw-r--r--sys/vm/vm_fault.c13
-rw-r--r--sys/vm/vm_glue.c17
-rw-r--r--sys/vm/vm_kern.c3
-rw-r--r--sys/vm/vm_map.c14
-rw-r--r--sys/vm/vm_mmap.c12
-rw-r--r--sys/vm/vm_object.c8
-rw-r--r--sys/vm/vm_pageout.c34
-rw-r--r--sys/vm/vm_pager.c72
-rw-r--r--sys/vm/vm_pager.h40
-rw-r--r--sys/vm/vm_unix.c8
-rw-r--r--sys/x86/acpica/acpi_wakeup.c4
-rw-r--r--sys/xen/blkif.h8
-rw-r--r--sys/xen/interface/io/blkif.h42
432 files changed, 10168 insertions, 3333 deletions
diff --git a/sys/amd64/amd64/gdb_machdep.c b/sys/amd64/amd64/gdb_machdep.c
index 5775c8f..61ffad6 100644
--- a/sys/amd64/amd64/gdb_machdep.c
+++ b/sys/amd64/amd64/gdb_machdep.c
@@ -48,6 +48,8 @@ __FBSDID("$FreeBSD$");
void *
gdb_cpu_getreg(int regnum, size_t *regsz)
{
+ static uint32_t _kcodesel = GSEL(GCODE_SEL, SEL_KPL);
+ static uint32_t _kdatasel = GSEL(GDATA_SEL, SEL_KPL);
*regsz = gdb_cpu_regsz(regnum);
@@ -76,6 +78,8 @@ gdb_cpu_getreg(int regnum, size_t *regsz)
case 14: return (&kdb_thrctx->pcb_r14);
case 15: return (&kdb_thrctx->pcb_r15);
case 16: return (&kdb_thrctx->pcb_rip);
+ case 18: return (&_kcodesel);
+ case 19: return (&_kdatasel);
}
return (NULL);
}
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 0836375..fa74eb2 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -257,8 +257,8 @@ trap(struct trapframe *frame)
td->td_pticks = 0;
td->td_frame = frame;
addr = frame->tf_rip;
- if (td->td_ucred != p->p_ucred)
- cred_update_thread(td);
+ if (td->td_cowgen != p->p_cowgen)
+ thread_cow_update(td);
switch (type) {
case T_PRIVINFLT: /* privileged instruction fault */
diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES
index e0fe465..97eefbf 100644
--- a/sys/amd64/conf/NOTES
+++ b/sys/amd64/conf/NOTES
@@ -17,6 +17,23 @@ profile 2
#
options KDTRACE_HOOKS
+# DTrace core
+# NOTE: introduces CDDL-licensed components into the kernel
+#device dtrace
+
+# DTrace modules
+#device dtrace_lockstat
+#device dtrace_profile
+#device dtrace_sdt
+#device dtrace_fbt
+#device dtrace_systrace
+#device dtrace_prototype
+#device dtnfscl
+#device dtmalloc
+
+# Alternatively include all the DTrace modules
+#device dtraceall
+
#####################################################################
# SMP OPTIONS:
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
index 1a4e5ab..f2de960 100644
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -108,7 +108,6 @@ enum x2apic_state {
struct vm;
struct vm_exception;
-struct vm_memory_segment;
struct seg_desc;
struct vm_exit;
struct vm_run;
@@ -175,17 +174,33 @@ int vm_create(const char *name, struct vm **retvm);
void vm_destroy(struct vm *vm);
int vm_reinit(struct vm *vm);
const char *vm_name(struct vm *vm);
-int vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len);
+
+/*
+ * APIs that modify the guest memory map require all vcpus to be frozen.
+ */
+int vm_mmap_memseg(struct vm *vm, vm_paddr_t gpa, int segid, vm_ooffset_t off,
+ size_t len, int prot, int flags);
+int vm_alloc_memseg(struct vm *vm, int ident, size_t len, bool sysmem);
+void vm_free_memseg(struct vm *vm, int ident);
int vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa);
int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len);
-void *vm_gpa_hold(struct vm *, vm_paddr_t gpa, size_t len, int prot,
- void **cookie);
+int vm_assign_pptdev(struct vm *vm, int bus, int slot, int func);
+int vm_unassign_pptdev(struct vm *vm, int bus, int slot, int func);
+
+/*
+ * APIs that inspect the guest memory map require only a *single* vcpu to
+ * be frozen. This acts like a read lock on the guest memory map since any
+ * modification requires *all* vcpus to be frozen.
+ */
+int vm_mmap_getnext(struct vm *vm, vm_paddr_t *gpa, int *segid,
+ vm_ooffset_t *segoff, size_t *len, int *prot, int *flags);
+int vm_get_memseg(struct vm *vm, int ident, size_t *len, bool *sysmem,
+ struct vm_object **objptr);
+void *vm_gpa_hold(struct vm *, int vcpuid, vm_paddr_t gpa, size_t len,
+ int prot, void **cookie);
void vm_gpa_release(void *cookie);
-int vm_gpabase2memseg(struct vm *vm, vm_paddr_t gpabase,
- struct vm_memory_segment *seg);
-int vm_get_memobj(struct vm *vm, vm_paddr_t gpa, size_t len,
- vm_offset_t *offset, struct vm_object **object);
-boolean_t vm_mem_allocated(struct vm *vm, vm_paddr_t gpa);
+bool vm_mem_allocated(struct vm *vm, int vcpuid, vm_paddr_t gpa);
+
int vm_get_register(struct vm *vm, int vcpu, int reg, uint64_t *retval);
int vm_set_register(struct vm *vm, int vcpu, int reg, uint64_t val);
int vm_get_seg_desc(struct vm *vm, int vcpu, int reg,
@@ -302,8 +317,6 @@ vcpu_should_yield(struct vm *vm, int vcpu)
void *vcpu_stats(struct vm *vm, int vcpu);
void vcpu_notify_event(struct vm *vm, int vcpuid, bool lapic_intr);
struct vmspace *vm_get_vmspace(struct vm *vm);
-int vm_assign_pptdev(struct vm *vm, int bus, int slot, int func);
-int vm_unassign_pptdev(struct vm *vm, int bus, int slot, int func);
struct vatpic *vm_atpic(struct vm *vm);
struct vatpit *vm_atpit(struct vm *vm);
struct vpmtmr *vm_pmtmr(struct vm *vm);
diff --git a/sys/amd64/include/vmm_dev.h b/sys/amd64/include/vmm_dev.h
index 9d031a9..1af75a3 100644
--- a/sys/amd64/include/vmm_dev.h
+++ b/sys/amd64/include/vmm_dev.h
@@ -34,10 +34,22 @@ void vmmdev_init(void);
int vmmdev_cleanup(void);
#endif
-struct vm_memory_segment {
- vm_paddr_t gpa; /* in */
+struct vm_memmap {
+ vm_paddr_t gpa;
+ int segid; /* memory segment */
+ vm_ooffset_t segoff; /* offset into memory segment */
+ size_t len; /* mmap length */
+ int prot; /* RWX */
+ int flags;
+};
+#define VM_MEMMAP_F_WIRED 0x01
+#define VM_MEMMAP_F_IOMMU 0x02
+
+#define VM_MEMSEG_NAME(m) ((m)->name[0] != '\0' ? (m)->name : NULL)
+struct vm_memseg {
+ int segid;
size_t len;
- int wired;
+ char name[SPECNAMELEN + 1];
};
struct vm_register {
@@ -214,10 +226,14 @@ enum {
IOCNUM_REINIT = 5,
/* memory apis */
- IOCNUM_MAP_MEMORY = 10,
- IOCNUM_GET_MEMORY_SEG = 11,
+ IOCNUM_MAP_MEMORY = 10, /* deprecated */
+ IOCNUM_GET_MEMORY_SEG = 11, /* deprecated */
IOCNUM_GET_GPA_PMAP = 12,
IOCNUM_GLA2GPA = 13,
+ IOCNUM_ALLOC_MEMSEG = 14,
+ IOCNUM_GET_MEMSEG = 15,
+ IOCNUM_MMAP_MEMSEG = 16,
+ IOCNUM_MMAP_GETNEXT = 17,
/* register/state accessors */
IOCNUM_SET_REGISTER = 20,
@@ -278,10 +294,14 @@ enum {
_IOW('v', IOCNUM_SUSPEND, struct vm_suspend)
#define VM_REINIT \
_IO('v', IOCNUM_REINIT)
-#define VM_MAP_MEMORY \
- _IOWR('v', IOCNUM_MAP_MEMORY, struct vm_memory_segment)
-#define VM_GET_MEMORY_SEG \
- _IOWR('v', IOCNUM_GET_MEMORY_SEG, struct vm_memory_segment)
+#define VM_ALLOC_MEMSEG \
+ _IOW('v', IOCNUM_ALLOC_MEMSEG, struct vm_memseg)
+#define VM_GET_MEMSEG \
+ _IOWR('v', IOCNUM_GET_MEMSEG, struct vm_memseg)
+#define VM_MMAP_MEMSEG \
+ _IOW('v', IOCNUM_MMAP_MEMSEG, struct vm_memmap)
+#define VM_MMAP_GETNEXT \
+ _IOWR('v', IOCNUM_MMAP_GETNEXT, struct vm_memmap)
#define VM_SET_REGISTER \
_IOW('v', IOCNUM_SET_REGISTER, struct vm_register)
#define VM_GET_REGISTER \
diff --git a/sys/amd64/linux/linux_machdep.c b/sys/amd64/linux/linux_machdep.c
index d6174e6..451e4b4 100644
--- a/sys/amd64/linux/linux_machdep.c
+++ b/sys/amd64/linux/linux_machdep.c
@@ -251,7 +251,7 @@ linux_mmap2(struct thread *td, struct linux_mmap2_args *args)
*/
PROC_LOCK(p);
p->p_vmspace->vm_maxsaddr = (char *)USRSTACK -
- lim_cur(p, RLIMIT_STACK);
+ lim_cur_proc(p, RLIMIT_STACK);
PROC_UNLOCK(p);
}
diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c
index f9c11ca..1c54c5c 100644
--- a/sys/amd64/linux32/linux32_machdep.c
+++ b/sys/amd64/linux32/linux32_machdep.c
@@ -615,7 +615,7 @@ linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot,
*/
PROC_LOCK(p);
p->p_vmspace->vm_maxsaddr = (char *)LINUX32_USRSTACK -
- lim_cur(p, RLIMIT_STACK);
+ lim_cur_proc(p, RLIMIT_STACK);
PROC_UNLOCK(p);
}
diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c
index b25d69d..6d44801 100644
--- a/sys/amd64/vmm/amd/svm.c
+++ b/sys/amd64/vmm/amd/svm.c
@@ -1477,7 +1477,7 @@ svm_vmexit(struct svm_softc *svm_sc, int vcpu, struct vm_exit *vmexit)
VCPU_CTR2(svm_sc->vm, vcpu, "nested page fault with "
"reserved bits set: info1(%#lx) info2(%#lx)",
info1, info2);
- } else if (vm_mem_allocated(svm_sc->vm, info2)) {
+ } else if (vm_mem_allocated(svm_sc->vm, vcpu, info2)) {
vmexit->exitcode = VM_EXITCODE_PAGING;
vmexit->u.paging.gpa = info2;
vmexit->u.paging.fault_type = npf_fault_type(info1);
diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c
index f590586..517a374 100644
--- a/sys/amd64/vmm/intel/vmx.c
+++ b/sys/amd64/vmm/intel/vmx.c
@@ -2425,7 +2425,7 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
* this must be an instruction that accesses MMIO space.
*/
gpa = vmcs_gpa();
- if (vm_mem_allocated(vmx->vm, gpa) ||
+ if (vm_mem_allocated(vmx->vm, vcpu, gpa) ||
apic_access_fault(vmx, vcpu, gpa)) {
vmexit->exitcode = VM_EXITCODE_PAGING;
vmexit->inst_length = 0;
diff --git a/sys/amd64/vmm/io/ppt.c b/sys/amd64/vmm/io/ppt.c
index b789f77..692190a 100644
--- a/sys/amd64/vmm/io/ppt.c
+++ b/sys/amd64/vmm/io/ppt.c
@@ -76,11 +76,17 @@ struct pptintr_arg { /* pptintr(pptintr_arg) */
uint64_t msg_data;
};
+struct pptseg {
+ vm_paddr_t gpa;
+ size_t len;
+ int wired;
+};
+
struct pptdev {
device_t dev;
struct vm *vm; /* owner of this device */
TAILQ_ENTRY(pptdev) next;
- struct vm_memory_segment mmio[MAX_MMIOSEGS];
+ struct pptseg mmio[MAX_MMIOSEGS];
struct {
int num_msgs; /* guest state */
@@ -207,14 +213,14 @@ static void
ppt_unmap_mmio(struct vm *vm, struct pptdev *ppt)
{
int i;
- struct vm_memory_segment *seg;
+ struct pptseg *seg;
for (i = 0; i < MAX_MMIOSEGS; i++) {
seg = &ppt->mmio[i];
if (seg->len == 0)
continue;
(void)vm_unmap_mmio(vm, seg->gpa, seg->len);
- bzero(seg, sizeof(struct vm_memory_segment));
+ bzero(seg, sizeof(struct pptseg));
}
}
@@ -324,7 +330,7 @@ ppt_is_mmio(struct vm *vm, vm_paddr_t gpa)
{
int i;
struct pptdev *ppt;
- struct vm_memory_segment *seg;
+ struct pptseg *seg;
TAILQ_FOREACH(ppt, &pptdev_list, next) {
if (ppt->vm != vm)
@@ -410,7 +416,7 @@ ppt_map_mmio(struct vm *vm, int bus, int slot, int func,
vm_paddr_t gpa, size_t len, vm_paddr_t hpa)
{
int i, error;
- struct vm_memory_segment *seg;
+ struct pptseg *seg;
struct pptdev *ppt;
ppt = ppt_find(bus, slot, func);
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index 2c37a1a..0987059 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -119,12 +119,21 @@ struct vcpu {
#define vcpu_assert_locked(v) mtx_assert(&((v)->mtx), MA_OWNED)
struct mem_seg {
+ size_t len;
+ bool sysmem;
+ struct vm_object *object;
+};
+#define VM_MAX_MEMSEGS 2
+
+struct mem_map {
vm_paddr_t gpa;
size_t len;
- boolean_t wired;
- vm_object_t object;
+ vm_ooffset_t segoff;
+ int segid;
+ int prot;
+ int flags;
};
-#define VM_MAX_MEMORY_SEGMENTS 2
+#define VM_MAX_MEMMAPS 4
/*
* Initialization:
@@ -150,8 +159,8 @@ struct vm {
void *rendezvous_arg; /* (x) rendezvous func/arg */
vm_rendezvous_func_t rendezvous_func;
struct mtx rendezvous_mtx; /* (o) rendezvous lock */
- int num_mem_segs; /* (o) guest memory segments */
- struct mem_seg mem_segs[VM_MAX_MEMORY_SEGMENTS];
+ struct mem_map mem_maps[VM_MAX_MEMMAPS]; /* (i) guest address space */
+ struct mem_seg mem_segs[VM_MAX_MEMSEGS]; /* (o) guest memory regions */
struct vmspace *vmspace; /* (o) guest's address space */
char name[VM_MAX_NAMELEN]; /* (o) virtual machine name */
struct vcpu vcpu[VM_MAXCPU]; /* (i) guest vcpus */
@@ -222,6 +231,8 @@ TUNABLE_INT("hw.vmm.force_iommu", &vmm_force_iommu);
SYSCTL_INT(_hw_vmm, OID_AUTO, force_iommu, CTLFLAG_RDTUN, &vmm_force_iommu, 0,
"Force use of I/O MMU even if no passthrough devices were found.");
+static void vm_free_memmap(struct vm *vm, int ident);
+static bool sysmem_mapping(struct vm *vm, struct mem_map *mm);
static void vcpu_notify_event_locked(struct vcpu *vcpu, bool lapic_intr);
#ifdef KTR
@@ -442,7 +453,6 @@ vm_create(const char *name, struct vm **retvm)
vm = malloc(sizeof(struct vm), M_VM, M_WAITOK | M_ZERO);
strcpy(vm->name, name);
- vm->num_mem_segs = 0;
vm->vmspace = vmspace;
mtx_init(&vm->rendezvous_mtx, "vm rendezvous lock", 0, MTX_DEF);
@@ -453,18 +463,9 @@ vm_create(const char *name, struct vm **retvm)
}
static void
-vm_free_mem_seg(struct vm *vm, struct mem_seg *seg)
-{
-
- if (seg->object != NULL)
- vmm_mem_free(vm->vmspace, seg->gpa, seg->len);
-
- bzero(seg, sizeof(*seg));
-}
-
-static void
vm_cleanup(struct vm *vm, bool destroy)
{
+ struct mem_map *mm;
int i;
ppt_unassign_all(vm);
@@ -487,11 +488,23 @@ vm_cleanup(struct vm *vm, bool destroy)
VMCLEANUP(vm->cookie);
- if (destroy) {
- for (i = 0; i < vm->num_mem_segs; i++)
- vm_free_mem_seg(vm, &vm->mem_segs[i]);
+ /*
+ * System memory is removed from the guest address space only when
+ * the VM is destroyed. This is because the mapping remains the same
+ * across VM reset.
+ *
+ * Device memory can be relocated by the guest (e.g. using PCI BARs)
+ * so those mappings are removed on a VM reset.
+ */
+ for (i = 0; i < VM_MAX_MEMMAPS; i++) {
+ mm = &vm->mem_maps[i];
+ if (destroy || !sysmem_mapping(vm, mm))
+ vm_free_memmap(vm, i);
+ }
- vm->num_mem_segs = 0;
+ if (destroy) {
+ for (i = 0; i < VM_MAX_MEMSEGS; i++)
+ vm_free_memseg(vm, i);
VMSPACE_FREE(vm->vmspace);
vm->vmspace = NULL;
@@ -549,146 +562,243 @@ vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len)
return (0);
}
-boolean_t
-vm_mem_allocated(struct vm *vm, vm_paddr_t gpa)
+/*
+ * Return 'true' if 'gpa' is allocated in the guest address space.
+ *
+ * This function is called in the context of a running vcpu which acts as
+ * an implicit lock on 'vm->mem_maps[]'.
+ */
+bool
+vm_mem_allocated(struct vm *vm, int vcpuid, vm_paddr_t gpa)
{
+ struct mem_map *mm;
int i;
- vm_paddr_t gpabase, gpalimit;
- for (i = 0; i < vm->num_mem_segs; i++) {
- gpabase = vm->mem_segs[i].gpa;
- gpalimit = gpabase + vm->mem_segs[i].len;
- if (gpa >= gpabase && gpa < gpalimit)
- return (TRUE); /* 'gpa' is regular memory */
+#ifdef INVARIANTS
+ int hostcpu, state;
+ state = vcpu_get_state(vm, vcpuid, &hostcpu);
+ KASSERT(state == VCPU_RUNNING && hostcpu == curcpu,
+ ("%s: invalid vcpu state %d/%d", __func__, state, hostcpu));
+#endif
+
+ for (i = 0; i < VM_MAX_MEMMAPS; i++) {
+ mm = &vm->mem_maps[i];
+ if (mm->len != 0 && gpa >= mm->gpa && gpa < mm->gpa + mm->len)
+ return (true); /* 'gpa' is sysmem or devmem */
}
if (ppt_is_mmio(vm, gpa))
- return (TRUE); /* 'gpa' is pci passthru mmio */
+ return (true); /* 'gpa' is pci passthru mmio */
- return (FALSE);
+ return (false);
}
int
-vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len)
+vm_alloc_memseg(struct vm *vm, int ident, size_t len, bool sysmem)
{
- int available, allocated;
struct mem_seg *seg;
- vm_object_t object;
- vm_paddr_t g;
+ vm_object_t obj;
- if ((gpa & PAGE_MASK) || (len & PAGE_MASK) || len == 0)
+ if (ident < 0 || ident >= VM_MAX_MEMSEGS)
return (EINVAL);
-
- available = allocated = 0;
- g = gpa;
- while (g < gpa + len) {
- if (vm_mem_allocated(vm, g))
- allocated++;
- else
- available++;
- g += PAGE_SIZE;
- }
-
- /*
- * If there are some allocated and some available pages in the address
- * range then it is an error.
- */
- if (allocated && available)
+ if (len == 0 || (len & PAGE_MASK))
return (EINVAL);
- /*
- * If the entire address range being requested has already been
- * allocated then there isn't anything more to do.
- */
- if (allocated && available == 0)
- return (0);
-
- if (vm->num_mem_segs >= VM_MAX_MEMORY_SEGMENTS)
- return (E2BIG);
-
- seg = &vm->mem_segs[vm->num_mem_segs];
+ seg = &vm->mem_segs[ident];
+ if (seg->object != NULL) {
+ if (seg->len == len && seg->sysmem == sysmem)
+ return (EEXIST);
+ else
+ return (EINVAL);
+ }
- if ((object = vmm_mem_alloc(vm->vmspace, gpa, len)) == NULL)
+ obj = vm_object_allocate(OBJT_DEFAULT, len >> PAGE_SHIFT);
+ if (obj == NULL)
return (ENOMEM);
- seg->gpa = gpa;
seg->len = len;
- seg->object = object;
- seg->wired = FALSE;
+ seg->object = obj;
+ seg->sysmem = sysmem;
+ return (0);
+}
- vm->num_mem_segs++;
+int
+vm_get_memseg(struct vm *vm, int ident, size_t *len, bool *sysmem,
+ vm_object_t *objptr)
+{
+ struct mem_seg *seg;
+
+ if (ident < 0 || ident >= VM_MAX_MEMSEGS)
+ return (EINVAL);
+ seg = &vm->mem_segs[ident];
+ if (len)
+ *len = seg->len;
+ if (sysmem)
+ *sysmem = seg->sysmem;
+ if (objptr)
+ *objptr = seg->object;
return (0);
}
-static vm_paddr_t
-vm_maxmem(struct vm *vm)
+void
+vm_free_memseg(struct vm *vm, int ident)
{
- int i;
- vm_paddr_t gpa, maxmem;
+ struct mem_seg *seg;
- maxmem = 0;
- for (i = 0; i < vm->num_mem_segs; i++) {
- gpa = vm->mem_segs[i].gpa + vm->mem_segs[i].len;
- if (gpa > maxmem)
- maxmem = gpa;
+ KASSERT(ident >= 0 && ident < VM_MAX_MEMSEGS,
+ ("%s: invalid memseg ident %d", __func__, ident));
+
+ seg = &vm->mem_segs[ident];
+ if (seg->object != NULL) {
+ vm_object_deallocate(seg->object);
+ bzero(seg, sizeof(struct mem_seg));
}
- return (maxmem);
}
-static void
-vm_gpa_unwire(struct vm *vm)
+int
+vm_mmap_memseg(struct vm *vm, vm_paddr_t gpa, int segid, vm_ooffset_t first,
+ size_t len, int prot, int flags)
{
- int i, rv;
struct mem_seg *seg;
+ struct mem_map *m, *map;
+ vm_ooffset_t last;
+ int i, error;
- for (i = 0; i < vm->num_mem_segs; i++) {
- seg = &vm->mem_segs[i];
- if (!seg->wired)
- continue;
+ if (prot == 0 || (prot & ~(VM_PROT_ALL)) != 0)
+ return (EINVAL);
+
+ if (flags & ~VM_MEMMAP_F_WIRED)
+ return (EINVAL);
+
+ if (segid < 0 || segid >= VM_MAX_MEMSEGS)
+ return (EINVAL);
- rv = vm_map_unwire(&vm->vmspace->vm_map,
- seg->gpa, seg->gpa + seg->len,
- VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES);
- KASSERT(rv == KERN_SUCCESS, ("vm(%s) memory segment "
- "%#lx/%ld could not be unwired: %d",
- vm_name(vm), seg->gpa, seg->len, rv));
+ seg = &vm->mem_segs[segid];
+ if (seg->object == NULL)
+ return (EINVAL);
+
+ last = first + len;
+ if (first < 0 || first >= last || last > seg->len)
+ return (EINVAL);
+
+ if ((gpa | first | last) & PAGE_MASK)
+ return (EINVAL);
+
+ map = NULL;
+ for (i = 0; i < VM_MAX_MEMMAPS; i++) {
+ m = &vm->mem_maps[i];
+ if (m->len == 0) {
+ map = m;
+ break;
+ }
+ }
- seg->wired = FALSE;
+ if (map == NULL)
+ return (ENOSPC);
+
+ error = vm_map_find(&vm->vmspace->vm_map, seg->object, first, &gpa,
+ len, 0, VMFS_NO_SPACE, prot, prot, 0);
+ if (error != KERN_SUCCESS)
+ return (EFAULT);
+
+ vm_object_reference(seg->object);
+
+ if (flags & VM_MEMMAP_F_WIRED) {
+ error = vm_map_wire(&vm->vmspace->vm_map, gpa, gpa + len,
+ VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES);
+ if (error != KERN_SUCCESS) {
+ vm_map_remove(&vm->vmspace->vm_map, gpa, gpa + len);
+ return (EFAULT);
+ }
}
+
+ map->gpa = gpa;
+ map->len = len;
+ map->segoff = first;
+ map->segid = segid;
+ map->prot = prot;
+ map->flags = flags;
+ return (0);
}
-static int
-vm_gpa_wire(struct vm *vm)
+int
+vm_mmap_getnext(struct vm *vm, vm_paddr_t *gpa, int *segid,
+ vm_ooffset_t *segoff, size_t *len, int *prot, int *flags)
{
- int i, rv;
- struct mem_seg *seg;
+ struct mem_map *mm, *mmnext;
+ int i;
- for (i = 0; i < vm->num_mem_segs; i++) {
- seg = &vm->mem_segs[i];
- if (seg->wired)
+ mmnext = NULL;
+ for (i = 0; i < VM_MAX_MEMMAPS; i++) {
+ mm = &vm->mem_maps[i];
+ if (mm->len == 0 || mm->gpa < *gpa)
continue;
+ if (mmnext == NULL || mm->gpa < mmnext->gpa)
+ mmnext = mm;
+ }
- /* XXX rlimits? */
- rv = vm_map_wire(&vm->vmspace->vm_map,
- seg->gpa, seg->gpa + seg->len,
- VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES);
- if (rv != KERN_SUCCESS)
- break;
-
- seg->wired = TRUE;
+ if (mmnext != NULL) {
+ *gpa = mmnext->gpa;
+ if (segid)
+ *segid = mmnext->segid;
+ if (segoff)
+ *segoff = mmnext->segoff;
+ if (len)
+ *len = mmnext->len;
+ if (prot)
+ *prot = mmnext->prot;
+ if (flags)
+ *flags = mmnext->flags;
+ return (0);
+ } else {
+ return (ENOENT);
}
+}
- if (i < vm->num_mem_segs) {
- /*
- * Undo the wiring before returning an error.
- */
- vm_gpa_unwire(vm);
- return (EAGAIN);
+static void
+vm_free_memmap(struct vm *vm, int ident)
+{
+ struct mem_map *mm;
+ int error;
+
+ mm = &vm->mem_maps[ident];
+ if (mm->len) {
+ error = vm_map_remove(&vm->vmspace->vm_map, mm->gpa,
+ mm->gpa + mm->len);
+ KASSERT(error == KERN_SUCCESS, ("%s: vm_map_remove error %d",
+ __func__, error));
+ bzero(mm, sizeof(struct mem_map));
}
+}
- return (0);
+static __inline bool
+sysmem_mapping(struct vm *vm, struct mem_map *mm)
+{
+
+ if (mm->len != 0 && vm->mem_segs[mm->segid].sysmem)
+ return (true);
+ else
+ return (false);
+}
+
+static vm_paddr_t
+sysmem_maxaddr(struct vm *vm)
+{
+ struct mem_map *mm;
+ vm_paddr_t maxaddr;
+ int i;
+
+ maxaddr = 0;
+ for (i = 0; i < VM_MAX_MEMMAPS; i++) {
+ mm = &vm->mem_maps[i];
+ if (sysmem_mapping(vm, mm)) {
+ if (maxaddr < mm->gpa + mm->len)
+ maxaddr = mm->gpa + mm->len;
+ }
+ }
+ return (maxaddr);
}
static void
@@ -696,20 +806,36 @@ vm_iommu_modify(struct vm *vm, boolean_t map)
{
int i, sz;
vm_paddr_t gpa, hpa;
- struct mem_seg *seg;
+ struct mem_map *mm;
void *vp, *cookie, *host_domain;
sz = PAGE_SIZE;
host_domain = iommu_host_domain();
- for (i = 0; i < vm->num_mem_segs; i++) {
- seg = &vm->mem_segs[i];
- KASSERT(seg->wired, ("vm(%s) memory segment %#lx/%ld not wired",
- vm_name(vm), seg->gpa, seg->len));
+ for (i = 0; i < VM_MAX_MEMMAPS; i++) {
+ mm = &vm->mem_maps[i];
+ if (!sysmem_mapping(vm, mm))
+ continue;
- gpa = seg->gpa;
- while (gpa < seg->gpa + seg->len) {
- vp = vm_gpa_hold(vm, gpa, PAGE_SIZE, VM_PROT_WRITE,
+ if (map) {
+ KASSERT((mm->flags & VM_MEMMAP_F_IOMMU) == 0,
+ ("iommu map found invalid memmap %#lx/%#lx/%#x",
+ mm->gpa, mm->len, mm->flags));
+ if ((mm->flags & VM_MEMMAP_F_WIRED) == 0)
+ continue;
+ mm->flags |= VM_MEMMAP_F_IOMMU;
+ } else {
+ if ((mm->flags & VM_MEMMAP_F_IOMMU) == 0)
+ continue;
+ mm->flags &= ~VM_MEMMAP_F_IOMMU;
+ KASSERT((mm->flags & VM_MEMMAP_F_WIRED) != 0,
+ ("iommu unmap found invalid memmap %#lx/%#lx/%#x",
+ mm->gpa, mm->len, mm->flags));
+ }
+
+ gpa = mm->gpa;
+ while (gpa < mm->gpa + mm->len) {
+ vp = vm_gpa_hold(vm, -1, gpa, PAGE_SIZE, VM_PROT_WRITE,
&cookie);
KASSERT(vp != NULL, ("vm(%s) could not map gpa %#lx",
vm_name(vm), gpa));
@@ -751,10 +877,9 @@ vm_unassign_pptdev(struct vm *vm, int bus, int slot, int func)
if (error)
return (error);
- if (ppt_assigned_devices(vm) == 0) {
+ if (ppt_assigned_devices(vm) == 0)
vm_iommu_unmap(vm);
- vm_gpa_unwire(vm);
- }
+
return (0);
}
@@ -764,23 +889,12 @@ vm_assign_pptdev(struct vm *vm, int bus, int slot, int func)
int error;
vm_paddr_t maxaddr;
- /*
- * Virtual machines with pci passthru devices get special treatment:
- * - the guest physical memory is wired
- * - the iommu is programmed to do the 'gpa' to 'hpa' translation
- *
- * We need to do this before the first pci passthru device is attached.
- */
+ /* Set up the IOMMU to do the 'gpa' to 'hpa' translation */
if (ppt_assigned_devices(vm) == 0) {
KASSERT(vm->iommu == NULL,
("vm_assign_pptdev: iommu must be NULL"));
- maxaddr = vm_maxmem(vm);
+ maxaddr = sysmem_maxaddr(vm);
vm->iommu = iommu_create_domain(maxaddr);
-
- error = vm_gpa_wire(vm);
- if (error)
- return (error);
-
vm_iommu_map(vm);
}
@@ -789,18 +903,43 @@ vm_assign_pptdev(struct vm *vm, int bus, int slot, int func)
}
void *
-vm_gpa_hold(struct vm *vm, vm_paddr_t gpa, size_t len, int reqprot,
+vm_gpa_hold(struct vm *vm, int vcpuid, vm_paddr_t gpa, size_t len, int reqprot,
void **cookie)
{
- int count, pageoff;
+ int i, count, pageoff;
+ struct mem_map *mm;
vm_page_t m;
-
+#ifdef INVARIANTS
+ /*
+ * All vcpus are frozen by ioctls that modify the memory map
+ * (e.g. VM_MMAP_MEMSEG). Therefore 'vm->memmap[]' stability is
+ * guaranteed if at least one vcpu is in the VCPU_FROZEN state.
+ */
+ int state;
+ KASSERT(vcpuid >= -1 || vcpuid < VM_MAXCPU, ("%s: invalid vcpuid %d",
+ __func__, vcpuid));
+ for (i = 0; i < VM_MAXCPU; i++) {
+ if (vcpuid != -1 && vcpuid != i)
+ continue;
+ state = vcpu_get_state(vm, i, NULL);
+ KASSERT(state == VCPU_FROZEN, ("%s: invalid vcpu state %d",
+ __func__, state));
+ }
+#endif
pageoff = gpa & PAGE_MASK;
if (len > PAGE_SIZE - pageoff)
panic("vm_gpa_hold: invalid gpa/len: 0x%016lx/%lu", gpa, len);
- count = vm_fault_quick_hold_pages(&vm->vmspace->vm_map,
- trunc_page(gpa), PAGE_SIZE, reqprot, &m, 1);
+ count = 0;
+ for (i = 0; i < VM_MAX_MEMMAPS; i++) {
+ mm = &vm->mem_maps[i];
+ if (sysmem_mapping(vm, mm) && gpa >= mm->gpa &&
+ gpa < mm->gpa + mm->len) {
+ count = vm_fault_quick_hold_pages(&vm->vmspace->vm_map,
+ trunc_page(gpa), PAGE_SIZE, reqprot, &m, 1);
+ break;
+ }
+ }
if (count == 1) {
*cookie = m;
@@ -822,50 +961,6 @@ vm_gpa_release(void *cookie)
}
int
-vm_gpabase2memseg(struct vm *vm, vm_paddr_t gpabase,
- struct vm_memory_segment *seg)
-{
- int i;
-
- for (i = 0; i < vm->num_mem_segs; i++) {
- if (gpabase == vm->mem_segs[i].gpa) {
- seg->gpa = vm->mem_segs[i].gpa;
- seg->len = vm->mem_segs[i].len;
- seg->wired = vm->mem_segs[i].wired;
- return (0);
- }
- }
- return (-1);
-}
-
-int
-vm_get_memobj(struct vm *vm, vm_paddr_t gpa, size_t len,
- vm_offset_t *offset, struct vm_object **object)
-{
- int i;
- size_t seg_len;
- vm_paddr_t seg_gpa;
- vm_object_t seg_obj;
-
- for (i = 0; i < vm->num_mem_segs; i++) {
- if ((seg_obj = vm->mem_segs[i].object) == NULL)
- continue;
-
- seg_gpa = vm->mem_segs[i].gpa;
- seg_len = vm->mem_segs[i].len;
-
- if (gpa >= seg_gpa && gpa < seg_gpa + seg_len) {
- *offset = gpa - seg_gpa;
- *object = seg_obj;
- vm_object_reference(seg_obj);
- return (0);
- }
- }
-
- return (EINVAL);
-}
-
-int
vm_get_register(struct vm *vm, int vcpu, int reg, uint64_t *retval)
{
@@ -2423,8 +2518,8 @@ vm_copy_setup(struct vm *vm, int vcpuid, struct vm_guest_paging *paging,
}
for (idx = 0; idx < nused; idx++) {
- hva = vm_gpa_hold(vm, copyinfo[idx].gpa, copyinfo[idx].len,
- prot, &cookie);
+ hva = vm_gpa_hold(vm, vcpuid, copyinfo[idx].gpa,
+ copyinfo[idx].len, prot, &cookie);
if (hva == NULL)
break;
copyinfo[idx].hva = hva;
diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c
index e3e140a..4ef1482 100644
--- a/sys/amd64/vmm/vmm_dev.c
+++ b/sys/amd64/vmm/vmm_dev.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
+#include <vm/vm_object.h>
#include <machine/vmparam.h>
#include <machine/vmm.h>
@@ -60,10 +61,19 @@ __FBSDID("$FreeBSD$");
#include "io/vhpet.h"
#include "io/vrtc.h"
+struct devmem_softc {
+ int segid;
+ char *name;
+ struct cdev *cdev;
+ struct vmmdev_softc *sc;
+ SLIST_ENTRY(devmem_softc) link;
+};
+
struct vmmdev_softc {
struct vm *vm; /* vm instance cookie */
struct cdev *cdev;
SLIST_ENTRY(vmmdev_softc) link;
+ SLIST_HEAD(, devmem_softc) devmem;
int flags;
};
#define VSC_LINKED 0x01
@@ -76,6 +86,63 @@ static MALLOC_DEFINE(M_VMMDEV, "vmmdev", "vmmdev");
SYSCTL_DECL(_hw_vmm);
+static int devmem_create_cdev(const char *vmname, int id, char *devmem);
+static void devmem_destroy(void *arg);
+
+static int
+vcpu_lock_one(struct vmmdev_softc *sc, int vcpu)
+{
+ int error;
+
+ if (vcpu < 0 || vcpu >= VM_MAXCPU)
+ return (EINVAL);
+
+ error = vcpu_set_state(sc->vm, vcpu, VCPU_FROZEN, true);
+ return (error);
+}
+
+static void
+vcpu_unlock_one(struct vmmdev_softc *sc, int vcpu)
+{
+ enum vcpu_state state;
+
+ state = vcpu_get_state(sc->vm, vcpu, NULL);
+ if (state != VCPU_FROZEN) {
+ panic("vcpu %s(%d) has invalid state %d", vm_name(sc->vm),
+ vcpu, state);
+ }
+
+ vcpu_set_state(sc->vm, vcpu, VCPU_IDLE, false);
+}
+
+static int
+vcpu_lock_all(struct vmmdev_softc *sc)
+{
+ int error, vcpu;
+
+ for (vcpu = 0; vcpu < VM_MAXCPU; vcpu++) {
+ error = vcpu_lock_one(sc, vcpu);
+ if (error)
+ break;
+ }
+
+ if (error) {
+ while (--vcpu >= 0)
+ vcpu_unlock_one(sc, vcpu);
+ }
+
+ return (error);
+}
+
+static void
+vcpu_unlock_all(struct vmmdev_softc *sc)
+{
+ int vcpu;
+
+ for (vcpu = 0; vcpu < VM_MAXCPU; vcpu++)
+ vcpu_unlock_one(sc, vcpu);
+}
+
static struct vmmdev_softc *
vmmdev_lookup(const char *name)
{
@@ -108,12 +175,16 @@ vmmdev_rw(struct cdev *cdev, struct uio *uio, int flags)
void *hpa, *cookie;
struct vmmdev_softc *sc;
- static char zerobuf[PAGE_SIZE];
-
- error = 0;
sc = vmmdev_lookup2(cdev);
if (sc == NULL)
- error = ENXIO;
+ return (ENXIO);
+
+ /*
+ * Get a read lock on the guest memory map by freezing any vcpu.
+ */
+ error = vcpu_lock_one(sc, VM_MAXCPU - 1);
+ if (error)
+ return (error);
prot = (uio->uio_rw == UIO_WRITE ? VM_PROT_WRITE : VM_PROT_READ);
while (uio->uio_resid > 0 && error == 0) {
@@ -129,10 +200,11 @@ vmmdev_rw(struct cdev *cdev, struct uio *uio, int flags)
* Since this device does not support lseek(2), dd(1) will
* read(2) blocks of data to simulate the lseek(2).
*/
- hpa = vm_gpa_hold(sc->vm, gpa, c, prot, &cookie);
+ hpa = vm_gpa_hold(sc->vm, VM_MAXCPU - 1, gpa, c, prot, &cookie);
if (hpa == NULL) {
if (uio->uio_rw == UIO_READ)
- error = uiomove(zerobuf, c, uio);
+ error = uiomove(__DECONST(void *, zero_region),
+ c, uio);
else
error = EFAULT;
} else {
@@ -140,6 +212,70 @@ vmmdev_rw(struct cdev *cdev, struct uio *uio, int flags)
vm_gpa_release(cookie);
}
}
+ vcpu_unlock_one(sc, VM_MAXCPU - 1);
+ return (error);
+}
+
+CTASSERT(sizeof(((struct vm_memseg *)0)->name) >= SPECNAMELEN + 1);
+
+static int
+get_memseg(struct vmmdev_softc *sc, struct vm_memseg *mseg)
+{
+ struct devmem_softc *dsc;
+ int error;
+ bool sysmem;
+
+ error = vm_get_memseg(sc->vm, mseg->segid, &mseg->len, &sysmem, NULL);
+ if (error || mseg->len == 0)
+ return (error);
+
+ if (!sysmem) {
+ SLIST_FOREACH(dsc, &sc->devmem, link) {
+ if (dsc->segid == mseg->segid)
+ break;
+ }
+ KASSERT(dsc != NULL, ("%s: devmem segment %d not found",
+ __func__, mseg->segid));
+ error = copystr(dsc->name, mseg->name, SPECNAMELEN + 1, NULL);
+ } else {
+ bzero(mseg->name, sizeof(mseg->name));
+ }
+
+ return (error);
+}
+
+static int
+alloc_memseg(struct vmmdev_softc *sc, struct vm_memseg *mseg)
+{
+ char *name;
+ int error;
+ bool sysmem;
+
+ error = 0;
+ name = NULL;
+ sysmem = true;
+
+ if (VM_MEMSEG_NAME(mseg)) {
+ sysmem = false;
+ name = malloc(SPECNAMELEN + 1, M_VMMDEV, M_WAITOK);
+ error = copystr(VM_MEMSEG_NAME(mseg), name, SPECNAMELEN + 1, 0);
+ if (error)
+ goto done;
+ }
+
+ error = vm_alloc_memseg(sc->vm, mseg->segid, mseg->len, sysmem);
+ if (error)
+ goto done;
+
+ if (VM_MEMSEG_NAME(mseg)) {
+ error = devmem_create_cdev(vm_name(sc->vm), mseg->segid, name);
+ if (error)
+ vm_free_memseg(sc->vm, mseg->segid);
+ else
+ name = NULL; /* freed when 'cdev' is destroyed */
+ }
+done:
+ free(name, M_VMMDEV);
return (error);
}
@@ -150,7 +286,6 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
int error, vcpu, state_changed, size;
cpuset_t *cpuset;
struct vmmdev_softc *sc;
- struct vm_memory_segment *seg;
struct vm_register *vmreg;
struct vm_seg_desc *vmsegdesc;
struct vm_run *vmrun;
@@ -177,6 +312,7 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
struct vm_intinfo *vmii;
struct vm_rtc_time *rtctime;
struct vm_rtc_data *rtcdata;
+ struct vm_memmap *mm;
sc = vmmdev_lookup2(cdev);
if (sc == NULL)
@@ -211,43 +347,41 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
* Assumes that the first field of the ioctl data is the vcpu.
*/
vcpu = *(int *)data;
- if (vcpu < 0 || vcpu >= VM_MAXCPU) {
- error = EINVAL;
- goto done;
- }
-
- error = vcpu_set_state(sc->vm, vcpu, VCPU_FROZEN, true);
+ error = vcpu_lock_one(sc, vcpu);
if (error)
goto done;
-
state_changed = 1;
break;
case VM_MAP_PPTDEV_MMIO:
case VM_BIND_PPTDEV:
case VM_UNBIND_PPTDEV:
- case VM_MAP_MEMORY:
+ case VM_ALLOC_MEMSEG:
+ case VM_MMAP_MEMSEG:
case VM_REINIT:
/*
* ioctls that operate on the entire virtual machine must
* prevent all vcpus from running.
*/
- error = 0;
- for (vcpu = 0; vcpu < VM_MAXCPU; vcpu++) {
- error = vcpu_set_state(sc->vm, vcpu, VCPU_FROZEN, true);
- if (error)
- break;
- }
-
- if (error) {
- while (--vcpu >= 0)
- vcpu_set_state(sc->vm, vcpu, VCPU_IDLE, false);
+ error = vcpu_lock_all(sc);
+ if (error)
goto done;
- }
-
state_changed = 2;
break;
+ case VM_GET_MEMSEG:
+ case VM_MMAP_GETNEXT:
+ /*
+ * Lock a vcpu to make sure that the memory map cannot be
+ * modified while it is being inspected.
+ */
+ vcpu = VM_MAXCPU - 1;
+ error = vcpu_lock_one(sc, vcpu);
+ if (error)
+ goto done;
+ state_changed = 1;
+ break;
+
default:
break;
}
@@ -372,15 +506,21 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
error = vatpic_set_irq_trigger(sc->vm,
isa_irq_trigger->atpic_irq, isa_irq_trigger->trigger);
break;
- case VM_MAP_MEMORY:
- seg = (struct vm_memory_segment *)data;
- error = vm_malloc(sc->vm, seg->gpa, seg->len);
+ case VM_MMAP_GETNEXT:
+ mm = (struct vm_memmap *)data;
+ error = vm_mmap_getnext(sc->vm, &mm->gpa, &mm->segid,
+ &mm->segoff, &mm->len, &mm->prot, &mm->flags);
break;
- case VM_GET_MEMORY_SEG:
- seg = (struct vm_memory_segment *)data;
- seg->len = 0;
- (void)vm_gpabase2memseg(sc->vm, seg->gpa, seg);
- error = 0;
+ case VM_MMAP_MEMSEG:
+ mm = (struct vm_memmap *)data;
+ error = vm_mmap_memseg(sc->vm, mm->gpa, mm->segid, mm->segoff,
+ mm->len, mm->prot, mm->flags);
+ break;
+ case VM_ALLOC_MEMSEG:
+ error = alloc_memseg(sc, (struct vm_memseg *)data);
+ break;
+ case VM_GET_MEMSEG:
+ error = get_memseg(sc, (struct vm_memseg *)data);
break;
case VM_GET_REGISTER:
vmreg = (struct vm_register *)data;
@@ -505,12 +645,10 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
break;
}
- if (state_changed == 1) {
- vcpu_set_state(sc->vm, vcpu, VCPU_IDLE, false);
- } else if (state_changed == 2) {
- for (vcpu = 0; vcpu < VM_MAXCPU; vcpu++)
- vcpu_set_state(sc->vm, vcpu, VCPU_IDLE, false);
- }
+ if (state_changed == 1)
+ vcpu_unlock_one(sc, vcpu);
+ else if (state_changed == 2)
+ vcpu_unlock_all(sc);
done:
/* Make sure that no handler returns a bogus value like ERESTART */
@@ -519,26 +657,79 @@ done:
}
static int
-vmmdev_mmap_single(struct cdev *cdev, vm_ooffset_t *offset,
- vm_size_t size, struct vm_object **object, int nprot)
+vmmdev_mmap_single(struct cdev *cdev, vm_ooffset_t *offset, vm_size_t mapsize,
+ struct vm_object **objp, int nprot)
{
- int error;
struct vmmdev_softc *sc;
+ vm_paddr_t gpa;
+ size_t len;
+ vm_ooffset_t segoff, first, last;
+ int error, found, segid;
+ bool sysmem;
+
+ first = *offset;
+ last = first + mapsize;
+ if ((nprot & PROT_EXEC) || first < 0 || first >= last)
+ return (EINVAL);
sc = vmmdev_lookup2(cdev);
- if (sc != NULL && (nprot & PROT_EXEC) == 0)
- error = vm_get_memobj(sc->vm, *offset, size, offset, object);
- else
- error = EINVAL;
+ if (sc == NULL) {
+ /* virtual machine is in the process of being created */
+ return (EINVAL);
+ }
+ /*
+ * Get a read lock on the guest memory map by freezing any vcpu.
+ */
+ error = vcpu_lock_one(sc, VM_MAXCPU - 1);
+ if (error)
+ return (error);
+
+ gpa = 0;
+ found = 0;
+ while (!found) {
+ error = vm_mmap_getnext(sc->vm, &gpa, &segid, &segoff, &len,
+ NULL, NULL);
+ if (error)
+ break;
+
+ if (first >= gpa && last <= gpa + len)
+ found = 1;
+ else
+ gpa += len;
+ }
+
+ if (found) {
+ error = vm_get_memseg(sc->vm, segid, &len, &sysmem, objp);
+ KASSERT(error == 0 && *objp != NULL,
+ ("%s: invalid memory segment %d", __func__, segid));
+ if (sysmem) {
+ vm_object_reference(*objp);
+ *offset = segoff + (first - gpa);
+ } else {
+ error = EINVAL;
+ }
+ }
+ vcpu_unlock_one(sc, VM_MAXCPU - 1);
return (error);
}
static void
vmmdev_destroy(void *arg)
{
-
struct vmmdev_softc *sc = arg;
+ struct devmem_softc *dsc;
+ int error;
+
+ error = vcpu_lock_all(sc);
+ KASSERT(error == 0, ("%s: error %d freezing vcpus", __func__, error));
+
+ while ((dsc = SLIST_FIRST(&sc->devmem)) != NULL) {
+ KASSERT(dsc->cdev == NULL, ("%s: devmem not free", __func__));
+ SLIST_REMOVE_HEAD(&sc->devmem, link);
+ free(dsc->name, M_VMMDEV);
+ free(dsc, M_VMMDEV);
+ }
if (sc->cdev != NULL)
destroy_dev(sc->cdev);
@@ -560,6 +751,7 @@ sysctl_vmm_destroy(SYSCTL_HANDLER_ARGS)
{
int error;
char buf[VM_MAX_NAMELEN];
+ struct devmem_softc *dsc;
struct vmmdev_softc *sc;
struct cdev *cdev;
@@ -578,22 +770,30 @@ sysctl_vmm_destroy(SYSCTL_HANDLER_ARGS)
/*
* The 'cdev' will be destroyed asynchronously when 'si_threadcount'
* goes down to 0 so we should not do it again in the callback.
+ *
+ * Setting 'sc->cdev' to NULL is also used to indicate that the VM
+ * is scheduled for destruction.
*/
cdev = sc->cdev;
sc->cdev = NULL;
mtx_unlock(&vmmdev_mtx);
/*
- * Schedule the 'cdev' to be destroyed:
+ * Schedule all cdevs to be destroyed:
*
- * - any new operations on this 'cdev' will return an error (ENXIO).
+ * - any new operations on the 'cdev' will return an error (ENXIO).
*
* - when the 'si_threadcount' dwindles down to zero the 'cdev' will
* be destroyed and the callback will be invoked in a taskqueue
* context.
+ *
+ * - the 'devmem' cdevs are destroyed before the virtual machine 'cdev'
*/
+ SLIST_FOREACH(dsc, &sc->devmem, link) {
+ KASSERT(dsc->cdev != NULL, ("devmem cdev already destroyed"));
+ destroy_dev_sched_cb(dsc->cdev, devmem_destroy, dsc);
+ }
destroy_dev_sched_cb(cdev, vmmdev_destroy, sc);
-
return (0);
}
SYSCTL_PROC(_hw_vmm, OID_AUTO, destroy, CTLTYPE_STRING | CTLFLAG_RW,
@@ -634,6 +834,7 @@ sysctl_vmm_create(SYSCTL_HANDLER_ARGS)
sc = malloc(sizeof(struct vmmdev_softc), M_VMMDEV, M_WAITOK | M_ZERO);
sc->vm = vm;
+ SLIST_INIT(&sc->devmem);
/*
* Lookup the name again just in case somebody sneaked in when we
@@ -687,3 +888,96 @@ vmmdev_cleanup(void)
return (error);
}
+
+static int
+devmem_mmap_single(struct cdev *cdev, vm_ooffset_t *offset, vm_size_t len,
+ struct vm_object **objp, int nprot)
+{
+ struct devmem_softc *dsc;
+ vm_ooffset_t first, last;
+ size_t seglen;
+ int error;
+ bool sysmem;
+
+ dsc = cdev->si_drv1;
+ if (dsc == NULL) {
+ /* 'cdev' has been created but is not ready for use */
+ return (ENXIO);
+ }
+
+ first = *offset;
+ last = *offset + len;
+ if ((nprot & PROT_EXEC) || first < 0 || first >= last)
+ return (EINVAL);
+
+ error = vcpu_lock_one(dsc->sc, VM_MAXCPU - 1);
+ if (error)
+ return (error);
+
+ error = vm_get_memseg(dsc->sc->vm, dsc->segid, &seglen, &sysmem, objp);
+ KASSERT(error == 0 && !sysmem && *objp != NULL,
+ ("%s: invalid devmem segment %d", __func__, dsc->segid));
+
+ vcpu_unlock_one(dsc->sc, VM_MAXCPU - 1);
+
+ if (seglen >= last) {
+ vm_object_reference(*objp);
+ return (0);
+ } else {
+ return (EINVAL);
+ }
+}
+
+static struct cdevsw devmemsw = {
+ .d_name = "devmem",
+ .d_version = D_VERSION,
+ .d_mmap_single = devmem_mmap_single,
+};
+
+static int
+devmem_create_cdev(const char *vmname, int segid, char *devname)
+{
+ struct devmem_softc *dsc;
+ struct vmmdev_softc *sc;
+ struct cdev *cdev;
+ int error;
+
+ error = make_dev_p(MAKEDEV_CHECKNAME, &cdev, &devmemsw, NULL,
+ UID_ROOT, GID_WHEEL, 0600, "vmm/%s.%s", vmname, devname);
+ if (error)
+ return (error);
+
+ dsc = malloc(sizeof(struct devmem_softc), M_VMMDEV, M_WAITOK | M_ZERO);
+
+ mtx_lock(&vmmdev_mtx);
+ sc = vmmdev_lookup(vmname);
+ KASSERT(sc != NULL, ("%s: vm %s softc not found", __func__, vmname));
+ if (sc->cdev == NULL) {
+ /* virtual machine is being created or destroyed */
+ mtx_unlock(&vmmdev_mtx);
+ free(dsc, M_VMMDEV);
+ destroy_dev_sched_cb(cdev, NULL, 0);
+ return (ENODEV);
+ }
+
+ dsc->segid = segid;
+ dsc->name = devname;
+ dsc->cdev = cdev;
+ dsc->sc = sc;
+ SLIST_INSERT_HEAD(&sc->devmem, dsc, link);
+ mtx_unlock(&vmmdev_mtx);
+
+ /* The 'cdev' is ready for use after 'si_drv1' is initialized */
+ cdev->si_drv1 = dsc;
+ return (0);
+}
+
+static void
+devmem_destroy(void *arg)
+{
+ struct devmem_softc *dsc = arg;
+
+ KASSERT(dsc->cdev, ("%s: devmem cdev already destroyed", __func__));
+ dsc->cdev = NULL;
+ dsc->sc = NULL;
+}
diff --git a/sys/amd64/vmm/vmm_instruction_emul.c b/sys/amd64/vmm/vmm_instruction_emul.c
index 758b7e8..6dadcc1 100644
--- a/sys/amd64/vmm/vmm_instruction_emul.c
+++ b/sys/amd64/vmm/vmm_instruction_emul.c
@@ -1677,12 +1677,12 @@ ptp_release(void **cookie)
}
static void *
-ptp_hold(struct vm *vm, vm_paddr_t ptpphys, size_t len, void **cookie)
+ptp_hold(struct vm *vm, int vcpu, vm_paddr_t ptpphys, size_t len, void **cookie)
{
void *ptr;
ptp_release(cookie);
- ptr = vm_gpa_hold(vm, ptpphys, len, VM_PROT_RW, cookie);
+ ptr = vm_gpa_hold(vm, vcpu, ptpphys, len, VM_PROT_RW, cookie);
return (ptr);
}
@@ -1729,7 +1729,8 @@ restart:
/* Zero out the lower 12 bits. */
ptpphys &= ~0xfff;
- ptpbase32 = ptp_hold(vm, ptpphys, PAGE_SIZE, &cookie);
+ ptpbase32 = ptp_hold(vm, vcpuid, ptpphys, PAGE_SIZE,
+ &cookie);
if (ptpbase32 == NULL)
goto error;
@@ -1788,7 +1789,8 @@ restart:
/* Zero out the lower 5 bits and the upper 32 bits */
ptpphys &= 0xffffffe0UL;
- ptpbase = ptp_hold(vm, ptpphys, sizeof(*ptpbase) * 4, &cookie);
+ ptpbase = ptp_hold(vm, vcpuid, ptpphys, sizeof(*ptpbase) * 4,
+ &cookie);
if (ptpbase == NULL)
goto error;
@@ -1811,7 +1813,7 @@ restart:
/* Zero out the lower 12 bits and the upper 12 bits */
ptpphys >>= 12; ptpphys <<= 24; ptpphys >>= 12;
- ptpbase = ptp_hold(vm, ptpphys, PAGE_SIZE, &cookie);
+ ptpbase = ptp_hold(vm, vcpuid, ptpphys, PAGE_SIZE, &cookie);
if (ptpbase == NULL)
goto error;
diff --git a/sys/amd64/vmm/vmm_mem.c b/sys/amd64/vmm/vmm_mem.c
index 1019f2b..c9be6c9 100644
--- a/sys/amd64/vmm/vmm_mem.c
+++ b/sys/amd64/vmm/vmm_mem.c
@@ -114,38 +114,6 @@ vmm_mmio_free(struct vmspace *vmspace, vm_paddr_t gpa, size_t len)
vm_map_remove(&vmspace->vm_map, gpa, gpa + len);
}
-vm_object_t
-vmm_mem_alloc(struct vmspace *vmspace, vm_paddr_t gpa, size_t len)
-{
- int error;
- vm_object_t obj;
-
- if (gpa & PAGE_MASK)
- panic("vmm_mem_alloc: invalid gpa %#lx", gpa);
-
- if (len == 0 || (len & PAGE_MASK) != 0)
- panic("vmm_mem_alloc: invalid allocation size %lu", len);
-
- obj = vm_object_allocate(OBJT_DEFAULT, len >> PAGE_SHIFT);
- if (obj != NULL) {
- error = vm_map_find(&vmspace->vm_map, obj, 0, &gpa, len, 0,
- VMFS_NO_SPACE, VM_PROT_ALL, VM_PROT_ALL, 0);
- if (error != KERN_SUCCESS) {
- vm_object_deallocate(obj);
- obj = NULL;
- }
- }
-
- return (obj);
-}
-
-void
-vmm_mem_free(struct vmspace *vmspace, vm_paddr_t gpa, size_t len)
-{
-
- vm_map_remove(&vmspace->vm_map, gpa, gpa + len);
-}
-
vm_paddr_t
vmm_mem_maxaddr(void)
{
diff --git a/sys/amd64/vmm/vmm_mem.h b/sys/amd64/vmm/vmm_mem.h
index a375070..7773faa 100644
--- a/sys/amd64/vmm/vmm_mem.h
+++ b/sys/amd64/vmm/vmm_mem.h
@@ -33,10 +33,8 @@ struct vmspace;
struct vm_object;
int vmm_mem_init(void);
-struct vm_object *vmm_mem_alloc(struct vmspace *, vm_paddr_t gpa, size_t size);
struct vm_object *vmm_mmio_alloc(struct vmspace *, vm_paddr_t gpa, size_t len,
vm_paddr_t hpa);
-void vmm_mem_free(struct vmspace *, vm_paddr_t gpa, size_t size);
void vmm_mmio_free(struct vmspace *, vm_paddr_t gpa, size_t size);
vm_paddr_t vmm_mem_maxaddr(void);
diff --git a/sys/arm/arm/bcopyinout.S b/sys/arm/arm/bcopyinout.S
index 8885717..c030e24 100644
--- a/sys/arm/arm/bcopyinout.S
+++ b/sys/arm/arm/bcopyinout.S
@@ -38,6 +38,7 @@
#include "assym.s"
+#include <machine/acle-compat.h>
#include <machine/asm.h>
#include <sys/errno.h>
@@ -54,7 +55,7 @@ __FBSDID("$FreeBSD$");
.text
.align 2
-#ifdef _ARM_ARCH_6
+#if __ARM_ARCH >= 6
#define GET_PCB(tmp) \
mrc p15, 0, tmp, c13, c0, 4; \
add tmp, tmp, #(TD_PCB)
diff --git a/sys/arm/arm/bcopyinout_xscale.S b/sys/arm/arm/bcopyinout_xscale.S
index ad61200..7a5abb5 100644
--- a/sys/arm/arm/bcopyinout_xscale.S
+++ b/sys/arm/arm/bcopyinout_xscale.S
@@ -38,11 +38,13 @@
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
+#include <machine/acle-compat.h>
+
.syntax unified
.text
.align 2
-#ifdef _ARM_ARCH_6
+#if __ARM_ARCH >= 6
#define GET_PCB(tmp) \
mrc p15, 0, tmp, c13, c0, 4; \
add tmp, tmp, #(TD_PCB)
diff --git a/sys/arm/arm/copystr.S b/sys/arm/arm/copystr.S
index d41525a..48c296b 100644
--- a/sys/arm/arm/copystr.S
+++ b/sys/arm/arm/copystr.S
@@ -39,6 +39,7 @@
*/
#include "assym.s"
+#include <machine/acle-compat.h>
#include <machine/asm.h>
#include <machine/armreg.h>
__FBSDID("$FreeBSD$");
@@ -48,7 +49,7 @@ __FBSDID("$FreeBSD$");
.text
.align 2
-#ifdef _ARM_ARCH_6
+#if __ARM_ARCH >= 6
#define GET_PCB(tmp) \
mrc p15, 0, tmp, c13, c0, 4; \
add tmp, tmp, #(TD_PCB)
diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c
index 56db9ca..636ba75 100644
--- a/sys/arm/arm/generic_timer.c
+++ b/sys/arm/arm/generic_timer.c
@@ -34,6 +34,9 @@
* Cortex-A7, Cortex-A15, ARMv8 and later Generic Timer
*/
+#include "opt_acpi.h"
+#include "opt_platform.h"
+
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -51,12 +54,17 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
#include <machine/intr.h>
+#ifdef FDT
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
+#endif
-#include <machine/bus.h>
+#ifdef DEV_ACPI
+#include <contrib/dev/acpica/include/acpi.h>
+#include <dev/acpica/acpivar.h>
+#endif
#define GT_CTRL_ENABLE (1 << 0)
#define GT_CTRL_INT_MASK (1 << 1)
@@ -247,8 +255,9 @@ arm_tmr_intr(void *arg)
return (FILTER_HANDLED);
}
+#ifdef FDT
static int
-arm_tmr_probe(device_t dev)
+arm_tmr_fdt_probe(device_t dev)
{
if (!ofw_bus_status_okay(dev))
@@ -264,14 +273,62 @@ arm_tmr_probe(device_t dev)
return (ENXIO);
}
+#endif
+
+#ifdef DEV_ACPI
+static void
+arm_tmr_acpi_identify(driver_t *driver, device_t parent)
+{
+ ACPI_TABLE_GTDT *gtdt;
+ vm_paddr_t physaddr;
+ device_t dev;
+
+ physaddr = acpi_find_table(ACPI_SIG_GTDT);
+ if (physaddr == 0)
+ return;
+
+ gtdt = acpi_map_table(physaddr, ACPI_SIG_GTDT);
+ if (gtdt == NULL) {
+ device_printf(parent, "gic: Unable to map the GTDT\n");
+ return;
+ }
+
+ dev = BUS_ADD_CHILD(parent, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE,
+ "generic_timer", -1);
+ if (dev == NULL) {
+ device_printf(parent, "add gic child failed\n");
+ goto out;
+ }
+
+ BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, 0,
+ gtdt->SecureEl1Interrupt, 1);
+ BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, 1,
+ gtdt->NonSecureEl1Interrupt, 1);
+ BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, 2,
+ gtdt->VirtualTimerInterrupt, 1);
+
+out:
+ acpi_unmap_table(gtdt);
+}
+
+static int
+arm_tmr_acpi_probe(device_t dev)
+{
+
+ device_set_desc(dev, "ARM Generic Timer");
+ return (BUS_PROBE_NOWILDCARD);
+}
+#endif
static int
arm_tmr_attach(device_t dev)
{
struct arm_tmr_softc *sc;
+#ifdef FDT
phandle_t node;
pcell_t clock;
+#endif
int error;
int i;
@@ -279,12 +336,17 @@ arm_tmr_attach(device_t dev)
if (arm_tmr_sc)
return (ENXIO);
+#ifdef FDT
/* Get the base clock frequency */
node = ofw_bus_get_node(dev);
- error = OF_getprop(node, "clock-frequency", &clock, sizeof(clock));
- if (error > 0) {
- sc->clkfreq = fdt32_to_cpu(clock);
+ if (node > 0) {
+ error = OF_getprop(node, "clock-frequency", &clock,
+ sizeof(clock));
+ if (error > 0) {
+ sc->clkfreq = fdt32_to_cpu(clock);
+ }
}
+#endif
if (sc->clkfreq == 0) {
/* Try to get clock frequency from timer */
@@ -339,24 +401,46 @@ arm_tmr_attach(device_t dev)
return (0);
}
-static device_method_t arm_tmr_methods[] = {
- DEVMETHOD(device_probe, arm_tmr_probe),
+#ifdef FDT
+static device_method_t arm_tmr_fdt_methods[] = {
+ DEVMETHOD(device_probe, arm_tmr_fdt_probe),
DEVMETHOD(device_attach, arm_tmr_attach),
{ 0, 0 }
};
-static driver_t arm_tmr_driver = {
+static driver_t arm_tmr_fdt_driver = {
"generic_timer",
- arm_tmr_methods,
+ arm_tmr_fdt_methods,
sizeof(struct arm_tmr_softc),
};
-static devclass_t arm_tmr_devclass;
+static devclass_t arm_tmr_fdt_devclass;
-EARLY_DRIVER_MODULE(timer, simplebus, arm_tmr_driver, arm_tmr_devclass, 0, 0,
- BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
-EARLY_DRIVER_MODULE(timer, ofwbus, arm_tmr_driver, arm_tmr_devclass, 0, 0,
- BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
+EARLY_DRIVER_MODULE(timer, simplebus, arm_tmr_fdt_driver, arm_tmr_fdt_devclass,
+ 0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
+EARLY_DRIVER_MODULE(timer, ofwbus, arm_tmr_fdt_driver, arm_tmr_fdt_devclass,
+ 0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
+#endif
+
+#ifdef DEV_ACPI
+static device_method_t arm_tmr_acpi_methods[] = {
+ DEVMETHOD(device_identify, arm_tmr_acpi_identify),
+ DEVMETHOD(device_probe, arm_tmr_acpi_probe),
+ DEVMETHOD(device_attach, arm_tmr_attach),
+ { 0, 0 }
+};
+
+static driver_t arm_tmr_acpi_driver = {
+ "generic_timer",
+ arm_tmr_acpi_methods,
+ sizeof(struct arm_tmr_softc),
+};
+
+static devclass_t arm_tmr_acpi_devclass;
+
+EARLY_DRIVER_MODULE(timer, acpi, arm_tmr_acpi_driver, arm_tmr_acpi_devclass,
+ 0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
+#endif
void
DELAY(int usec)
diff --git a/sys/arm/arm/locore-v4.S b/sys/arm/arm/locore-v4.S
index d798e97..cc4f636 100644
--- a/sys/arm/arm/locore-v4.S
+++ b/sys/arm/arm/locore-v4.S
@@ -49,8 +49,7 @@ __FBSDID("$FreeBSD$");
*
* TODO: Fix the ARMv4/v5 case.
*/
-#if (defined(FLASHADDR) || defined(LOADERRAMADDR) || !defined(_ARM_ARCH_6)) && \
- !defined(PHYSADDR)
+#ifndef PHYSADDR
#error PHYSADDR must be defined for this configuration
#endif
diff --git a/sys/arm/arm/locore-v6.S b/sys/arm/arm/locore-v6.S
index 7d5ba97..cddcdab 100644
--- a/sys/arm/arm/locore-v6.S
+++ b/sys/arm/arm/locore-v6.S
@@ -240,7 +240,7 @@ ASENTRY_NP(init_mmu)
* - All is set to uncacheable memory
*/
ldr r0, =0xAAAAA
- mrc CP15_PRRR(r0)
+ mcr CP15_PRRR(r0)
mov r0, #0
mcr CP15_NMRR(r0)
#endif
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
index 55b4cb9..99d4572 100644
--- a/sys/arm/arm/machdep.c
+++ b/sys/arm/arm/machdep.c
@@ -911,7 +911,7 @@ fake_preload_metadata(struct arm_boot_params *abp __unused)
void
pcpu0_init(void)
{
-#if ARM_ARCH_6 || ARM_ARCH_7A || defined(CPU_MV_PJ4B)
+#if __ARM_ARCH >= 6
set_curthread(&thread0);
#endif
pcpu_init(pcpup, 0, sizeof(struct pcpu));
diff --git a/sys/arm/arm/trap-v6.c b/sys/arm/arm/trap-v6.c
index 833b42f..b15062c 100644
--- a/sys/arm/arm/trap-v6.c
+++ b/sys/arm/arm/trap-v6.c
@@ -395,8 +395,8 @@ abort_handler(struct trapframe *tf, int prefetch)
p = td->td_proc;
if (usermode) {
td->td_pticks = 0;
- if (td->td_ucred != p->p_ucred)
- cred_update_thread(td);
+ if (td->td_cowgen != p->p_cowgen)
+ thread_cow_update(td);
}
/* Invoke the appropriate handler, if necessary. */
diff --git a/sys/arm/arm/trap.c b/sys/arm/arm/trap.c
index 26e7bf6..52a5baa 100644
--- a/sys/arm/arm/trap.c
+++ b/sys/arm/arm/trap.c
@@ -78,10 +78,6 @@
* Created : 28/11/94
*/
-#ifdef KDTRACE_HOOKS
-#include <sys/dtrace_bsd.h>
-#endif
-
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -98,6 +94,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_map.h>
#include <vm/vm_extern.h>
+#include <machine/acle-compat.h>
#include <machine/cpu.h>
#include <machine/frame.h>
#include <machine/machdep.h>
@@ -108,6 +105,10 @@ __FBSDID("$FreeBSD$");
#include <sys/kdb.h>
#endif
+#ifdef KDTRACE_HOOKS
+#include <sys/dtrace_bsd.h>
+#endif
+
extern char fusubailout[];
#ifdef DEBUG
@@ -214,8 +215,8 @@ abort_handler(struct trapframe *tf, int type)
if (user) {
td->td_pticks = 0;
td->td_frame = tf;
- if (td->td_ucred != td->td_proc->p_ucred)
- cred_update_thread(td);
+ if (td->td_cowgen != td->td_proc->p_cowgen)
+ thread_cow_update(td);
}
/* Grab the current pcb */
@@ -325,7 +326,7 @@ abort_handler(struct trapframe *tf, int type)
* location, so we can deal with those quickly. Otherwise we need to
* disassemble the faulting instruction to determine if it was a write.
*/
-#if ARM_ARCH_6 || ARM_ARCH_7A
+#if __ARM_ARCH >= 6
ftype = (fsr & FAULT_WNR) ? VM_PROT_READ | VM_PROT_WRITE : VM_PROT_READ;
#else
if (IS_PERMISSION_FAULT(fsr))
@@ -644,8 +645,8 @@ prefetch_abort_handler(struct trapframe *tf)
if (TRAP_USERMODE(tf)) {
td->td_frame = tf;
- if (td->td_ucred != td->td_proc->p_ucred)
- cred_update_thread(td);
+ if (td->td_cowgen != td->td_proc->p_cowgen)
+ thread_cow_update(td);
}
fault_pc = tf->tf_pc;
if (td->td_md.md_spinlock_count == 0) {
diff --git a/sys/arm/conf/BEAGLEBONE b/sys/arm/conf/BEAGLEBONE
index 38c6b4a..8b06d20 100644
--- a/sys/arm/conf/BEAGLEBONE
+++ b/sys/arm/conf/BEAGLEBONE
@@ -138,3 +138,11 @@ device fdt_pinctrl
# Flattened Device Tree
options FDT # Configure using FDT/DTB data
+
+# Comment following lines for boot console on serial port
+device vt
+device videomode
+device hdmi
+device ums
+device ukbd
+device kbdmux
diff --git a/sys/arm/conf/NOTES b/sys/arm/conf/NOTES
index 85a4c16..885bfd1 100644
--- a/sys/arm/conf/NOTES
+++ b/sys/arm/conf/NOTES
@@ -86,3 +86,26 @@ nodevice cxgbe
nodevice pcii
nodevice snd_cmi
nodevice tnt4882
+
+#
+# Enable the kernel DTrace hooks which are required to load the DTrace
+# kernel modules.
+#
+options KDTRACE_HOOKS
+
+# DTrace core
+# NOTE: introduces CDDL-licensed components into the kernel
+#device dtrace
+
+# DTrace modules
+#device dtrace_lockstat
+#device dtrace_profile
+#device dtrace_sdt
+#device dtrace_fbt
+#device dtrace_systrace
+#device dtrace_prototype
+#device dtnfscl
+#device dtmalloc
+
+# Alternatively include all the DTrace modules
+#device dtraceall
diff --git a/sys/arm/include/pcpu.h b/sys/arm/include/pcpu.h
index 4ce8b3a..73400c5 100644
--- a/sys/arm/include/pcpu.h
+++ b/sys/arm/include/pcpu.h
@@ -32,6 +32,7 @@
#ifdef _KERNEL
+#include <machine/acle-compat.h>
#include <machine/cpuconf.h>
#define ALT_STACK_SIZE 128
@@ -40,7 +41,7 @@ struct vmspace;
#endif /* _KERNEL */
-#ifdef VFP
+#if __ARM_ARCH >= 6
#define PCPU_MD_FIELDS \
unsigned int pc_vfpsid; \
unsigned int pc_vfpmvfr0; \
@@ -58,9 +59,8 @@ struct pcb;
struct pcpu;
extern struct pcpu *pcpup;
-#if ARM_ARCH_6 || ARM_ARCH_7A
-/* or ARM_TP_ADDRESS mark REMOVE ME NOTE */
+#if __ARM_ARCH >= 6
#define CPU_MASK (0xf)
#ifndef SMP
diff --git a/sys/arm/ti/am335x/am335x_lcd.c b/sys/arm/ti/am335x/am335x_lcd.c
index 501042a..1f38664 100644
--- a/sys/arm/ti/am335x/am335x_lcd.c
+++ b/sys/arm/ti/am335x/am335x_lcd.c
@@ -52,6 +52,10 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
+#include <arm/ti/am335x/hdmi.h>
+#include <dev/videomode/videomode.h>
+#include <dev/videomode/edidvar.h>
+
#include <dev/fb/fbreg.h>
#ifdef DEV_SC
#include <dev/syscons/syscons.h>
@@ -66,6 +70,7 @@ __FBSDID("$FreeBSD$");
#include "am335x_pwm.h"
#include "fb_if.h"
+#include "hdmi_if.h"
#define LCD_PID 0x00
#define LCD_CTRL 0x04
@@ -176,11 +181,20 @@ __FBSDID("$FreeBSD$");
#define LCD_WRITE4(_sc, reg, value) \
bus_write_4((_sc)->sc_mem_res, reg, value);
-
/* Backlight is controlled by eCAS interface on PWM unit 0 */
#define PWM_UNIT 0
#define PWM_PERIOD 100
+#define MODE_HBP(mode) ((mode)->htotal - (mode)->hsync_end)
+#define MODE_HFP(mode) ((mode)->hsync_start - (mode)->hdisplay)
+#define MODE_HSW(mode) ((mode)->hsync_end - (mode)->hsync_start)
+#define MODE_VBP(mode) ((mode)->vtotal - (mode)->vsync_end)
+#define MODE_VFP(mode) ((mode)->vsync_start - (mode)->vdisplay)
+#define MODE_VSW(mode) ((mode)->vsync_end - (mode)->vsync_start)
+
+#define MAX_PIXEL_CLOCK 126000
+#define MAX_BANDWIDTH (1280*1024*60)
+
struct am335x_lcd_softc {
device_t sc_dev;
struct fb_info sc_fb_info;
@@ -191,12 +205,18 @@ struct am335x_lcd_softc {
int sc_backlight;
struct sysctl_oid *sc_oid;
+ struct panel_info sc_panel;
+
/* Framebuffer */
bus_dma_tag_t sc_dma_tag;
bus_dmamap_t sc_dma_map;
size_t sc_fb_size;
bus_addr_t sc_fb_phys;
uint8_t *sc_fb_base;
+
+ /* HDMI framer */
+ phandle_t sc_hdmi_framer;
+ eventhandler_tag sc_hdmi_evh;
};
static void
@@ -214,13 +234,22 @@ am335x_fb_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
static uint32_t
am335x_lcd_calc_divisor(uint32_t reference, uint32_t freq)
{
- uint32_t div;
+ uint32_t div, i;
+ uint32_t delta, min_delta;
+
+ min_delta = freq;
+ div = 255;
+
/* Raster mode case: divisors are in range from 2 to 255 */
- for (div = 2; div < 255; div++)
- if (reference/div <= freq)
- return (div);
+ for (i = 2; i < 255; i++) {
+ delta = abs(reference/i - freq);
+ if (delta < min_delta) {
+ div = i;
+ min_delta = delta;
+ }
+ }
- return (255);
+ return (div);
}
static int
@@ -229,7 +258,7 @@ am335x_lcd_sysctl_backlight(SYSCTL_HANDLER_ARGS)
struct am335x_lcd_softc *sc = (struct am335x_lcd_softc*)arg1;
int error;
int backlight;
-
+
backlight = sc->sc_backlight;
error = sysctl_handle_int(oidp, &backlight, 0, req);
@@ -251,6 +280,81 @@ am335x_lcd_sysctl_backlight(SYSCTL_HANDLER_ARGS)
return (error);
}
+static uint32_t
+am335x_mode_vrefresh(const struct videomode *mode)
+{
+ uint32_t refresh;
+
+ /* Calculate vertical refresh rate */
+ refresh = (mode->dot_clock * 1000 / mode->htotal);
+ refresh = (refresh + mode->vtotal / 2) / mode->vtotal;
+
+ if (mode->flags & VID_INTERLACE)
+ refresh *= 2;
+ if (mode->flags & VID_DBLSCAN)
+ refresh /= 2;
+
+ return refresh;
+}
+
+static int
+am335x_mode_is_valid(const struct videomode *mode)
+{
+ uint32_t hbp, hfp, hsw;
+ uint32_t vbp, vfp, vsw;
+
+ if (mode->dot_clock > MAX_PIXEL_CLOCK)
+ return (0);
+
+ if (mode->hdisplay & 0xf)
+ return (0);
+
+ if (mode->vdisplay > 2048)
+ return (0);
+
+ /* Check ranges for timing parameters */
+ hbp = MODE_HBP(mode) - 1;
+ hfp = MODE_HFP(mode) - 1;
+ hsw = MODE_HSW(mode) - 1;
+ vbp = MODE_VBP(mode);
+ vfp = MODE_VFP(mode);
+ vsw = MODE_VSW(mode) - 1;
+
+ if (hbp > 0x3ff)
+ return (0);
+ if (hfp > 0x3ff)
+ return (0);
+ if (hsw > 0x3ff)
+ return (0);
+
+ if (vbp > 0xff)
+ return (0);
+ if (vfp > 0xff)
+ return (0);
+ if (vsw > 0x3f)
+ return (0);
+ if (mode->vdisplay*mode->hdisplay*am335x_mode_vrefresh(mode)
+ > MAX_BANDWIDTH)
+ return (0);
+
+ return (1);
+}
+
+static void
+am335x_read_hdmi_property(device_t dev)
+{
+ phandle_t node;
+ phandle_t hdmi_xref;
+ struct am335x_lcd_softc *sc;
+
+ sc = device_get_softc(dev);
+ node = ofw_bus_get_node(dev);
+ if (OF_getencprop(node, "hdmi", &hdmi_xref, sizeof(hdmi_xref)) == -1)
+ sc->sc_hdmi_framer = 0;
+ else
+ sc->sc_hdmi_framer = hdmi_xref;
+}
+
static int
am335x_read_property(device_t dev, phandle_t node, const char *name, uint32_t *val)
{
@@ -343,44 +447,34 @@ out:
static int
am335x_read_panel_info(device_t dev, phandle_t node, struct panel_info *panel)
{
- int error;
phandle_t panel_info_node;
panel_info_node = ofw_bus_find_child(node, "panel-info");
if (panel_info_node == 0)
return (-1);
- error = 0;
-
- if ((error = am335x_read_property(dev, panel_info_node,
- "ac-bias", &panel->ac_bias)))
- goto out;
+ am335x_read_property(dev, panel_info_node,
+ "ac-bias", &panel->ac_bias);
- if ((error = am335x_read_property(dev, panel_info_node,
- "ac-bias-intrpt", &panel->ac_bias_intrpt)))
- goto out;
+ am335x_read_property(dev, panel_info_node,
+ "ac-bias-intrpt", &panel->ac_bias_intrpt);
- if ((error = am335x_read_property(dev, panel_info_node,
- "dma-burst-sz", &panel->dma_burst_sz)))
- goto out;
+ am335x_read_property(dev, panel_info_node,
+ "dma-burst-sz", &panel->dma_burst_sz);
- if ((error = am335x_read_property(dev, panel_info_node,
- "bpp", &panel->bpp)))
- goto out;
+ am335x_read_property(dev, panel_info_node,
+ "bpp", &panel->bpp);
- if ((error = am335x_read_property(dev, panel_info_node,
- "fdd", &panel->fdd)))
- goto out;
+ am335x_read_property(dev, panel_info_node,
+ "fdd", &panel->fdd);
- if ((error = am335x_read_property(dev, panel_info_node,
- "sync-edge", &panel->sync_edge)))
- goto out;
+ am335x_read_property(dev, panel_info_node,
+ "sync-edge", &panel->sync_edge);
- error = am335x_read_property(dev, panel_info_node,
+ am335x_read_property(dev, panel_info_node,
"sync-ctrl", &panel->sync_ctrl);
-out:
- return (error);
+ return (0);
}
static void
@@ -442,119 +536,75 @@ done:
reg = LCD_READ4(sc, LCD_END_OF_INT_IND);
}
-static int
-am335x_lcd_probe(device_t dev)
+static const struct videomode *
+am335x_lcd_pick_mode(struct edid_info *ei)
{
-#ifdef DEV_SC
- int err;
-#endif
-
- if (!ofw_bus_status_okay(dev))
- return (ENXIO);
+ const struct videomode *videomode;
+ const struct videomode *m;
+ int n;
- if (!ofw_bus_is_compatible(dev, "ti,am33xx-tilcdc"))
- return (ENXIO);
+ /* Get standard VGA as default */
+ videomode = NULL;
- device_set_desc(dev, "AM335x LCD controller");
+ /*
+ * Pick a mode.
+ */
+ if (ei->edid_preferred_mode != NULL) {
+ if (am335x_mode_is_valid(ei->edid_preferred_mode))
+ videomode = ei->edid_preferred_mode;
+ }
-#ifdef DEV_SC
- err = sc_probe_unit(device_get_unit(dev),
- device_get_flags(dev) | SC_AUTODETECT_KBD);
- if (err != 0)
- return (err);
-#endif
+ if (videomode == NULL) {
+ m = ei->edid_modes;
+
+ sort_modes(ei->edid_modes,
+ &ei->edid_preferred_mode,
+ ei->edid_nmodes);
+ for (n = 0; n < ei->edid_nmodes; n++)
+ if (am335x_mode_is_valid(&m[n])) {
+ videomode = &m[n];
+ break;
+ }
+ }
- return (BUS_PROBE_DEFAULT);
+ return videomode;
}
static int
-am335x_lcd_attach(device_t dev)
+am335x_lcd_configure(struct am335x_lcd_softc *sc)
{
- struct am335x_lcd_softc *sc;
- int rid;
int div;
- struct panel_info panel;
uint32_t reg, timing0, timing1, timing2;
- struct sysctl_ctx_list *ctx;
- struct sysctl_oid *tree;
uint32_t burst_log;
- int err;
size_t dma_size;
uint32_t hbp, hfp, hsw;
uint32_t vbp, vfp, vsw;
uint32_t width, height;
- phandle_t root, panel_node;
-
- sc = device_get_softc(dev);
- sc->sc_dev = dev;
-
- root = OF_finddevice("/");
- if (root == 0) {
- device_printf(dev, "failed to get FDT root node\n");
- return (ENXIO);
- }
-
- panel_node = fdt_find_compatible(root, "ti,tilcdc,panel", 1);
- if (panel_node == 0) {
- device_printf(dev, "failed to find compatible panel in FDT blob\n");
- return (ENXIO);
- }
-
- if (am335x_read_panel_info(dev, panel_node, &panel)) {
- device_printf(dev, "failed to read panel info\n");
- return (ENXIO);
- }
+ unsigned int ref_freq;
+ int err;
- if (am335x_read_timing(dev, panel_node, &panel)) {
- device_printf(dev, "failed to read timings\n");
+ /*
+ * try to adjust clock to get double of requested frequency
+ * HDMI/DVI displays are very sensitive to error in frequncy value
+ */
+ if (ti_prcm_clk_set_source_freq(LCDC_CLK, sc->sc_panel.panel_pxl_clk*2)) {
+ device_printf(sc->sc_dev, "can't set source frequency\n");
return (ENXIO);
}
- int ref_freq = 0;
- ti_prcm_clk_enable(LCDC_CLK);
if (ti_prcm_clk_get_source_freq(LCDC_CLK, &ref_freq)) {
- device_printf(dev, "Can't get reference frequency\n");
+ device_printf(sc->sc_dev, "can't get reference frequency\n");
return (ENXIO);
}
- rid = 0;
- sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
- RF_ACTIVE);
- if (!sc->sc_mem_res) {
- device_printf(dev, "cannot allocate memory window\n");
- return (ENXIO);
- }
-
- rid = 0;
- sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_ACTIVE);
- if (!sc->sc_irq_res) {
- bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
- device_printf(dev, "cannot allocate interrupt\n");
- return (ENXIO);
- }
-
- if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
- NULL, am335x_lcd_intr, sc,
- &sc->sc_intr_hl) != 0) {
- bus_release_resource(dev, SYS_RES_IRQ, rid,
- sc->sc_irq_res);
- bus_release_resource(dev, SYS_RES_MEMORY, rid,
- sc->sc_mem_res);
- device_printf(dev, "Unable to setup the irq handler.\n");
- return (ENXIO);
- }
-
- LCD_LOCK_INIT(sc);
-
/* Panle initialization */
- dma_size = round_page(panel.panel_width*panel.panel_height*panel.bpp/8);
+ dma_size = round_page(sc->sc_panel.panel_width*sc->sc_panel.panel_height*sc->sc_panel.bpp/8);
/*
* Now allocate framebuffer memory
*/
err = bus_dma_tag_create(
- bus_get_dma_tag(dev),
+ bus_get_dma_tag(sc->sc_dev),
4, 0, /* alignment, boundary */
BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
@@ -564,49 +614,49 @@ am335x_lcd_attach(device_t dev)
NULL, NULL, /* lockfunc, lockarg */
&sc->sc_dma_tag);
if (err)
- goto fail;
+ goto done;
err = bus_dmamem_alloc(sc->sc_dma_tag, (void **)&sc->sc_fb_base,
BUS_DMA_COHERENT, &sc->sc_dma_map);
if (err) {
- device_printf(dev, "cannot allocate framebuffer\n");
- goto fail;
+ device_printf(sc->sc_dev, "cannot allocate framebuffer\n");
+ goto done;
}
err = bus_dmamap_load(sc->sc_dma_tag, sc->sc_dma_map, sc->sc_fb_base,
dma_size, am335x_fb_dmamap_cb, &sc->sc_fb_phys, BUS_DMA_NOWAIT);
if (err) {
- device_printf(dev, "cannot load DMA map\n");
- goto fail;
+ device_printf(sc->sc_dev, "cannot load DMA map\n");
+ goto done;
}
/* Make sure it's blank */
- memset(sc->sc_fb_base, 0x00, dma_size);
+ memset(sc->sc_fb_base, 0x0, dma_size);
/* Calculate actual FB Size */
- sc->sc_fb_size = panel.panel_width*panel.panel_height*panel.bpp/8;
+ sc->sc_fb_size = sc->sc_panel.panel_width*sc->sc_panel.panel_height*sc->sc_panel.bpp/8;
/* Only raster mode is supported */
reg = CTRL_RASTER_MODE;
- div = am335x_lcd_calc_divisor(ref_freq, panel.panel_pxl_clk);
+ div = am335x_lcd_calc_divisor(ref_freq, sc->sc_panel.panel_pxl_clk);
reg |= (div << CTRL_DIV_SHIFT);
LCD_WRITE4(sc, LCD_CTRL, reg);
/* Set timing */
timing0 = timing1 = timing2 = 0;
- hbp = panel.panel_hbp - 1;
- hfp = panel.panel_hfp - 1;
- hsw = panel.panel_hsw - 1;
+ hbp = sc->sc_panel.panel_hbp - 1;
+ hfp = sc->sc_panel.panel_hfp - 1;
+ hsw = sc->sc_panel.panel_hsw - 1;
- vbp = panel.panel_vbp;
- vfp = panel.panel_vfp;
- vsw = panel.panel_vsw - 1;
+ vbp = sc->sc_panel.panel_vbp;
+ vfp = sc->sc_panel.panel_vfp;
+ vsw = sc->sc_panel.panel_vsw - 1;
- height = panel.panel_height - 1;
- width = panel.panel_width - 1;
+ height = sc->sc_panel.panel_height - 1;
+ width = sc->sc_panel.panel_width - 1;
/* Horizontal back porch */
timing0 |= (hbp & 0xff) << RASTER_TIMING_0_HBP_SHIFT;
@@ -636,22 +686,22 @@ am335x_lcd_attach(device_t dev)
<< RASTER_TIMING_2_LPP_B10_SHIFT;
/* clock signal settings */
- if (panel.sync_ctrl)
+ if (sc->sc_panel.sync_ctrl)
timing2 |= RASTER_TIMING_2_PHSVS;
- if (panel.sync_edge)
+ if (sc->sc_panel.sync_edge)
timing2 |= RASTER_TIMING_2_PHSVS_RISE;
else
timing2 |= RASTER_TIMING_2_PHSVS_FALL;
- if (panel.hsync_active == 0)
+ if (sc->sc_panel.hsync_active == 0)
timing2 |= RASTER_TIMING_2_IHS;
- if (panel.vsync_active == 0)
+ if (sc->sc_panel.vsync_active == 0)
timing2 |= RASTER_TIMING_2_IVS;
- if (panel.pixelclk_active == 0)
+ if (sc->sc_panel.pixelclk_active == 0)
timing2 |= RASTER_TIMING_2_IPC;
/* AC bias */
- timing2 |= (panel.ac_bias << RASTER_TIMING_2_ACB_SHIFT);
- timing2 |= (panel.ac_bias_intrpt << RASTER_TIMING_2_ACBI_SHIFT);
+ timing2 |= (sc->sc_panel.ac_bias << RASTER_TIMING_2_ACB_SHIFT);
+ timing2 |= (sc->sc_panel.ac_bias_intrpt << RASTER_TIMING_2_ACBI_SHIFT);
LCD_WRITE4(sc, LCD_RASTER_TIMING_0, timing0);
LCD_WRITE4(sc, LCD_RASTER_TIMING_1, timing1);
@@ -660,7 +710,7 @@ am335x_lcd_attach(device_t dev)
/* DMA settings */
reg = LCDDMA_CTRL_FB0_FB1;
/* Find power of 2 for current burst size */
- switch (panel.dma_burst_sz) {
+ switch (sc->sc_panel.dma_burst_sz) {
case 1:
burst_log = 0;
break;
@@ -690,11 +740,11 @@ am335x_lcd_attach(device_t dev)
/* Enable LCD */
reg = RASTER_CTRL_LCDTFT;
- reg |= (panel.fdd << RASTER_CTRL_REQDLY_SHIFT);
+ reg |= (sc->sc_panel.fdd << RASTER_CTRL_REQDLY_SHIFT);
reg |= (PALETTE_DATA_ONLY << RASTER_CTRL_PALMODE_SHIFT);
- if (panel.bpp >= 24)
+ if (sc->sc_panel.bpp >= 24)
reg |= RASTER_CTRL_TFT24;
- if (panel.bpp == 32)
+ if (sc->sc_panel.bpp == 32)
reg |= RASTER_CTRL_TFT24_UNPACKED;
LCD_WRITE4(sc, LCD_RASTER_CTRL, reg);
@@ -717,54 +767,241 @@ am335x_lcd_attach(device_t dev)
LCD_WRITE4(sc, LCD_SYSCONFIG,
SYSCONFIG_STANDBY_SMART | SYSCONFIG_IDLE_SMART);
- /* Init backlight interface */
- ctx = device_get_sysctl_ctx(sc->sc_dev);
- tree = device_get_sysctl_tree(sc->sc_dev);
- sc->sc_oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
- "backlight", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
- am335x_lcd_sysctl_backlight, "I", "LCD backlight");
- sc->sc_backlight = 0;
- /* Check if eCAS interface is available at this point */
- if (am335x_pwm_config_ecap(PWM_UNIT,
- PWM_PERIOD, PWM_PERIOD) == 0)
- sc->sc_backlight = 100;
-
sc->sc_fb_info.fb_name = device_get_nameunit(sc->sc_dev);
sc->sc_fb_info.fb_vbase = (intptr_t)sc->sc_fb_base;
sc->sc_fb_info.fb_pbase = sc->sc_fb_phys;
sc->sc_fb_info.fb_size = sc->sc_fb_size;
- sc->sc_fb_info.fb_bpp = sc->sc_fb_info.fb_depth = panel.bpp;
- sc->sc_fb_info.fb_stride = panel.panel_width*panel.bpp / 8;
- sc->sc_fb_info.fb_width = panel.panel_width;
- sc->sc_fb_info.fb_height = panel.panel_height;
+ sc->sc_fb_info.fb_bpp = sc->sc_fb_info.fb_depth = sc->sc_panel.bpp;
+ sc->sc_fb_info.fb_stride = sc->sc_panel.panel_width*sc->sc_panel.bpp / 8;
+ sc->sc_fb_info.fb_width = sc->sc_panel.panel_width;
+ sc->sc_fb_info.fb_height = sc->sc_panel.panel_height;
#ifdef DEV_SC
- err = (sc_attach_unit(device_get_unit(dev),
- device_get_flags(dev) | SC_AUTODETECT_KBD));
+ err = (sc_attach_unit(device_get_unit(sc->sc_dev),
+ device_get_flags(sc->sc_dev) | SC_AUTODETECT_KBD));
if (err) {
- device_printf(dev, "failed to attach syscons\n");
+ device_printf(sc->sc_dev, "failed to attach syscons\n");
goto fail;
}
am335x_lcd_syscons_setup((vm_offset_t)sc->sc_fb_base, sc->sc_fb_phys, &panel);
#else /* VT */
- device_t fbd = device_add_child(dev, "fbd",
- device_get_unit(dev));
- if (fbd == NULL) {
- device_printf(dev, "Failed to add fbd child\n");
- goto fail;
+ device_t fbd = device_add_child(sc->sc_dev, "fbd",
+ device_get_unit(sc->sc_dev));
+ if (fbd != NULL) {
+ if (device_probe_and_attach(fbd) != 0)
+ device_printf(sc->sc_dev, "failed to attach fbd device\n");
+ } else
+ device_printf(sc->sc_dev, "failed to add fbd child\n");
+#endif
+
+done:
+ return (err);
+}
+
+static void
+am335x_lcd_hdmi_event(void *arg)
+{
+ struct am335x_lcd_softc *sc;
+ const struct videomode *videomode;
+ struct videomode hdmi_mode;
+ device_t hdmi_dev;
+ uint8_t *edid;
+ uint32_t edid_len;
+ struct edid_info ei;
+
+ sc = arg;
+
+ /* Nothing to work with */
+ if (!sc->sc_hdmi_framer) {
+ device_printf(sc->sc_dev, "HDMI event without HDMI framer set\n");
+ return;
}
- if (device_probe_and_attach(fbd) != 0) {
- device_printf(dev, "Failed to attach fbd device\n");
- goto fail;
+
+ hdmi_dev = OF_device_from_xref(sc->sc_hdmi_framer);
+ if (!hdmi_dev) {
+ device_printf(sc->sc_dev, "no actual device for \"hdmi\" property\n");
+ return;
}
+
+ edid = NULL;
+ edid_len = 0;
+ if (HDMI_GET_EDID(hdmi_dev, &edid, &edid_len) != 0) {
+ device_printf(sc->sc_dev, "failed to get EDID info from HDMI framer\n");
+ return;
+ }
+
+ videomode = NULL;
+
+ if (edid_parse(edid, &ei) == 0) {
+ edid_print(&ei);
+ videomode = am335x_lcd_pick_mode(&ei);
+ } else
+ device_printf(sc->sc_dev, "failed to parse EDID\n");
+
+ /* Use standard VGA as fallback */
+ if (videomode == NULL)
+ videomode = pick_mode_by_ref(640, 480, 60);
+
+ if (videomode == NULL) {
+ device_printf(sc->sc_dev, "failed to find usable videomode");
+ return;
+ }
+
+ device_printf(sc->sc_dev, "detected videomode: %dx%d @ %dKHz\n", videomode->hdisplay,
+ videomode->vdisplay, am335x_mode_vrefresh(videomode));
+
+ sc->sc_panel.panel_width = videomode->hdisplay;
+ sc->sc_panel.panel_height = videomode->vdisplay;
+ sc->sc_panel.panel_hfp = videomode->hsync_start - videomode->hdisplay;
+ sc->sc_panel.panel_hbp = videomode->htotal - videomode->hsync_end;
+ sc->sc_panel.panel_hsw = videomode->hsync_end - videomode->hsync_start;
+ sc->sc_panel.panel_vfp = videomode->vsync_start - videomode->vdisplay;
+ sc->sc_panel.panel_vbp = videomode->vtotal - videomode->vsync_end;
+ sc->sc_panel.panel_vsw = videomode->vsync_end - videomode->vsync_start;
+ sc->sc_panel.pixelclk_active = 1;
+
+ /* logic for HSYNC should be reversed */
+ if (videomode->flags & VID_NHSYNC)
+ sc->sc_panel.hsync_active = 1;
+ else
+ sc->sc_panel.hsync_active = 0;
+
+ if (videomode->flags & VID_NVSYNC)
+ sc->sc_panel.vsync_active = 0;
+ else
+ sc->sc_panel.vsync_active = 1;
+
+ sc->sc_panel.panel_pxl_clk = videomode->dot_clock * 1000;
+
+ am335x_lcd_configure(sc);
+
+ memcpy(&hdmi_mode, videomode, sizeof(hdmi_mode));
+ hdmi_mode.hskew = videomode->hsync_end - videomode->hsync_start;
+ hdmi_mode.flags |= VID_HSKEW;
+
+ HDMI_SET_VIDEOMODE(hdmi_dev, &hdmi_mode);
+}
+
+static int
+am335x_lcd_probe(device_t dev)
+{
+#ifdef DEV_SC
+ int err;
#endif
- return (0);
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
-fail:
- return (err);
+ if (!ofw_bus_is_compatible(dev, "ti,am33xx-tilcdc"))
+ return (ENXIO);
+
+ device_set_desc(dev, "AM335x LCD controller");
+
+#ifdef DEV_SC
+ err = sc_probe_unit(device_get_unit(dev),
+ device_get_flags(dev) | SC_AUTODETECT_KBD);
+ if (err != 0)
+ return (err);
+#endif
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+am335x_lcd_attach(device_t dev)
+{
+ struct am335x_lcd_softc *sc;
+
+ int err;
+ int rid;
+ struct sysctl_ctx_list *ctx;
+ struct sysctl_oid *tree;
+ phandle_t root, panel_node;
+
+ err = 0;
+ sc = device_get_softc(dev);
+ sc->sc_dev = dev;
+
+ am335x_read_hdmi_property(dev);
+
+ root = OF_finddevice("/");
+ if (root == 0) {
+ device_printf(dev, "failed to get FDT root node\n");
+ return (ENXIO);
+ }
+
+ sc->sc_panel.ac_bias = 255;
+ sc->sc_panel.ac_bias_intrpt = 0;
+ sc->sc_panel.dma_burst_sz = 16;
+ sc->sc_panel.bpp = 16;
+ sc->sc_panel.fdd = 128;
+ sc->sc_panel.sync_edge = 0;
+ sc->sc_panel.sync_ctrl = 1;
+
+ panel_node = fdt_find_compatible(root, "ti,tilcdc,panel", 1);
+ if (panel_node != 0) {
+ device_printf(dev, "using static panel info\n");
+ if (am335x_read_panel_info(dev, panel_node, &sc->sc_panel)) {
+ device_printf(dev, "failed to read panel info\n");
+ return (ENXIO);
+ }
+
+ if (am335x_read_timing(dev, panel_node, &sc->sc_panel)) {
+ device_printf(dev, "failed to read timings\n");
+ return (ENXIO);
+ }
+ }
+
+ ti_prcm_clk_enable(LCDC_CLK);
+
+ rid = 0;
+ sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+ RF_ACTIVE);
+ if (!sc->sc_mem_res) {
+ device_printf(dev, "cannot allocate memory window\n");
+ return (ENXIO);
+ }
+
+ rid = 0;
+ sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+ RF_ACTIVE);
+ if (!sc->sc_irq_res) {
+ bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+ device_printf(dev, "cannot allocate interrupt\n");
+ return (ENXIO);
+ }
+
+ if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
+ NULL, am335x_lcd_intr, sc,
+ &sc->sc_intr_hl) != 0) {
+ bus_release_resource(dev, SYS_RES_IRQ, rid,
+ sc->sc_irq_res);
+ bus_release_resource(dev, SYS_RES_MEMORY, rid,
+ sc->sc_mem_res);
+ device_printf(dev, "Unable to setup the irq handler.\n");
+ return (ENXIO);
+ }
+
+ LCD_LOCK_INIT(sc);
+
+ /* Init backlight interface */
+ ctx = device_get_sysctl_ctx(sc->sc_dev);
+ tree = device_get_sysctl_tree(sc->sc_dev);
+ sc->sc_oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+ "backlight", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+ am335x_lcd_sysctl_backlight, "I", "LCD backlight");
+ sc->sc_backlight = 0;
+ /* Check if eCAS interface is available at this point */
+ if (am335x_pwm_config_ecap(PWM_UNIT,
+ PWM_PERIOD, PWM_PERIOD) == 0)
+ sc->sc_backlight = 100;
+
+ sc->sc_hdmi_evh = EVENTHANDLER_REGISTER(hdmi_event,
+ am335x_lcd_hdmi_event, sc, 0);
+
+ return (0);
}
static int
diff --git a/sys/arm/ti/am335x/am335x_lcd.h b/sys/arm/ti/am335x/am335x_lcd.h
index e3c82db..ed0779f 100644
--- a/sys/arm/ti/am335x/am335x_lcd.h
+++ b/sys/arm/ti/am335x/am335x_lcd.h
@@ -29,6 +29,7 @@
#define __AM335X_LCD_H__
struct panel_info {
+ /* Timing part */
uint32_t panel_width;
uint32_t panel_height;
uint32_t panel_hfp;
@@ -37,16 +38,17 @@ struct panel_info {
uint32_t panel_vfp;
uint32_t panel_vbp;
uint32_t panel_vsw;
+ uint32_t hsync_active;
+ uint32_t vsync_active;
+ uint32_t panel_pxl_clk;
+
uint32_t ac_bias;
uint32_t ac_bias_intrpt;
uint32_t dma_burst_sz;
uint32_t bpp;
uint32_t fdd;
- uint32_t hsync_active;
- uint32_t vsync_active;
uint32_t sync_edge;
uint32_t sync_ctrl;
- uint32_t panel_pxl_clk;
uint32_t pixelclk_active;
};
diff --git a/sys/arm/ti/am335x/am335x_pmic.c b/sys/arm/ti/am335x/am335x_pmic.c
index 06d4a1a..eefece8 100644
--- a/sys/arm/ti/am335x/am335x_pmic.c
+++ b/sys/arm/ti/am335x/am335x_pmic.c
@@ -131,7 +131,7 @@ am335x_pmic_intr(void *arg)
shutdown_nice(RB_POWEROFF);
if (int_reg.aci) {
snprintf(notify_buf, sizeof(notify_buf), "notify=0x%02x",
- status_reg.acpwr ? 1 : 0);
+ status_reg.acpwr);
devctl_notify_f("ACPI", "ACAD", "power", notify_buf, M_NOWAIT);
}
}
diff --git a/sys/arm/ti/am335x/am335x_prcm.c b/sys/arm/ti/am335x/am335x_prcm.c
index fa47f63..69fa6e2 100644
--- a/sys/arm/ti/am335x/am335x_prcm.c
+++ b/sys/arm/ti/am335x/am335x_prcm.c
@@ -151,6 +151,7 @@ static int am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev, unsign
static int am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
static int am335x_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
static int am335x_clk_get_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
+static int am335x_clk_set_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int freq);
static void am335x_prcm_reset(void);
static int am335x_clk_cpsw_activate(struct ti_clock_dev *clkdev);
static int am335x_clk_musb0_activate(struct ti_clock_dev *clkdev);
@@ -163,7 +164,8 @@ static int am335x_clk_pruss_activate(struct ti_clock_dev *clkdev);
.clk_deactivate = am335x_clk_noop_deactivate, \
.clk_set_source = am335x_clk_noop_set_source, \
.clk_accessible = NULL, \
- .clk_get_source_freq = NULL \
+ .clk_get_source_freq = NULL, \
+ .clk_set_source_freq = NULL \
}
#define AM335X_GENERIC_CLOCK_DEV(i) \
@@ -172,7 +174,8 @@ static int am335x_clk_pruss_activate(struct ti_clock_dev *clkdev);
.clk_deactivate = am335x_clk_generic_deactivate, \
.clk_set_source = am335x_clk_generic_set_source, \
.clk_accessible = NULL, \
- .clk_get_source_freq = NULL \
+ .clk_get_source_freq = NULL, \
+ .clk_set_source_freq = NULL \
}
#define AM335X_GPIO_CLOCK_DEV(i) \
@@ -181,7 +184,8 @@ static int am335x_clk_pruss_activate(struct ti_clock_dev *clkdev);
.clk_deactivate = am335x_clk_generic_deactivate, \
.clk_set_source = am335x_clk_generic_set_source, \
.clk_accessible = NULL, \
- .clk_get_source_freq = NULL \
+ .clk_get_source_freq = NULL, \
+ .clk_set_source_freq = NULL \
}
#define AM335X_MMCHS_CLOCK_DEV(i) \
@@ -190,7 +194,8 @@ static int am335x_clk_pruss_activate(struct ti_clock_dev *clkdev);
.clk_deactivate = am335x_clk_generic_deactivate, \
.clk_set_source = am335x_clk_generic_set_source, \
.clk_accessible = NULL, \
- .clk_get_source_freq = am335x_clk_hsmmc_get_source_freq \
+ .clk_get_source_freq = am335x_clk_hsmmc_get_source_freq, \
+ .clk_set_source_freq = NULL \
}
struct ti_clock_dev ti_am335x_clk_devmap[] = {
@@ -201,6 +206,7 @@ struct ti_clock_dev ti_am335x_clk_devmap[] = {
.clk_set_source = NULL,
.clk_accessible = NULL,
.clk_get_source_freq = am335x_clk_get_sysclk_freq,
+ .clk_set_source_freq = NULL,
},
/* MPU (ARM) core clocks */
{ .id = MPU_CLK,
@@ -209,6 +215,7 @@ struct ti_clock_dev ti_am335x_clk_devmap[] = {
.clk_set_source = NULL,
.clk_accessible = NULL,
.clk_get_source_freq = am335x_clk_get_arm_fclk_freq,
+ .clk_set_source_freq = NULL,
},
/* CPSW Ethernet Switch core clocks */
{ .id = CPSW_CLK,
@@ -217,6 +224,7 @@ struct ti_clock_dev ti_am335x_clk_devmap[] = {
.clk_set_source = NULL,
.clk_accessible = NULL,
.clk_get_source_freq = NULL,
+ .clk_set_source_freq = NULL,
},
/* Mentor USB HS controller core clocks */
@@ -226,6 +234,7 @@ struct ti_clock_dev ti_am335x_clk_devmap[] = {
.clk_set_source = NULL,
.clk_accessible = NULL,
.clk_get_source_freq = NULL,
+ .clk_set_source_freq = NULL,
},
/* LCD controller clocks */
@@ -235,6 +244,7 @@ struct ti_clock_dev ti_am335x_clk_devmap[] = {
.clk_set_source = NULL,
.clk_accessible = NULL,
.clk_get_source_freq = am335x_clk_get_arm_disp_freq,
+ .clk_set_source_freq = am335x_clk_set_arm_disp_freq,
},
/* UART */
@@ -296,6 +306,7 @@ struct ti_clock_dev ti_am335x_clk_devmap[] = {
.clk_set_source = NULL,
.clk_accessible = NULL,
.clk_get_source_freq = NULL,
+ .clk_set_source_freq = NULL,
},
/* RTC */
@@ -627,6 +638,8 @@ am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
#define DPLL_BYP_CLKSEL(reg) ((reg>>23) & 1)
#define DPLL_DIV(reg) ((reg & 0x7f)+1)
#define DPLL_MULT(reg) ((reg>>8) & 0x7FF)
+#define DPLL_MAX_MUL 0x800
+#define DPLL_MAX_DIV 0x80
static int
am335x_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
@@ -662,6 +675,52 @@ am335x_clk_get_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
return(0);
}
+static int
+am335x_clk_set_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int freq)
+{
+ uint32_t sysclk;
+ uint32_t mul, div;
+ uint32_t i, j;
+ unsigned int delta, min_delta;
+
+ am335x_clk_get_sysclk_freq(NULL, &sysclk);
+
+ /* Bypass mode */
+ prcm_write_4(CM_WKUP_CM_CLKMODE_DPLL_DISP, 0x4);
+
+ /* Make sure it's in bypass mode */
+ while (!(prcm_read_4(CM_WKUP_CM_IDLEST_DPLL_DISP)
+ & (1 << 8)))
+ DELAY(10);
+
+ /* Dumb and non-optimal implementation */
+ min_delta = freq;
+ for (i = 1; i < DPLL_MAX_MUL; i++) {
+ for (j = 1; j < DPLL_MAX_DIV; j++) {
+ delta = abs(freq - i*(sysclk/j));
+ if (delta < min_delta) {
+ mul = i;
+ div = j;
+ min_delta = delta;
+ }
+ if (min_delta == 0)
+ break;
+ }
+ }
+
+ prcm_write_4(CM_WKUP_CM_CLKSEL_DPLL_DISP, (mul << 8) | (div - 1));
+
+ /* Locked mode */
+ prcm_write_4(CM_WKUP_CM_CLKMODE_DPLL_DISP, 0x7);
+
+ int timeout = 10000;
+ while ((!(prcm_read_4(CM_WKUP_CM_IDLEST_DPLL_DISP)
+ & (1 << 0))) && timeout--)
+ DELAY(10);
+
+ return(0);
+}
+
static void
am335x_prcm_reset(void)
{
@@ -724,27 +783,10 @@ am335x_clk_lcdc_activate(struct ti_clock_dev *clkdev)
if (sc == NULL)
return (ENXIO);
- /* Bypass mode */
- prcm_write_4(CM_WKUP_CM_CLKMODE_DPLL_DISP, 0x4);
-
- /* Make sure it's in bypass mode */
- while (!(prcm_read_4(CM_WKUP_CM_IDLEST_DPLL_DISP)
- & (1 << 8)))
- DELAY(10);
-
/*
- * For now set frequency to 99*SYSFREQ/8 which is twice as
- * HDMI 1080p pixel clock (minimum LCDC freq divisor is 2)
+ * For now set frequency to 2*VGA_PIXEL_CLOCK
*/
- prcm_write_4(CM_WKUP_CM_CLKSEL_DPLL_DISP, (99 << 8) | 8);
-
- /* Locked mode */
- prcm_write_4(CM_WKUP_CM_CLKMODE_DPLL_DISP, 0x7);
-
- int timeout = 10000;
- while ((!(prcm_read_4(CM_WKUP_CM_IDLEST_DPLL_DISP)
- & (1 << 0))) && timeout--)
- DELAY(10);
+ am335x_clk_set_arm_disp_freq(clkdev, 25175000*2);
/*set MODULEMODE to ENABLE(2) */
prcm_write_4(CM_PER_LCDC_CLKCTRL, 2);
diff --git a/sys/arm/ti/am335x/files.am335x b/sys/arm/ti/am335x/files.am335x
index 277ee52..7293fd0 100644
--- a/sys/arm/ti/am335x/files.am335x
+++ b/sys/arm/ti/am335x/files.am335x
@@ -16,5 +16,8 @@ arm/ti/am335x/am335x_scm_padconf.c standard
arm/ti/am335x/am335x_usbss.c optional musb fdt
arm/ti/am335x/am335x_musb.c optional musb fdt
+arm/ti/am335x/hdmi_if.m optional hdmi
+arm/ti/am335x/tda19988.c optional hdmi
+
arm/ti/ti_edma3.c standard
arm/ti/cpsw/if_cpsw.c optional cpsw
diff --git a/sys/arm/ti/am335x/hdmi.h b/sys/arm/ti/am335x/hdmi.h
new file mode 100644
index 0000000..989d132
--- /dev/null
+++ b/sys/arm/ti/am335x/hdmi.h
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2015 Oleksandr Tymoshenko
+ * 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 _HDMI_H_
+#define _HDMI_H_
+
+#include <sys/eventhandler.h>
+
+typedef void (*hdmi_event_hook)(void *, int);
+EVENTHANDLER_DECLARE(hdmi_event, hdmi_event_hook);
+
+#endif /* !_HDMI_H_ */
+
diff --git a/sys/arm/ti/am335x/hdmi_if.m b/sys/arm/ti/am335x/hdmi_if.m
new file mode 100644
index 0000000..e5c6080
--- /dev/null
+++ b/sys/arm/ti/am335x/hdmi_if.m
@@ -0,0 +1,50 @@
+#-
+# Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@freebsd.org>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+
+#include <sys/bus.h>
+#include <dev/videomode/videomode.h>
+#include <dev/videomode/edidvar.h>
+
+INTERFACE hdmi;
+
+#
+# Get EDID info
+#
+METHOD int get_edid {
+ device_t dev;
+ uint8_t **edid;
+ uint32_t *edid_length;
+};
+
+#
+# Set videomode
+#
+METHOD int set_videomode {
+ device_t dev;
+ const struct videomode *videomode;
+};
diff --git a/sys/arm/ti/am335x/tda19988.c b/sys/arm/ti/am335x/tda19988.c
new file mode 100644
index 0000000..83dcf43
--- /dev/null
+++ b/sys/arm/ti/am335x/tda19988.c
@@ -0,0 +1,810 @@
+/*-
+ * Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+/*
+* NXP TDA19988 HDMI encoder
+*/
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/clock.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+
+#include <dev/iicbus/iicbus.h>
+#include <dev/iicbus/iiconf.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/videomode/videomode.h>
+#include <dev/videomode/edidvar.h>
+#include <arm/ti/am335x/hdmi.h>
+
+#include "iicbus_if.h"
+#include "hdmi_if.h"
+
+#define MKREG(page, addr) (((page) << 8) | (addr))
+
+#define REGPAGE(reg) (((reg) >> 8) & 0xff)
+#define REGADDR(reg) ((reg) & 0xff)
+
+#define TDA_VERSION MKREG(0x00, 0x00)
+#define TDA_MAIN_CNTRL0 MKREG(0x00, 0x01)
+#define MAIN_CNTRL0_SR (1 << 0)
+#define TDA_VERSION_MSB MKREG(0x00, 0x02)
+#define TDA_SOFTRESET MKREG(0x00, 0x0a)
+#define SOFTRESET_I2C (1 << 1)
+#define SOFTRESET_AUDIO (1 << 0)
+#define TDA_DDC_CTRL MKREG(0x00, 0x0b)
+#define DDC_ENABLE 0
+#define TDA_CCLK MKREG(0x00, 0x0c)
+#define CCLK_ENABLE 1
+#define TDA_INT_FLAGS_2 MKREG(0x00, 0x11)
+#define INT_FLAGS_2_EDID_BLK_RD (1 << 1)
+
+#define TDA_VIP_CNTRL_0 MKREG(0x00, 0x20)
+#define TDA_VIP_CNTRL_1 MKREG(0x00, 0x21)
+#define TDA_VIP_CNTRL_2 MKREG(0x00, 0x22)
+#define TDA_VIP_CNTRL_3 MKREG(0x00, 0x23)
+#define VIP_CNTRL_3_SYNC_HS (2 << 4)
+#define VIP_CNTRL_3_V_TGL (1 << 2)
+#define VIP_CNTRL_3_H_TGL (1 << 1)
+
+#define TDA_VIP_CNTRL_4 MKREG(0x00, 0x24)
+#define VIP_CNTRL_4_BLANKIT_NDE (0 << 2)
+#define VIP_CNTRL_4_BLANKIT_HS_VS (1 << 2)
+#define VIP_CNTRL_4_BLANKIT_NHS_VS (2 << 2)
+#define VIP_CNTRL_4_BLANKIT_HE_VE (3 << 2)
+#define VIP_CNTRL_4_BLC_NONE (0 << 0)
+#define VIP_CNTRL_4_BLC_RGB444 (1 << 0)
+#define VIP_CNTRL_4_BLC_YUV444 (2 << 0)
+#define VIP_CNTRL_4_BLC_YUV422 (3 << 0)
+#define TDA_VIP_CNTRL_5 MKREG(0x00, 0x25)
+#define VIP_CNTRL_5_SP_CNT(n) (((n) & 3) << 1)
+#define TDA_MUX_VP_VIP_OUT MKREG(0x00, 0x27)
+#define TDA_MAT_CONTRL MKREG(0x00, 0x80)
+#define MAT_CONTRL_MAT_BP (1 << 2)
+#define TDA_VIDFORMAT MKREG(0x00, 0xa0)
+#define TDA_REFPIX_MSB MKREG(0x00, 0xa1)
+#define TDA_REFPIX_LSB MKREG(0x00, 0xa2)
+#define TDA_REFLINE_MSB MKREG(0x00, 0xa3)
+#define TDA_REFLINE_LSB MKREG(0x00, 0xa4)
+#define TDA_NPIX_MSB MKREG(0x00, 0xa5)
+#define TDA_NPIX_LSB MKREG(0x00, 0xa6)
+#define TDA_NLINE_MSB MKREG(0x00, 0xa7)
+#define TDA_NLINE_LSB MKREG(0x00, 0xa8)
+#define TDA_VS_LINE_STRT_1_MSB MKREG(0x00, 0xa9)
+#define TDA_VS_LINE_STRT_1_LSB MKREG(0x00, 0xaa)
+#define TDA_VS_PIX_STRT_1_MSB MKREG(0x00, 0xab)
+#define TDA_VS_PIX_STRT_1_LSB MKREG(0x00, 0xac)
+#define TDA_VS_LINE_END_1_MSB MKREG(0x00, 0xad)
+#define TDA_VS_LINE_END_1_LSB MKREG(0x00, 0xae)
+#define TDA_VS_PIX_END_1_MSB MKREG(0x00, 0xaf)
+#define TDA_VS_PIX_END_1_LSB MKREG(0x00, 0xb0)
+#define TDA_VS_LINE_STRT_2_MSB MKREG(0x00, 0xb1)
+#define TDA_VS_LINE_STRT_2_LSB MKREG(0x00, 0xb2)
+#define TDA_VS_PIX_STRT_2_MSB MKREG(0x00, 0xb3)
+#define TDA_VS_PIX_STRT_2_LSB MKREG(0x00, 0xb4)
+#define TDA_VS_LINE_END_2_MSB MKREG(0x00, 0xb5)
+#define TDA_VS_LINE_END_2_LSB MKREG(0x00, 0xb6)
+#define TDA_VS_PIX_END_2_MSB MKREG(0x00, 0xb7)
+#define TDA_VS_PIX_END_2_LSB MKREG(0x00, 0xb8)
+#define TDA_HS_PIX_START_MSB MKREG(0x00, 0xb9)
+#define TDA_HS_PIX_START_LSB MKREG(0x00, 0xba)
+#define TDA_HS_PIX_STOP_MSB MKREG(0x00, 0xbb)
+#define TDA_HS_PIX_STOP_LSB MKREG(0x00, 0xbc)
+#define TDA_VWIN_START_1_MSB MKREG(0x00, 0xbd)
+#define TDA_VWIN_START_1_LSB MKREG(0x00, 0xbe)
+#define TDA_VWIN_END_1_MSB MKREG(0x00, 0xbf)
+#define TDA_VWIN_END_1_LSB MKREG(0x00, 0xc0)
+#define TDA_VWIN_START_2_MSB MKREG(0x00, 0xc1)
+#define TDA_VWIN_START_2_LSB MKREG(0x00, 0xc2)
+#define TDA_VWIN_END_2_MSB MKREG(0x00, 0xc3)
+#define TDA_VWIN_END_2_LSB MKREG(0x00, 0xc4)
+#define TDA_DE_START_MSB MKREG(0x00, 0xc5)
+#define TDA_DE_START_LSB MKREG(0x00, 0xc6)
+#define TDA_DE_STOP_MSB MKREG(0x00, 0xc7)
+#define TDA_DE_STOP_LSB MKREG(0x00, 0xc8)
+
+#define TDA_TBG_CNTRL_0 MKREG(0x00, 0xca)
+#define TBG_CNTRL_0_SYNC_ONCE (1 << 7)
+#define TBG_CNTRL_0_SYNC_MTHD (1 << 6)
+
+#define TDA_TBG_CNTRL_1 MKREG(0x00, 0xcb)
+#define TBG_CNTRL_1_DWIN_DIS (1 << 6)
+#define TBG_CNTRL_1_TGL_EN (1 << 2)
+#define TBG_CNTRL_1_V_TGL (1 << 1)
+#define TBG_CNTRL_1_H_TGL (1 << 0)
+
+#define TDA_HVF_CNTRL_0 MKREG(0x00, 0xe4)
+#define HVF_CNTRL_0_PREFIL_NONE (0 << 2)
+#define HVF_CNTRL_0_INTPOL_BYPASS (0 << 0)
+#define TDA_HVF_CNTRL_1 MKREG(0x00, 0xe5)
+#define HVF_CNTRL_1_VQR(x) (((x) & 3) << 2)
+#define HVF_CNTRL_1_VQR_FULL HVF_CNTRL_1_VQR(0)
+#define TDA_ENABLE_SPACE MKREG(0x00, 0xd6)
+#define TDA_RPT_CNTRL MKREG(0x00, 0xf0)
+
+#define TDA_PLL_SERIAL_1 MKREG(0x02, 0x00)
+#define PLL_SERIAL_1_SRL_MAN_IP (1 << 6)
+#define TDA_PLL_SERIAL_2 MKREG(0x02, 0x01)
+#define PLL_SERIAL_2_SRL_PR(x) (((x) & 0xf) << 4)
+#define PLL_SERIAL_2_SRL_NOSC(x) (((x) & 0x3) << 0)
+#define TDA_PLL_SERIAL_3 MKREG(0x02, 0x02)
+#define PLL_SERIAL_3_SRL_PXIN_SEL (1 << 4)
+#define PLL_SERIAL_3_SRL_DE (1 << 2)
+#define PLL_SERIAL_3_SRL_CCIR (1 << 0)
+#define TDA_SERIALIZER MKREG(0x02, 0x03)
+#define TDA_BUFFER_OUT MKREG(0x02, 0x04)
+#define TDA_PLL_SCG1 MKREG(0x02, 0x05)
+#define TDA_PLL_SCG2 MKREG(0x02, 0x06)
+#define TDA_PLL_SCGN1 MKREG(0x02, 0x07)
+#define TDA_PLL_SCGN2 MKREG(0x02, 0x08)
+#define TDA_PLL_SCGR1 MKREG(0x02, 0x09)
+#define TDA_PLL_SCGR2 MKREG(0x02, 0x0a)
+
+#define TDA_SEL_CLK MKREG(0x02, 0x11)
+#define SEL_CLK_ENA_SC_CLK (1 << 3)
+#define SEL_CLK_SEL_VRF_CLK(x) (((x) & 3) << 1)
+#define SEL_CLK_SEL_CLK1 (1 << 0)
+#define TDA_ANA_GENERAL MKREG(0x02, 0x12)
+
+#define TDA_EDID_DATA0 MKREG(0x09, 0x00)
+#define TDA_EDID_CTRL MKREG(0x09, 0xfa)
+#define TDA_DDC_ADDR MKREG(0x09, 0xfb)
+#define TDA_DDC_OFFS MKREG(0x09, 0xfc)
+#define TDA_DDC_SEGM_ADDR MKREG(0x09, 0xfd)
+#define TDA_DDC_SEGM MKREG(0x09, 0xfe)
+
+#define TDA_IF_VSP MKREG(0x10, 0x20)
+#define TDA_IF_AVI MKREG(0x10, 0x40)
+#define TDA_IF_SPD MKREG(0x10, 0x60)
+#define TDA_IF_AUD MKREG(0x10, 0x80)
+#define TDA_IF_MPS MKREG(0x10, 0xa0)
+
+#define TDA_ENC_CNTRL MKREG(0x11, 0x0d)
+#define ENC_CNTRL_DVI_MODE (0 << 2)
+#define ENC_CNTRL_HDMI_MODE (1 << 2)
+#define TDA_DIP_IF_FLAGS MKREG(0x11, 0x0f)
+#define DIP_IF_FLAGS_IF5 (1 << 5)
+#define DIP_IF_FLAGS_IF4 (1 << 4)
+#define DIP_IF_FLAGS_IF3 (1 << 3)
+#define DIP_IF_FLAGS_IF2 (1 << 2) /* AVI IF on page 10h */
+#define DIP_IF_FLAGS_IF1 (1 << 1)
+
+#define TDA_TX3 MKREG(0x12, 0x9a)
+#define TDA_TX4 MKREG(0x12, 0x9b)
+#define TX4_PD_RAM (1 << 1)
+#define TDA_HDCP_TX33 MKREG(0x12, 0xb8)
+#define HDCP_TX33_HDMI (1 << 1)
+
+#define TDA_CURPAGE_ADDR 0xff
+
+#define TDA_CEC_ENAMODS 0xff
+#define ENAMODS_RXSENS (1 << 2)
+#define ENAMODS_HDMI (1 << 1)
+#define TDA_CEC_FRO_IM_CLK_CTRL 0xfb
+#define CEC_FRO_IM_CLK_CTRL_GHOST_DIS (1 << 7)
+#define CEC_FRO_IM_CLK_CTRL_IMCLK_SEL (1 << 1)
+
+/* EDID reading */
+#define EDID_LENGTH 0x80
+#define MAX_READ_ATTEMPTS 100
+
+/* EDID fields */
+#define EDID_MODES0 35
+#define EDID_MODES1 36
+#define EDID_TIMING_START 38
+#define EDID_TIMING_END 54
+#define EDID_TIMING_X(v) (((v) + 31) * 8)
+#define EDID_FREQ(v) (((v) & 0x3f) + 60)
+#define EDID_RATIO(v) (((v) >> 6) & 0x3)
+#define EDID_RATIO_10x16 0
+#define EDID_RATIO_3x4 1
+#define EDID_RATIO_4x5 2
+#define EDID_RATIO_9x16 3
+
+#define TDA19988 0x0301
+
+struct tda19988_softc {
+ device_t sc_dev;
+ uint32_t sc_addr;
+ uint32_t sc_cec_addr;
+ uint16_t sc_version;
+ struct intr_config_hook enum_hook;
+ int sc_current_page;
+ uint8_t *sc_edid;
+ uint32_t sc_edid_len;
+};
+
+static int
+tda19988_set_page(struct tda19988_softc *sc, uint8_t page)
+{
+ uint8_t addr = TDA_CURPAGE_ADDR;
+ uint8_t cmd[2];
+ int result;
+ struct iic_msg msg[] = {
+ { sc->sc_addr, IIC_M_WR, 2, cmd },
+ };
+
+ cmd[0] = addr;
+ cmd[1] = page;
+
+ result = (iicbus_transfer(sc->sc_dev, msg, 1));
+ if (result)
+ printf("tda19988_set_page failed: %d\n", result);
+ else
+ sc->sc_current_page = page;
+
+ return (result);
+}
+
+static int
+tda19988_cec_read(struct tda19988_softc *sc, uint8_t addr, uint8_t *data)
+{
+ int result;
+ struct iic_msg msg[] = {
+ { sc->sc_cec_addr, IIC_M_WR, 1, &addr },
+ { sc->sc_cec_addr, IIC_M_RD, 1, data },
+ };
+
+ result = iicbus_transfer(sc->sc_dev, msg, 2);
+ if (result)
+ printf("tda19988_cec_read failed: %d\n", result);
+ return (result);
+}
+
+static int
+tda19988_cec_write(struct tda19988_softc *sc, uint8_t address, uint8_t data)
+{
+ uint8_t cmd[2];
+ int result;
+ struct iic_msg msg[] = {
+ { sc->sc_cec_addr, IIC_M_WR, 2, cmd },
+ };
+
+ cmd[0] = address;
+ cmd[1] = data;
+
+ result = iicbus_transfer(sc->sc_dev, msg, 1);
+ if (result)
+ printf("tda19988_cec_write failed: %d\n", result);
+ return (result);
+}
+
+static int
+tda19988_block_read(struct tda19988_softc *sc, uint16_t addr, uint8_t *data, int len)
+{
+ uint8_t reg;
+ int result;
+ struct iic_msg msg[] = {
+ { sc->sc_addr, IIC_M_WR, 1, &reg },
+ { sc->sc_addr, IIC_M_RD, len, data },
+ };
+
+ reg = REGADDR(addr);
+
+ if (sc->sc_current_page != REGPAGE(addr))
+ tda19988_set_page(sc, REGPAGE(addr));
+
+ result = (iicbus_transfer(sc->sc_dev, msg, 2));
+ if (result)
+ device_printf(sc->sc_dev, "tda19988_block_read failed: %d\n", result);
+ return (result);
+}
+
+static int
+tda19988_reg_read(struct tda19988_softc *sc, uint16_t addr, uint8_t *data)
+{
+ uint8_t reg;
+ int result;
+ struct iic_msg msg[] = {
+ { sc->sc_addr, IIC_M_WR, 1, &reg },
+ { sc->sc_addr, IIC_M_RD, 1, data },
+ };
+
+ reg = REGADDR(addr);
+
+ if (sc->sc_current_page != REGPAGE(addr))
+ tda19988_set_page(sc, REGPAGE(addr));
+
+ result = (iicbus_transfer(sc->sc_dev, msg, 2));
+ if (result)
+ device_printf(sc->sc_dev, "tda19988_reg_read failed: %d\n", result);
+ return (result);
+}
+
+static int
+tda19988_reg_write(struct tda19988_softc *sc, uint16_t address, uint8_t data)
+{
+ uint8_t cmd[2];
+ int result;
+ struct iic_msg msg[] = {
+ { sc->sc_addr, IIC_M_WR, 2, cmd },
+ };
+
+ cmd[0] = REGADDR(address);
+ cmd[1] = data;
+
+ if (sc->sc_current_page != REGPAGE(address))
+ tda19988_set_page(sc, REGPAGE(address));
+
+ result = iicbus_transfer(sc->sc_dev, msg, 1);
+ if (result)
+ device_printf(sc->sc_dev, "tda19988_reg_write failed: %d\n", result);
+
+ return (result);
+}
+
+static int
+tda19988_reg_write2(struct tda19988_softc *sc, uint16_t address, uint16_t data)
+{
+ uint8_t cmd[3];
+ int result;
+ struct iic_msg msg[] = {
+ { sc->sc_addr, IIC_M_WR, 3, cmd },
+ };
+
+ cmd[0] = REGADDR(address);
+ cmd[1] = (data >> 8);
+ cmd[2] = (data & 0xff);
+
+ if (sc->sc_current_page != REGPAGE(address))
+ tda19988_set_page(sc, REGPAGE(address));
+
+ result = iicbus_transfer(sc->sc_dev, msg, 1);
+ if (result)
+ device_printf(sc->sc_dev, "tda19988_reg_write2 failed: %d\n", result);
+
+ return (result);
+}
+
+static void
+tda19988_reg_set(struct tda19988_softc *sc, uint16_t addr, uint8_t flags)
+{
+ uint8_t data;
+
+ tda19988_reg_read(sc, addr, &data);
+ data |= flags;
+ tda19988_reg_write(sc, addr, data);
+}
+
+static void
+tda19988_reg_clear(struct tda19988_softc *sc, uint16_t addr, uint8_t flags)
+{
+ uint8_t data;
+
+ tda19988_reg_read(sc, addr, &data);
+ data &= ~flags;
+ tda19988_reg_write(sc, addr, data);
+}
+
+static int
+tda19988_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "nxp,tda998x"))
+ return (ENXIO);
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static void
+tda19988_init_encoder(struct tda19988_softc *sc, const struct videomode *mode)
+{
+ uint16_t ref_pix, ref_line, n_pix, n_line;
+ uint16_t hs_pix_start, hs_pix_stop;
+ uint16_t vs1_pix_start, vs1_pix_stop;
+ uint16_t vs1_line_start, vs1_line_end;
+ uint16_t vs2_pix_start, vs2_pix_stop;
+ uint16_t vs2_line_start, vs2_line_end;
+ uint16_t vwin1_line_start, vwin1_line_end;
+ uint16_t vwin2_line_start, vwin2_line_end;
+ uint16_t de_start, de_stop;
+ uint8_t reg, div;
+
+ n_pix = mode->htotal;
+ n_line = mode->vtotal;
+
+ hs_pix_stop = mode->hsync_end - mode->hdisplay;
+ hs_pix_start = mode->hsync_start - mode->hdisplay;
+
+ de_stop = mode->htotal;
+ de_start = mode->htotal - mode->hdisplay;
+ ref_pix = hs_pix_start + 3;
+
+ if (mode->flags & VID_HSKEW)
+ ref_pix += mode->hskew;
+
+ if ((mode->flags & VID_INTERLACE) == 0) {
+ ref_line = 1 + mode->vsync_start - mode->vdisplay;
+ vwin1_line_start = mode->vtotal - mode->vdisplay - 1;
+ vwin1_line_end = vwin1_line_start + mode->vdisplay;
+
+ vs1_pix_start = vs1_pix_stop = hs_pix_start;
+ vs1_line_start = mode->vsync_start - mode->vdisplay;
+ vs1_line_end = vs1_line_start + mode->vsync_end - mode->vsync_start;
+
+ vwin2_line_start = vwin2_line_end = 0;
+ vs2_pix_start = vs2_pix_stop = 0;
+ vs2_line_start = vs2_line_end = 0;
+ } else {
+ ref_line = 1 + (mode->vsync_start - mode->vdisplay)/2;
+ vwin1_line_start = (mode->vtotal - mode->vdisplay)/2;
+ vwin1_line_end = vwin1_line_start + mode->vdisplay/2;
+
+ vs1_pix_start = vs1_pix_stop = hs_pix_start;
+ vs1_line_start = (mode->vsync_start - mode->vdisplay)/2;
+ vs1_line_end = vs1_line_start + (mode->vsync_end - mode->vsync_start)/2;
+
+ vwin2_line_start = vwin1_line_start + mode->vtotal/2;
+ vwin2_line_end = vwin2_line_start + mode->vdisplay/2;
+
+ vs2_pix_start = vs2_pix_stop = hs_pix_start + mode->htotal/2;
+ vs2_line_start = vs1_line_start + mode->vtotal/2 ;
+ vs2_line_end = vs2_line_start + (mode->vsync_end - mode->vsync_start)/2;
+ }
+
+ div = 148500 / mode->dot_clock;
+ if (div != 0) {
+ div--;
+ if (div > 3)
+ div = 3;
+ }
+
+ /* set HDMI HDCP mode off */
+ tda19988_reg_set(sc, TDA_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS);
+ tda19988_reg_clear(sc, TDA_HDCP_TX33, HDCP_TX33_HDMI);
+ tda19988_reg_write(sc, TDA_ENC_CNTRL, ENC_CNTRL_DVI_MODE);
+
+ /* no pre-filter or interpolator */
+ tda19988_reg_write(sc, TDA_HVF_CNTRL_0,
+ HVF_CNTRL_0_INTPOL_BYPASS | HVF_CNTRL_0_PREFIL_NONE);
+ tda19988_reg_write(sc, TDA_VIP_CNTRL_5, VIP_CNTRL_5_SP_CNT(0));
+ tda19988_reg_write(sc, TDA_VIP_CNTRL_4,
+ VIP_CNTRL_4_BLANKIT_NDE | VIP_CNTRL_4_BLC_NONE);
+
+ tda19988_reg_clear(sc, TDA_PLL_SERIAL_3, PLL_SERIAL_3_SRL_CCIR);
+ tda19988_reg_clear(sc, TDA_PLL_SERIAL_1, PLL_SERIAL_1_SRL_MAN_IP);
+ tda19988_reg_clear(sc, TDA_PLL_SERIAL_3, PLL_SERIAL_3_SRL_DE);
+ tda19988_reg_write(sc, TDA_SERIALIZER, 0);
+ tda19988_reg_write(sc, TDA_HVF_CNTRL_1, HVF_CNTRL_1_VQR_FULL);
+
+ tda19988_reg_write(sc, TDA_RPT_CNTRL, 0);
+ tda19988_reg_write(sc, TDA_SEL_CLK, SEL_CLK_SEL_VRF_CLK(0) |
+ SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK);
+
+ tda19988_reg_write(sc, TDA_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) |
+ PLL_SERIAL_2_SRL_PR(0));
+
+ tda19988_reg_set(sc, TDA_MAT_CONTRL, MAT_CONTRL_MAT_BP);
+
+ tda19988_reg_write(sc, TDA_ANA_GENERAL, 0x09);
+
+ tda19988_reg_clear(sc, TDA_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_MTHD);
+
+ /*
+ * Sync on rising HSYNC/VSYNC
+ */
+ reg = VIP_CNTRL_3_SYNC_HS;
+ if (mode->flags & VID_NHSYNC)
+ reg |= VIP_CNTRL_3_H_TGL;
+ if (mode->flags & VID_NVSYNC)
+ reg |= VIP_CNTRL_3_V_TGL;
+ tda19988_reg_write(sc, TDA_VIP_CNTRL_3, reg);
+
+ reg = TBG_CNTRL_1_TGL_EN;
+ if (mode->flags & VID_NHSYNC)
+ reg |= TBG_CNTRL_1_H_TGL;
+ if (mode->flags & VID_NVSYNC)
+ reg |= TBG_CNTRL_1_V_TGL;
+ tda19988_reg_write(sc, TDA_TBG_CNTRL_1, reg);
+
+ /* Program timing */
+ tda19988_reg_write(sc, TDA_VIDFORMAT, 0x00);
+
+ tda19988_reg_write2(sc, TDA_REFPIX_MSB, ref_pix);
+ tda19988_reg_write2(sc, TDA_REFLINE_MSB, ref_line);
+ tda19988_reg_write2(sc, TDA_NPIX_MSB, n_pix);
+ tda19988_reg_write2(sc, TDA_NLINE_MSB, n_line);
+
+ tda19988_reg_write2(sc, TDA_VS_LINE_STRT_1_MSB, vs1_line_start);
+ tda19988_reg_write2(sc, TDA_VS_PIX_STRT_1_MSB, vs1_pix_start);
+ tda19988_reg_write2(sc, TDA_VS_LINE_END_1_MSB, vs1_line_end);
+ tda19988_reg_write2(sc, TDA_VS_PIX_END_1_MSB, vs1_pix_stop);
+ tda19988_reg_write2(sc, TDA_VS_LINE_STRT_2_MSB, vs2_line_start);
+ tda19988_reg_write2(sc, TDA_VS_PIX_STRT_2_MSB, vs2_pix_start);
+ tda19988_reg_write2(sc, TDA_VS_LINE_END_2_MSB, vs2_line_end);
+ tda19988_reg_write2(sc, TDA_VS_PIX_END_2_MSB, vs2_pix_stop);
+ tda19988_reg_write2(sc, TDA_HS_PIX_START_MSB, hs_pix_start);
+ tda19988_reg_write2(sc, TDA_HS_PIX_STOP_MSB, hs_pix_stop);
+ tda19988_reg_write2(sc, TDA_VWIN_START_1_MSB, vwin1_line_start);
+ tda19988_reg_write2(sc, TDA_VWIN_END_1_MSB, vwin1_line_end);
+ tda19988_reg_write2(sc, TDA_VWIN_START_2_MSB, vwin2_line_start);
+ tda19988_reg_write2(sc, TDA_VWIN_END_2_MSB, vwin2_line_end);
+ tda19988_reg_write2(sc, TDA_DE_START_MSB, de_start);
+ tda19988_reg_write2(sc, TDA_DE_STOP_MSB, de_stop);
+
+ if (sc->sc_version == TDA19988)
+ tda19988_reg_write(sc, TDA_ENABLE_SPACE, 0x00);
+
+ /* must be last register set */
+ tda19988_reg_clear(sc, TDA_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_ONCE);
+}
+
+static int
+tda19988_read_edid_block(struct tda19988_softc *sc, uint8_t *buf, int block)
+{
+ int attempt, err;
+ uint8_t data;
+
+ err = 0;
+
+ tda19988_reg_set(sc, TDA_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
+
+ /* Block 0 */
+ tda19988_reg_write(sc, TDA_DDC_ADDR, 0xa0);
+ tda19988_reg_write(sc, TDA_DDC_OFFS, (block % 2) ? 128 : 0);
+ tda19988_reg_write(sc, TDA_DDC_SEGM_ADDR, 0x60);
+ tda19988_reg_write(sc, TDA_DDC_SEGM, block / 2);
+
+ tda19988_reg_write(sc, TDA_EDID_CTRL, 1);
+ tda19988_reg_write(sc, TDA_EDID_CTRL, 0);
+
+ data = 0;
+ for (attempt = 0; attempt < MAX_READ_ATTEMPTS; attempt++) {
+ tda19988_reg_read(sc, TDA_INT_FLAGS_2, &data);
+ if (data & INT_FLAGS_2_EDID_BLK_RD)
+ break;
+ pause("EDID", 1);
+ }
+
+ if (attempt == MAX_READ_ATTEMPTS) {
+ err = -1;
+ goto done;
+ }
+
+ if (tda19988_block_read(sc, TDA_EDID_DATA0, buf, EDID_LENGTH) != 0) {
+ err = -1;
+ goto done;
+ }
+
+done:
+ tda19988_reg_clear(sc, TDA_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
+
+ return (err);
+}
+
+static int
+tda19988_read_edid(struct tda19988_softc *sc)
+{
+ int err;
+ int blocks, i;
+ uint8_t *buf;
+
+ err = 0;
+ if (sc->sc_version == TDA19988)
+ tda19988_reg_clear(sc, TDA_TX4, TX4_PD_RAM);
+
+ err = tda19988_read_edid_block(sc, sc->sc_edid, 0);
+ if (err)
+ goto done;
+
+ blocks = sc->sc_edid[0x7e];
+ if (blocks > 0) {
+ sc->sc_edid = realloc(sc->sc_edid,
+ EDID_LENGTH*(blocks+1), M_DEVBUF, M_WAITOK);
+ sc->sc_edid_len = EDID_LENGTH*(blocks+1);
+ for (i = 0; i < blocks; i++) {
+ /* TODO: check validity */
+ buf = sc->sc_edid + EDID_LENGTH*(i+1);
+ err = tda19988_read_edid_block(sc, buf, i);
+ if (err)
+ goto done;
+ }
+ }
+
+ EVENTHANDLER_INVOKE(hdmi_event, 0);
+done:
+ if (sc->sc_version == TDA19988)
+ tda19988_reg_set(sc, TDA_TX4, TX4_PD_RAM);
+
+ return (err);
+}
+
+static void
+tda19988_start(void *xdev)
+{
+ struct tda19988_softc *sc;
+ device_t dev = (device_t)xdev;
+ uint8_t data;
+ uint16_t version;
+
+ sc = device_get_softc(dev);
+
+ tda19988_cec_write(sc, TDA_CEC_ENAMODS, ENAMODS_RXSENS | ENAMODS_HDMI);
+ DELAY(1000);
+ tda19988_cec_read(sc, 0xfe, &data);
+
+ /* Reset core */
+ tda19988_reg_set(sc, TDA_SOFTRESET, 3);
+ DELAY(100);
+ tda19988_reg_clear(sc, TDA_SOFTRESET, 3);
+ DELAY(100);
+
+ /* reset transmitter: */
+ tda19988_reg_set(sc, TDA_MAIN_CNTRL0, MAIN_CNTRL0_SR);
+ tda19988_reg_clear(sc, TDA_MAIN_CNTRL0, MAIN_CNTRL0_SR);
+
+ /* PLL registers common configuration */
+ tda19988_reg_write(sc, TDA_PLL_SERIAL_1, 0x00);
+ tda19988_reg_write(sc, TDA_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(1));
+ tda19988_reg_write(sc, TDA_PLL_SERIAL_3, 0x00);
+ tda19988_reg_write(sc, TDA_SERIALIZER, 0x00);
+ tda19988_reg_write(sc, TDA_BUFFER_OUT, 0x00);
+ tda19988_reg_write(sc, TDA_PLL_SCG1, 0x00);
+ tda19988_reg_write(sc, TDA_SEL_CLK, SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK);
+ tda19988_reg_write(sc, TDA_PLL_SCGN1, 0xfa);
+ tda19988_reg_write(sc, TDA_PLL_SCGN2, 0x00);
+ tda19988_reg_write(sc, TDA_PLL_SCGR1, 0x5b);
+ tda19988_reg_write(sc, TDA_PLL_SCGR2, 0x00);
+ tda19988_reg_write(sc, TDA_PLL_SCG2, 0x10);
+
+ /* Write the default value MUX register */
+ tda19988_reg_write(sc, TDA_MUX_VP_VIP_OUT, 0x24);
+
+ version = 0;
+ tda19988_reg_read(sc, TDA_VERSION, &data);
+ version |= data;
+ tda19988_reg_read(sc, TDA_VERSION_MSB, &data);
+ version |= (data << 8);
+
+ /* Clear feature bits */
+ sc->sc_version = version & ~0x30;
+ switch (sc->sc_version) {
+ case TDA19988:
+ device_printf(dev, "TDA19988\n");
+ break;
+ default:
+ device_printf(dev, "Unknown device: %04x\n", sc->sc_version);
+ goto done;
+ }
+
+ tda19988_reg_write(sc, TDA_DDC_CTRL, DDC_ENABLE);
+ tda19988_reg_write(sc, TDA_TX3, 39);
+
+ tda19988_cec_write(sc, TDA_CEC_FRO_IM_CLK_CTRL,
+ CEC_FRO_IM_CLK_CTRL_GHOST_DIS | CEC_FRO_IM_CLK_CTRL_IMCLK_SEL);
+
+ if (tda19988_read_edid(sc) < 0) {
+ device_printf(dev, "failed to read EDID\n");
+ goto done;
+ }
+
+ /* Default values for RGB 4:4:4 mapping */
+ tda19988_reg_write(sc, TDA_VIP_CNTRL_0, 0x23);
+ tda19988_reg_write(sc, TDA_VIP_CNTRL_1, 0x45);
+ tda19988_reg_write(sc, TDA_VIP_CNTRL_2, 0x01);
+
+done:
+ config_intrhook_disestablish(&sc->enum_hook);
+}
+
+static int
+tda19988_attach(device_t dev)
+{
+ struct tda19988_softc *sc;
+ phandle_t node;
+
+ sc = device_get_softc(dev);
+
+ sc->sc_dev = dev;
+ sc->sc_addr = iicbus_get_addr(dev) << 1;
+ sc->sc_cec_addr = (0x34 << 1); /* hardcoded */
+ sc->sc_edid = malloc(EDID_LENGTH, M_DEVBUF, M_WAITOK | M_ZERO);
+ sc->sc_edid_len = EDID_LENGTH;
+
+ device_set_desc(dev, "NXP TDA19988 HDMI transmitter");
+
+ sc->enum_hook.ich_func = tda19988_start;
+ sc->enum_hook.ich_arg = dev;
+
+ if (config_intrhook_establish(&sc->enum_hook) != 0)
+ return (ENOMEM);
+
+ node = ofw_bus_get_node(dev);
+ OF_device_register_xref(OF_xref_from_node(node), dev);
+
+ return (0);
+}
+
+static int
+tda19988_detach(device_t dev)
+{
+
+ /* XXX: Do not let unload drive */
+ return (EBUSY);
+}
+
+static int
+tda19988_get_edid(device_t dev, uint8_t **edid, uint32_t *edid_len)
+{
+ struct tda19988_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ if (sc->sc_edid) {
+ *edid = sc->sc_edid;
+ *edid_len = sc->sc_edid_len;
+ } else
+ return (ENXIO);
+
+ return (0);
+}
+
+static int
+tda19988_set_videomode(device_t dev, const struct videomode *mode)
+{
+ struct tda19988_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ tda19988_init_encoder(sc, mode);
+
+ return (0);
+}
+
+static device_method_t tda_methods[] = {
+ DEVMETHOD(device_probe, tda19988_probe),
+ DEVMETHOD(device_attach, tda19988_attach),
+ DEVMETHOD(device_detach, tda19988_detach),
+
+ /* HDMI methods */
+ DEVMETHOD(hdmi_get_edid, tda19988_get_edid),
+ DEVMETHOD(hdmi_set_videomode, tda19988_set_videomode),
+ {0, 0},
+};
+
+static driver_t tda_driver = {
+ "tda",
+ tda_methods,
+ sizeof(struct tda19988_softc),
+};
+
+static devclass_t tda_devclass;
+
+DRIVER_MODULE(tda, iicbus, tda_driver, tda_devclass, 0, 0);
+MODULE_VERSION(tda, 1);
+MODULE_DEPEND(tda, iicbus, 1, 1, 1);
diff --git a/sys/arm/ti/am335x/tps65217x.h b/sys/arm/ti/am335x/tps65217x.h
index 96f16dd..cdeca25 100644
--- a/sys/arm/ti/am335x/tps65217x.h
+++ b/sys/arm/ti/am335x/tps65217x.h
@@ -34,7 +34,7 @@
* TPS65217 PMIC is a companion chip for AM335x SoC sitting on I2C bus
*/
-/* TPS65217 Reisters */
+/* TPS65217 Registers */
#define TPS65217_CHIPID_REG 0x00
struct tps65217_chipid_reg {
unsigned int rev:4;
diff --git a/sys/arm/ti/omap4/omap4_prcm_clks.c b/sys/arm/ti/omap4/omap4_prcm_clks.c
index 8b1cb6e..fc5fb97 100644
--- a/sys/arm/ti/omap4/omap4_prcm_clks.c
+++ b/sys/arm/ti/omap4/omap4_prcm_clks.c
@@ -217,7 +217,8 @@ static int omap4_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int
.clk_deactivate = omap4_clk_generic_deactivate, \
.clk_set_source = omap4_clk_generic_set_source, \
.clk_accessible = omap4_clk_generic_accessible, \
- .clk_get_source_freq = omap4_clk_generic_get_source_freq \
+ .clk_get_source_freq = omap4_clk_generic_get_source_freq, \
+ .clk_set_source_freq = NULL \
}
#define OMAP4_GPTIMER_CLOCK_DEV(i) \
@@ -226,7 +227,8 @@ static int omap4_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int
.clk_deactivate = omap4_clk_generic_deactivate, \
.clk_set_source = omap4_clk_gptimer_set_source, \
.clk_accessible = omap4_clk_generic_accessible, \
- .clk_get_source_freq = omap4_clk_gptimer_get_source_freq \
+ .clk_get_source_freq = omap4_clk_gptimer_get_source_freq, \
+ .clk_set_source_freq = NULL \
}
#define OMAP4_HSMMC_CLOCK_DEV(i) \
@@ -235,7 +237,8 @@ static int omap4_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int
.clk_deactivate = omap4_clk_generic_deactivate, \
.clk_set_source = omap4_clk_hsmmc_set_source, \
.clk_accessible = omap4_clk_generic_accessible, \
- .clk_get_source_freq = omap4_clk_hsmmc_get_source_freq \
+ .clk_get_source_freq = omap4_clk_hsmmc_get_source_freq, \
+ .clk_set_source_freq = NULL \
}
#define OMAP4_HSUSBHOST_CLOCK_DEV(i) \
@@ -244,7 +247,8 @@ static int omap4_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int
.clk_deactivate = omap4_clk_hsusbhost_deactivate, \
.clk_set_source = omap4_clk_hsusbhost_set_source, \
.clk_accessible = omap4_clk_hsusbhost_accessible, \
- .clk_get_source_freq = NULL \
+ .clk_get_source_freq = NULL, \
+ .clk_set_source_freq = NULL \
}
@@ -257,6 +261,7 @@ struct ti_clock_dev ti_omap4_clk_devmap[] = {
.clk_set_source = NULL,
.clk_accessible = NULL,
.clk_get_source_freq = omap4_clk_get_sysclk_freq,
+ .clk_set_source_freq = NULL,
},
/* MPU (ARM) core clocks */
{ .id = MPU_CLK,
@@ -265,6 +270,7 @@ struct ti_clock_dev ti_omap4_clk_devmap[] = {
.clk_set_source = NULL,
.clk_accessible = NULL,
.clk_get_source_freq = omap4_clk_get_arm_fclk_freq,
+ .clk_set_source_freq = NULL,
},
diff --git a/sys/arm/ti/ti_prcm.c b/sys/arm/ti/ti_prcm.c
index 3c073f9..c5ab9c7 100644
--- a/sys/arm/ti/ti_prcm.c
+++ b/sys/arm/ti/ti_prcm.c
@@ -285,7 +285,7 @@ ti_prcm_clk_set_source(clk_ident_t clk, clk_src_t clksrc)
* @clk: identifier for the module to enable, see ti_prcm.h for a list
* of possible modules.
* @freq: pointer to an integer that upon return will contain the src freq
- *
+ *
* This function returns the frequency of the source clock.
*
* The real work done to enable the clock is really done in the callback
@@ -319,6 +319,39 @@ ti_prcm_clk_get_source_freq(clk_ident_t clk, unsigned int *freq)
ret = clk_dev->clk_get_source_freq(clk_dev, freq);
else
ret = EINVAL;
-
+
+ return (ret);
+}
+
+/**
+ * ti_prcm_clk_set_source_freq - sets the source clock frequency as close to freq as possible
+ * @clk: identifier for the module to enable, see ti_prcm.h for a list
+ * of possible modules.
+ * @freq: requested freq
+ *
+ * LOCKING:
+ * Internally locks the driver context.
+ *
+ * RETURNS:
+ * Returns 0 on success or positive error code on failure.
+ */
+int
+ti_prcm_clk_set_source_freq(clk_ident_t clk, unsigned int freq)
+{
+ struct ti_clock_dev *clk_dev;
+ int ret;
+
+ clk_dev = ti_prcm_clk_dev(clk);
+
+ /* Sanity check we managed to find the clock */
+ if (clk_dev == NULL)
+ return (EINVAL);
+
+ /* Get the source frequency of the clock */
+ if (clk_dev->clk_set_source_freq)
+ ret = clk_dev->clk_set_source_freq(clk_dev, freq);
+ else
+ ret = EINVAL;
+
return (ret);
}
diff --git a/sys/arm/ti/ti_prcm.h b/sys/arm/ti/ti_prcm.h
index eaea990..c40439a 100644
--- a/sys/arm/ti/ti_prcm.h
+++ b/sys/arm/ti/ti_prcm.h
@@ -184,6 +184,8 @@ struct ti_clock_dev {
int (*clk_set_source)(struct ti_clock_dev *clkdev,
clk_src_t clksrc);
int (*clk_accessible)(struct ti_clock_dev *clkdev);
+ int (*clk_set_source_freq)(struct ti_clock_dev *clkdev,
+ unsigned int freq);
int (*clk_get_source_freq)(struct ti_clock_dev *clkdev,
unsigned int *freq);
};
@@ -194,6 +196,7 @@ int ti_prcm_clk_disable(clk_ident_t clk);
int ti_prcm_clk_accessible(clk_ident_t clk);
int ti_prcm_clk_disable_autoidle(clk_ident_t clk);
int ti_prcm_clk_set_source(clk_ident_t clk, clk_src_t clksrc);
+int ti_prcm_clk_set_source_freq(clk_ident_t clk, unsigned int freq);
int ti_prcm_clk_get_source_freq(clk_ident_t clk, unsigned int *freq);
void ti_prcm_reset(void);
diff --git a/sys/arm64/acpica/OsdEnvironment.c b/sys/arm64/acpica/OsdEnvironment.c
new file mode 100644
index 0000000..79dc212
--- /dev/null
+++ b/sys/arm64/acpica/OsdEnvironment.c
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 2000,2001 Michael Smith
+ * Copyright (c) 2000 BSDi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <sys/sysctl.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+static u_long acpi_root_phys;
+
+SYSCTL_ULONG(_machdep, OID_AUTO, acpi_root, CTLFLAG_RD, &acpi_root_phys, 0,
+ "The physical address of the RSDP");
+
+ACPI_STATUS
+AcpiOsInitialize(void)
+{
+
+ return (AE_OK);
+}
+
+ACPI_STATUS
+AcpiOsTerminate(void)
+{
+
+ return (AE_OK);
+}
+
+static u_long
+acpi_get_root_from_loader(void)
+{
+ long acpi_root;
+
+ if (resource_long_value("acpi", 0, "rsdp", &acpi_root) == 0)
+ return (acpi_root);
+
+ return (0);
+}
+
+ACPI_PHYSICAL_ADDRESS
+AcpiOsGetRootPointer(void)
+{
+
+ if (acpi_root_phys == 0)
+ acpi_root_phys = acpi_get_root_from_loader();
+
+ return (acpi_root_phys);
+}
diff --git a/sys/arm64/acpica/acpi_machdep.c b/sys/arm64/acpica/acpi_machdep.c
new file mode 100644
index 0000000..da07cfc
--- /dev/null
+++ b/sys/arm64/acpica/acpi_machdep.c
@@ -0,0 +1,217 @@
+/*-
+ * Copyright (c) 2001 Mitsuru IWASAKI
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Andrew Turner 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#include <dev/acpica/acpivar.h>
+
+int
+acpi_machdep_init(device_t dev)
+{
+
+ return (0);
+}
+
+int
+acpi_machdep_quirks(int *quirks)
+{
+
+ return (0);
+}
+
+static void *
+map_table(vm_paddr_t pa, int offset, const char *sig)
+{
+ ACPI_TABLE_HEADER *header;
+ vm_offset_t length;
+ void *table;
+
+ header = pmap_mapbios(pa, sizeof(ACPI_TABLE_HEADER));
+ if (strncmp(header->Signature, sig, ACPI_NAME_SIZE) != 0) {
+ pmap_unmapbios((vm_offset_t)header, sizeof(ACPI_TABLE_HEADER));
+ return (NULL);
+ }
+ length = header->Length;
+ pmap_unmapbios((vm_offset_t)header, sizeof(ACPI_TABLE_HEADER));
+
+ table = pmap_mapbios(pa, length);
+ if (ACPI_FAILURE(AcpiTbChecksum(table, length))) {
+ if (bootverbose)
+ printf("ACPI: Failed checksum for table %s\n", sig);
+#if (ACPI_CHECKSUM_ABORT)
+ pmap_unmapbios(table, length);
+ return (NULL);
+#endif
+ }
+ return (table);
+}
+
+/*
+ * See if a given ACPI table is the requested table. Returns the
+ * length of the able if it matches or zero on failure.
+ */
+static int
+probe_table(vm_paddr_t address, const char *sig)
+{
+ ACPI_TABLE_HEADER *table;
+
+ table = pmap_mapbios(address, sizeof(ACPI_TABLE_HEADER));
+ if (table == NULL) {
+ if (bootverbose)
+ printf("ACPI: Failed to map table at 0x%jx\n",
+ (uintmax_t)address);
+ return (0);
+ }
+ if (bootverbose)
+ printf("Table '%.4s' at 0x%jx\n", table->Signature,
+ (uintmax_t)address);
+
+ if (strncmp(table->Signature, sig, ACPI_NAME_SIZE) != 0) {
+ pmap_unmapbios((vm_offset_t)table, sizeof(ACPI_TABLE_HEADER));
+ return (0);
+ }
+ pmap_unmapbios((vm_offset_t)table, sizeof(ACPI_TABLE_HEADER));
+ return (1);
+}
+
+/* Unmap a table previously mapped via acpi_map_table(). */
+void
+acpi_unmap_table(void *table)
+{
+ ACPI_TABLE_HEADER *header;
+
+ header = (ACPI_TABLE_HEADER *)table;
+ pmap_unmapbios((vm_offset_t)table, header->Length);
+}
+
+/*
+ * Try to map a table at a given physical address previously returned
+ * by acpi_find_table().
+ */
+void *
+acpi_map_table(vm_paddr_t pa, const char *sig)
+{
+
+ return (map_table(pa, 0, sig));
+}
+
+/*
+ * Return the physical address of the requested table or zero if one
+ * is not found.
+ */
+vm_paddr_t
+acpi_find_table(const char *sig)
+{
+ ACPI_PHYSICAL_ADDRESS rsdp_ptr;
+ ACPI_TABLE_RSDP *rsdp;
+ ACPI_TABLE_XSDT *xsdt;
+ ACPI_TABLE_HEADER *table;
+ vm_paddr_t addr;
+ int i, count;
+
+ if (resource_disabled("acpi", 0))
+ return (0);
+
+ /*
+ * Map in the RSDP. Since ACPI uses AcpiOsMapMemory() which in turn
+ * calls pmap_mapbios() to find the RSDP, we assume that we can use
+ * pmap_mapbios() to map the RSDP.
+ */
+ if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
+ return (0);
+ rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP));
+ if (rsdp == NULL) {
+ if (bootverbose)
+ printf("ACPI: Failed to map RSDP\n");
+ return (0);
+ }
+
+ addr = 0;
+ if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
+ /*
+ * AcpiOsGetRootPointer only verifies the checksum for
+ * the version 1.0 portion of the RSDP. Version 2.0 has
+ * an additional checksum that we verify first.
+ */
+ if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) {
+ if (bootverbose)
+ printf("ACPI: RSDP failed extended checksum\n");
+ return (0);
+ }
+ xsdt = map_table(rsdp->XsdtPhysicalAddress, 2, ACPI_SIG_XSDT);
+ if (xsdt == NULL) {
+ if (bootverbose)
+ printf("ACPI: Failed to map XSDT\n");
+ pmap_unmapbios((vm_offset_t)rsdp,
+ sizeof(ACPI_TABLE_RSDP));
+ return (0);
+ }
+ count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
+ sizeof(UINT64);
+ for (i = 0; i < count; i++)
+ if (probe_table(xsdt->TableOffsetEntry[i], sig)) {
+ addr = xsdt->TableOffsetEntry[i];
+ break;
+ }
+ acpi_unmap_table(xsdt);
+ }
+ pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP));
+
+ if (addr == 0) {
+ if (bootverbose)
+ printf("ACPI: No %s table found\n", sig);
+ return (0);
+ }
+ if (bootverbose)
+ printf("%s: Found table at 0x%jx\n", sig, (uintmax_t)addr);
+
+ /*
+ * Verify that we can map the full table and that its checksum is
+ * correct, etc.
+ */
+ table = map_table(addr, 0, sig);
+ if (table == NULL)
+ return (0);
+ acpi_unmap_table(table);
+
+ return (addr);
+}
diff --git a/sys/arm64/acpica/acpi_wakeup.c b/sys/arm64/acpica/acpi_wakeup.c
new file mode 100644
index 0000000..7724fdd
--- /dev/null
+++ b/sys/arm64/acpica/acpi_wakeup.c
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Andrew Turner 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+
+#include <dev/acpica/acpivar.h>
+
+/*
+ * ARM64TODO: Implement this.
+ */
+int
+acpi_sleep_machdep(struct acpi_softc *sc, int state)
+{
+
+ return (-1);
+}
+
+int
+acpi_wakeup_machdep(struct acpi_softc *sc, int state, int sleep_result,
+ int intr_enabled)
+{
+
+ /* ARM64TODO: We will need this with acpi_sleep_machdep */
+ KASSERT(sleep_result == -1,
+ ("acpi_wakeup_machdep: Invalid sleep result"));
+
+ return (sleep_result);
+}
diff --git a/sys/arm64/arm64/db_interface.c b/sys/arm64/arm64/db_interface.c
index 38834af..e40802f 100644
--- a/sys/arm64/arm64/db_interface.c
+++ b/sys/arm64/arm64/db_interface.c
@@ -156,13 +156,11 @@ db_write_bytes(vm_offset_t addr, size_t size, char *data)
}
*dst++ = *data++;
}
+ dsb(ish);
- dsb();
/* Clean D-cache and invalidate I-cache */
cpu_dcache_wb_range(addr, (vm_size_t)size);
cpu_icache_sync_range(addr, (vm_size_t)size);
- dsb();
- isb();
return (0);
}
diff --git a/sys/arm64/arm64/db_trace.c b/sys/arm64/arm64/db_trace.c
index 1e89bac..c606377 100644
--- a/sys/arm64/arm64/db_trace.c
+++ b/sys/arm64/arm64/db_trace.c
@@ -38,12 +38,7 @@ __FBSDID("$FreeBSD$");
#include <machine/armreg.h>
#include <machine/debug_monitor.h>
-
-struct unwind_state {
- uint64_t fp;
- uint64_t sp;
- uint64_t pc;
-};
+#include <machine/stack.h>
void
db_md_list_watchpoints()
@@ -67,22 +62,6 @@ db_md_set_watchpoint(db_expr_t addr, db_expr_t size)
HW_BREAKPOINT_RW));
}
-static int
-db_unwind_frame(struct unwind_state *frame)
-{
- uint64_t fp = frame->fp;
-
- if (fp == 0)
- return -1;
-
- frame->sp = fp + 0x10;
- /* FP to previous frame (X29) */
- frame->fp = *(uint64_t *)(fp);
- /* LR (X30) */
- frame->pc = *(uint64_t *)(fp + 8) - 4;
- return (0);
-}
-
static void
db_stack_trace_cmd(struct unwind_state *frame)
{
@@ -95,7 +74,7 @@ db_stack_trace_cmd(struct unwind_state *frame)
uint64_t pc = frame->pc;
int ret;
- ret = db_unwind_frame(frame);
+ ret = unwind_frame(frame);
if (ret < 0)
break;
diff --git a/sys/arm64/arm64/gic.c b/sys/arm64/arm64/gic.c
index 59fac99..7c0692e 100644
--- a/sys/arm64/arm64/gic.c
+++ b/sys/arm64/arm64/gic.c
@@ -51,11 +51,7 @@ __FBSDID("$FreeBSD$");
#include <machine/intr.h>
#include <machine/smp.h>
-#include <dev/fdt/fdt_common.h>
-#include <dev/ofw/openfirm.h>
-#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_bus_subr.h>
-
+#include <arm64/arm64/gic.h>
#include "pic_if.h"
@@ -102,18 +98,6 @@ __FBSDID("$FreeBSD$");
#define GICD_ICFGR_TRIG_EDGE (1 << 1)
#define GICD_ICFGR_TRIG_MASK 0x2
-struct arm_gic_softc {
- device_t gic_dev;
- struct resource * gic_res[3];
- bus_space_tag_t gic_c_bst;
- bus_space_tag_t gic_d_bst;
- bus_space_handle_t gic_c_bsh;
- bus_space_handle_t gic_d_bsh;
- uint8_t ver;
- struct mtx mutex;
- uint32_t nirqs;
-};
-
static struct resource_spec arm_gic_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Distributor registers */
{ SYS_RES_MEMORY, 1, RF_ACTIVE }, /* CPU Interrupt Intf. registers */
@@ -136,31 +120,6 @@ static pic_eoi_t gic_eoi;
static pic_mask_t gic_mask_irq;
static pic_unmask_t gic_unmask_irq;
-static struct ofw_compat_data compat_data[] = {
- {"arm,gic", true}, /* Non-standard, used in FreeBSD dts. */
- {"arm,gic-400", true},
- {"arm,cortex-a15-gic", true},
- {"arm,cortex-a9-gic", true},
- {"arm,cortex-a7-gic", true},
- {"arm,arm11mp-gic", true},
- {"brcm,brahma-b15-gic", true},
- {NULL, false}
-};
-
-static int
-arm_gic_probe(device_t dev)
-{
-
- if (!ofw_bus_status_okay(dev))
- return (ENXIO);
-
- if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
- return (ENXIO);
-
- device_set_desc(dev, "ARM Generic Interrupt Controller");
- return (BUS_PROBE_DEFAULT);
-}
-
#ifdef SMP
static void
gic_init_secondary(device_t dev)
@@ -367,7 +326,6 @@ arm_gic_ipi_clear(device_t dev, int ipi)
static device_method_t arm_gic_methods[] = {
/* Device interface */
- DEVMETHOD(device_probe, arm_gic_probe),
DEVMETHOD(device_attach, arm_gic_attach),
/* pic_if */
@@ -384,15 +342,5 @@ static device_method_t arm_gic_methods[] = {
{ 0, 0 }
};
-static driver_t arm_gic_driver = {
- "gic",
- arm_gic_methods,
- sizeof(struct arm_gic_softc),
-};
-
-static devclass_t arm_gic_devclass;
-
-EARLY_DRIVER_MODULE(gic, simplebus, arm_gic_driver, arm_gic_devclass, 0, 0,
- BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
-EARLY_DRIVER_MODULE(gic, ofwbus, arm_gic_driver, arm_gic_devclass, 0, 0,
- BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
+DEFINE_CLASS_0(gic, arm_gic_driver, arm_gic_methods,
+ sizeof(struct arm_gic_softc));
diff --git a/sys/arm64/arm64/gic.h b/sys/arm64/arm64/gic.h
new file mode 100644
index 0000000..2660884
--- /dev/null
+++ b/sys/arm64/arm64/gic.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * Copyright (c) 2014 Andrew Turner
+ * All rights reserved.
+ *
+ * Developed by Damjan Marion <damjan.marion@gmail.com>
+ *
+ * Based on OMAP4 GIC code by Ben Gray
+ *
+ * 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 company nor the name of the author 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$
+ */
+
+#ifndef _ARM64_GIC_H_
+#define _ARM64_GIC_H_
+
+DECLARE_CLASS(arm_gic_driver);
+
+struct arm_gic_softc {
+ device_t gic_dev;
+ struct resource * gic_res[3];
+ bus_space_tag_t gic_c_bst;
+ bus_space_tag_t gic_d_bst;
+ bus_space_handle_t gic_c_bsh;
+ bus_space_handle_t gic_d_bsh;
+ uint8_t ver;
+ struct mtx mutex;
+ uint32_t nirqs;
+};
+
+#endif
diff --git a/sys/arm64/arm64/gic_acpi.c b/sys/arm64/arm64/gic_acpi.c
new file mode 100644
index 0000000..ad26c0c
--- /dev/null
+++ b/sys/arm64/arm64/gic_acpi.c
@@ -0,0 +1,161 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Andrew Turner 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+
+#include <arm64/arm64/gic.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+
+#include <dev/acpica/acpivar.h>
+
+struct arm_gic_acpi_softc {
+ struct arm_gic_softc gic_sc;
+ struct resource_list res;
+};
+
+struct madt_table_data {
+ device_t parent;
+ ACPI_MADT_GENERIC_DISTRIBUTOR *dist;
+ ACPI_MADT_GENERIC_INTERRUPT *intr;
+};
+
+static void
+madt_handler(ACPI_SUBTABLE_HEADER *entry, void *arg)
+{
+ struct madt_table_data *madt_data;
+
+ madt_data = (struct madt_table_data *)arg;
+
+ switch(entry->Type) {
+ case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
+ if (madt_data->intr != NULL) {
+ if (bootverbose)
+ device_printf(madt_data->parent,
+ "gic: Already have an interrupt table");
+ break;
+ }
+
+ madt_data->intr = (ACPI_MADT_GENERIC_INTERRUPT *)entry;
+ break;
+
+ case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
+ if (madt_data->dist != NULL) {
+ if (bootverbose)
+ device_printf(madt_data->parent,
+ "gic: Already have a distributor table");
+ break;
+ }
+
+ madt_data->dist = (ACPI_MADT_GENERIC_DISTRIBUTOR *)entry;
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void
+arm_gic_acpi_identify(driver_t *driver, device_t parent)
+{
+ struct madt_table_data madt_data;
+ ACPI_TABLE_MADT *madt;
+ vm_paddr_t physaddr;
+ device_t dev;
+
+ physaddr = acpi_find_table(ACPI_SIG_MADT);
+ if (physaddr == 0)
+ return;
+
+ madt = acpi_map_table(physaddr, ACPI_SIG_MADT);
+ if (madt == NULL) {
+ device_printf(parent, "gic: Unable to map the MADT\n");
+ return;
+ }
+
+ madt_data.parent = parent;
+ madt_data.dist = NULL;
+ madt_data.intr = NULL;
+
+ acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length,
+ madt_handler, &madt_data);
+ if (madt_data.intr == NULL || madt_data.dist == NULL) {
+ device_printf(parent,
+ "No gic interrupt or distributor table\n");
+ goto out;
+ }
+
+ dev = BUS_ADD_CHILD(parent, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE,
+ "gic", -1);
+ if (dev == NULL) {
+ device_printf(parent, "add gic child failed\n");
+ goto out;
+ }
+
+ /* Add the MADT data */
+ BUS_SET_RESOURCE(parent, dev, SYS_RES_MEMORY, 0,
+ madt_data.dist->BaseAddress, PAGE_SIZE);
+ BUS_SET_RESOURCE(parent, dev, SYS_RES_MEMORY, 1,
+ madt_data.intr->BaseAddress, PAGE_SIZE);
+
+out:
+ acpi_unmap_table(madt);
+}
+
+static int
+arm_gic_acpi_probe(device_t dev)
+{
+
+ device_set_desc(dev, "ARM Generic Interrupt Controller");
+ return (BUS_PROBE_NOWILDCARD);
+}
+
+static device_method_t arm_gic_acpi_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_identify, arm_gic_acpi_identify),
+ DEVMETHOD(device_probe, arm_gic_acpi_probe),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_1(gic, arm_gic_acpi_driver, arm_gic_acpi_methods,
+ sizeof(struct arm_gic_acpi_softc), arm_gic_driver);
+
+static devclass_t arm_gic_acpi_devclass;
+
+EARLY_DRIVER_MODULE(gic, acpi, arm_gic_acpi_driver,
+ arm_gic_acpi_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
diff --git a/sys/arm64/arm64/gic_fdt.c b/sys/arm64/arm64/gic_fdt.c
new file mode 100644
index 0000000..5b70624
--- /dev/null
+++ b/sys/arm64/arm64/gic_fdt.c
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Andrew Turner 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm64/arm64/gic.h>
+
+static struct ofw_compat_data compat_data[] = {
+ {"arm,gic", true}, /* Non-standard, used in FreeBSD dts. */
+ {"arm,gic-400", true},
+ {"arm,cortex-a15-gic", true},
+ {"arm,cortex-a9-gic", true},
+ {"arm,cortex-a7-gic", true},
+ {"arm,arm11mp-gic", true},
+ {"brcm,brahma-b15-gic", true},
+ {NULL, false}
+};
+
+static int
+arm_gic_fdt_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
+ return (ENXIO);
+
+ device_set_desc(dev, "ARM Generic Interrupt Controller");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static device_method_t arm_gic_fdt_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, arm_gic_fdt_probe),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_1(gic, arm_gic_fdt_driver, arm_gic_fdt_methods,
+ sizeof(struct arm_gic_softc), arm_gic_driver);
+
+static devclass_t arm_gic_fdt_devclass;
+
+EARLY_DRIVER_MODULE(gic, simplebus, arm_gic_fdt_driver,
+ arm_gic_fdt_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
+EARLY_DRIVER_MODULE(gic, ofwbus, arm_gic_fdt_driver, arm_gic_fdt_devclass,
+ 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c
index 221b138..c36769d 100644
--- a/sys/arm64/arm64/machdep.c
+++ b/sys/arm64/arm64/machdep.c
@@ -392,6 +392,8 @@ cpu_est_clockrate(int cpu_id, uint64_t *rate)
void
cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
{
+
+ pcpu->pc_acpi_id = 0xffffffff;
}
void
diff --git a/sys/arm64/arm64/nexus.c b/sys/arm64/arm64/nexus.c
index d6c6d2b..764012e 100644
--- a/sys/arm64/arm64/nexus.c
+++ b/sys/arm64/arm64/nexus.c
@@ -60,12 +60,17 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h>
#include <machine/intr.h>
+#include "opt_acpi.h"
#include "opt_platform.h"
#ifdef FDT
#include <dev/fdt/fdt_common.h>
#include "ofw_bus_if.h"
#endif
+#ifdef DEV_ACPI
+#include <contrib/dev/acpica/include/acpi.h>
+#include <dev/acpica/acpivar.h>
+#endif
extern struct bus_space memmap_bus;
@@ -78,9 +83,19 @@ struct nexus_device {
#define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev))
static struct rman mem_rman;
+static struct rman irq_rman;
-static int nexus_probe(device_t);
static int nexus_attach(device_t);
+
+#ifdef FDT
+static device_probe_t nexus_fdt_probe;
+static device_attach_t nexus_fdt_attach;
+#endif
+#ifdef DEV_ACPI
+static device_probe_t nexus_acpi_probe;
+static device_attach_t nexus_acpi_attach;
+#endif
+
static int nexus_print_child(device_t, device_t);
static device_t nexus_add_child(device_t, u_int, const char *, int);
static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
@@ -89,6 +104,8 @@ static int nexus_activate_resource(device_t, device_t, int, int,
struct resource *);
static int nexus_config_intr(device_t dev, int irq, enum intr_trigger trig,
enum intr_polarity pol);
+static struct resource_list *nexus_get_reslist(device_t, device_t);
+static int nexus_set_resource(device_t, device_t, int, int, u_long, u_long);
static int nexus_deactivate_resource(device_t, device_t, int, int,
struct resource *);
@@ -102,21 +119,18 @@ static int nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent,
#endif
static device_method_t nexus_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, nexus_probe),
- DEVMETHOD(device_attach, nexus_attach),
/* Bus interface */
DEVMETHOD(bus_print_child, nexus_print_child),
DEVMETHOD(bus_add_child, nexus_add_child),
DEVMETHOD(bus_alloc_resource, nexus_alloc_resource),
DEVMETHOD(bus_activate_resource, nexus_activate_resource),
DEVMETHOD(bus_config_intr, nexus_config_intr),
+ DEVMETHOD(bus_get_resource_list, nexus_get_reslist),
+ DEVMETHOD(bus_set_resource, nexus_set_resource),
DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource),
DEVMETHOD(bus_setup_intr, nexus_setup_intr),
DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
-#ifdef FDT
- DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr),
-#endif
+
{ 0, 0 }
};
@@ -129,15 +143,6 @@ static driver_t nexus_driver = {
DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
static int
-nexus_probe(device_t dev)
-{
-
- device_quiet(dev); /* suppress attach message for neatness */
-
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
nexus_attach(device_t dev)
{
@@ -146,15 +151,14 @@ nexus_attach(device_t dev)
mem_rman.rm_type = RMAN_ARRAY;
mem_rman.rm_descr = "I/O memory addresses";
if (rman_init(&mem_rman) || rman_manage_region(&mem_rman, 0, ~0))
- panic("nexus_probe mem_rman");
-
- /* Add the ofwbus device */
- /* ARM64TODO: Alternatively add acpi */
- nexus_add_child(dev, 10, "ofwbus", 0);
+ panic("nexus_attach mem_rman");
+ irq_rman.rm_start = 0;
+ irq_rman.rm_end = ~0ul;
+ irq_rman.rm_type = RMAN_ARRAY;
+ irq_rman.rm_descr = "Interrupts";
+ if (rman_init(&irq_rman) || rman_manage_region(&irq_rman, 0, ~0))
+ panic("nexus_attach irq_rman");
- /*
- * First, deal with the children we know about already
- */
bus_generic_probe(dev);
bus_generic_attach(dev);
@@ -201,11 +205,34 @@ static struct resource *
nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
+ struct nexus_device *ndev = DEVTONX(child);
struct resource *rv;
+ struct resource_list_entry *rle;
struct rman *rm;
int needactivate = flags & RF_ACTIVE;
+ /*
+ * If this is an allocation of the "default" range for a given
+ * RID, and we know what the resources for this device are
+ * (ie. they aren't maintained by a child bus), then work out
+ * the start/end values.
+ */
+ if ((start == 0UL) && (end == ~0UL) && (count == 1)) {
+ if (device_get_parent(child) != bus || ndev == NULL)
+ return(NULL);
+ rle = resource_list_find(&ndev->nx_resources, type, *rid);
+ if (rle == NULL)
+ return(NULL);
+ start = rle->start;
+ end = rle->end;
+ count = rle->count;
+ }
+
switch (type) {
+ case SYS_RES_IRQ:
+ rm = &irq_rman;
+ break;
+
case SYS_RES_MEMORY:
case SYS_RES_IOPORT:
rm = &mem_rman;
@@ -297,6 +324,28 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid,
return (0);
}
+static struct resource_list *
+nexus_get_reslist(device_t dev, device_t child)
+{
+ struct nexus_device *ndev = DEVTONX(child);
+
+ return (&ndev->nx_resources);
+}
+
+static int
+nexus_set_resource(device_t dev, device_t child, int type, int rid,
+ u_long start, u_long count)
+{
+ struct nexus_device *ndev = DEVTONX(child);
+ struct resource_list *rl = &ndev->nx_resources;
+
+ /* XXX this should return a success/failure indicator */
+ resource_list_add(rl, type, rid, start, start + count - 1, count);
+
+ return(0);
+}
+
+
static int
nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
@@ -317,6 +366,41 @@ nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
}
#ifdef FDT
+static device_method_t nexus_fdt_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, nexus_fdt_probe),
+ DEVMETHOD(device_attach, nexus_fdt_attach),
+
+ /* OFW interface */
+ DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr),
+};
+
+#define nexus_baseclasses nexus_fdt_baseclasses
+DEFINE_CLASS_1(nexus, nexus_fdt_driver, nexus_fdt_methods, 1, nexus_driver);
+#undef nexus_baseclasses
+static devclass_t nexus_fdt_devclass;
+
+DRIVER_MODULE(nexus_fdt, root, nexus_fdt_driver, nexus_fdt_devclass, 0, 0);
+
+static int
+nexus_fdt_probe(device_t dev)
+{
+
+ if (OF_peer(0) == 0)
+ return (ENXIO);
+
+ device_quiet(dev);
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+nexus_fdt_attach(device_t dev)
+{
+
+ nexus_add_child(dev, 10, "ofwbus", 0);
+ return (nexus_attach(dev));
+}
+
static int
nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells,
pcell_t *intr)
@@ -336,3 +420,37 @@ nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells,
}
#endif
+#ifdef DEV_ACPI
+static device_method_t nexus_acpi_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, nexus_acpi_probe),
+ DEVMETHOD(device_attach, nexus_acpi_attach),
+};
+
+#define nexus_baseclasses nexus_acpi_baseclasses
+DEFINE_CLASS_1(nexus, nexus_acpi_driver, nexus_acpi_methods, 1,
+ nexus_driver);
+#undef nexus_baseclasses
+static devclass_t nexus_acpi_devclass;
+
+DRIVER_MODULE(nexus_acpi, root, nexus_acpi_driver, nexus_acpi_devclass, 0, 0);
+
+static int
+nexus_acpi_probe(device_t dev)
+{
+
+ if (acpi_identify() != 0)
+ return (ENXIO);
+
+ device_quiet(dev);
+ return (BUS_PROBE_LOW_PRIORITY);
+}
+
+static int
+nexus_acpi_attach(device_t dev)
+{
+
+ nexus_add_child(dev, 10, "acpi", 0);
+ return (nexus_attach(dev));
+}
+#endif
diff --git a/sys/arm64/arm64/unwind.c b/sys/arm64/arm64/unwind.c
new file mode 100644
index 0000000..13e0b54
--- /dev/null
+++ b/sys/arm64/arm64/unwind.c
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under
+ * the sponsorship of 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/param.h>
+
+#include <machine/stack.h>
+
+int
+unwind_frame(struct unwind_state *frame)
+{
+ uint64_t fp;
+
+ fp = frame->fp;
+ if (fp == 0)
+ return (-1);
+
+ frame->sp = fp + 0x10;
+ /* FP to previous frame (X29) */
+ frame->fp = *(uint64_t *)(fp);
+ /* LR (X30) */
+ frame->pc = *(uint64_t *)(fp + 8) - 4;
+
+ return (0);
+}
diff --git a/sys/arm64/arm64/vfp.c b/sys/arm64/arm64/vfp.c
index 7ce59b8..5e44d5e 100644
--- a/sys/arm64/arm64/vfp.c
+++ b/sys/arm64/arm64/vfp.c
@@ -120,7 +120,7 @@ vfp_save_state(struct thread *td)
td->td_pcb->pcb_fpcr = fpcr;
td->td_pcb->pcb_fpsr = fpsr;
- dsb();
+ dsb(ish);
vfp_disable();
}
critical_exit();
diff --git a/sys/arm64/conf/GENERIC b/sys/arm64/conf/GENERIC
index 8e20d60..4eae4df 100644
--- a/sys/arm64/conf/GENERIC
+++ b/sys/arm64/conf/GENERIC
@@ -95,3 +95,4 @@ device psci # Support for ARM PSCI
device bpf # Berkeley packet filter
options FDT
+device acpi
diff --git a/sys/arm64/include/acpica_machdep.h b/sys/arm64/include/acpica_machdep.h
new file mode 100644
index 0000000..9a3434a
--- /dev/null
+++ b/sys/arm64/include/acpica_machdep.h
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 2002 Mitsuru IWASAKI
+ * 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$
+ */
+
+/******************************************************************************
+ *
+ * Name: acpica_machdep.h - arch-specific defines, etc.
+ * $Revision$
+ *
+ *****************************************************************************/
+
+#ifndef __ACPICA_MACHDEP_H__
+#define __ACPICA_MACHDEP_H__
+
+
+#ifdef _KERNEL
+
+/* Only use the reduced hardware model */
+#define ACPI_REDUCED_HARDWARE 1
+
+/* Section 5.2.10.1: global lock acquire/release functions */
+int acpi_acquire_global_lock(volatile uint32_t *);
+int acpi_release_global_lock(volatile uint32_t *);
+
+void *acpi_map_table(vm_paddr_t pa, const char *sig);
+void acpi_unmap_table(void *table);
+vm_paddr_t acpi_find_table(const char *sig);
+
+#endif /* _KERNEL */
+
+#endif /* __ACPICA_MACHDEP_H__ */
diff --git a/sys/arm64/include/atomic.h b/sys/arm64/include/atomic.h
index f0f6c17..99252b8 100644
--- a/sys/arm64/include/atomic.h
+++ b/sys/arm64/include/atomic.h
@@ -29,13 +29,29 @@
#ifndef _MACHINE_ATOMIC_H_
#define _MACHINE_ATOMIC_H_
-#define isb() __asm __volatile("isb" : : : "memory")
-#define dsb() __asm __volatile("dsb sy" : : : "memory")
-#define dmb() __asm __volatile("dmb sy" : : : "memory")
+#define isb() __asm __volatile("isb" : : : "memory")
-#define mb() dmb()
-#define wmb() dmb()
-#define rmb() dmb()
+/*
+ * Options for DMB and DSB:
+ * oshld Outer Shareable, load
+ * oshst Outer Shareable, store
+ * osh Outer Shareable, all
+ * nshld Non-shareable, load
+ * nshst Non-shareable, store
+ * nsh Non-shareable, all
+ * ishld Inner Shareable, load
+ * ishst Inner Shareable, store
+ * ish Inner Shareable, all
+ * ld Full system, load
+ * st Full system, store
+ * sy Full system, all
+ */
+#define dsb(opt) __asm __volatile("dsb " __STRING(opt) : : : "memory")
+#define dmb(opt) __asm __volatile("dmb " __STRING(opt) : : : "memory")
+
+#define mb() dmb(sy) /* Full system memory barrier all */
+#define wmb() dmb(st) /* Full system memory barrier store */
+#define rmb() dmb(ld) /* Full system memory barrier load */
static __inline void
atomic_add_32(volatile uint32_t *p, uint32_t val)
diff --git a/sys/arm64/include/iodev.h b/sys/arm64/include/iodev.h
new file mode 100644
index 0000000..5521ff7
--- /dev/null
+++ b/sys/arm64/include/iodev.h
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Andrew Turner 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 _MACHINE_IODEV_H_
+#define _MACHINE_IODEV_H_
+
+#define iodev_read_1(a) \
+({ \
+ uint8_t val; \
+ __asm __volatile("ldrb %w0, [%1]" : "=&r" (val) : "r"(a)); \
+ val; \
+})
+
+#define iodev_read_2(a) \
+({ \
+ uint16_t val; \
+ __asm __volatile("ldrh %w0, [%1]" : "=&r" (val) : "r"(a)); \
+ val; \
+})
+
+#define iodev_read_4(a) \
+({ \
+ uint32_t val; \
+ __asm __volatile("ldr %w0, [%1]" : "=&r" (val) : "r"(a)); \
+ val; \
+})
+
+#define iodev_write_1(a, v) \
+ __asm __volatile("strb %w0, [%1]" :: "r" (v), "r"(a))
+
+#define iodev_write_2(a, v) \
+ __asm __volatile("strh %w0, [%1]" :: "r" (v), "r"(a))
+
+#define iodev_write_4(a, v) \
+ __asm __volatile("str %w0, [%1]" :: "r" (v), "r"(a))
+
+#endif /* _MACHINE_IODEV_H_ */
diff --git a/sys/arm64/include/pci_cfgreg.h b/sys/arm64/include/pci_cfgreg.h
new file mode 100644
index 0000000..da23dbe
--- /dev/null
+++ b/sys/arm64/include/pci_cfgreg.h
@@ -0,0 +1 @@
+/* $FreeBSD$ */
diff --git a/sys/arm64/include/pcpu.h b/sys/arm64/include/pcpu.h
index 6de3e89..19cd758 100644
--- a/sys/arm64/include/pcpu.h
+++ b/sys/arm64/include/pcpu.h
@@ -36,7 +36,8 @@
#define ALT_STACK_SIZE 128
#define PCPU_MD_FIELDS \
- char __pad[129]
+ u_int pc_acpi_id; /* ACPI CPU id */ \
+ char __pad[125]
#ifdef _KERNEL
diff --git a/sys/arm64/include/stack.h b/sys/arm64/include/stack.h
index 8131ce5..db0d4ab 100644
--- a/sys/arm64/include/stack.h
+++ b/sys/arm64/include/stack.h
@@ -32,4 +32,12 @@
#define INKERNEL(va) \
((va) >= VM_MIN_KERNEL_ADDRESS && (va) <= VM_MAX_KERNEL_ADDRESS)
+struct unwind_state {
+ uint64_t fp;
+ uint64_t sp;
+ uint64_t pc;
+};
+
+int unwind_frame(struct unwind_state *);
+
#endif /* !_MACHINE_STACK_H_ */
diff --git a/sys/boot/Makefile b/sys/boot/Makefile
index 2aa76b7..2607651 100644
--- a/sys/boot/Makefile
+++ b/sys/boot/Makefile
@@ -8,6 +8,8 @@ SUBDIR+= ficl
SUBDIR+= forth
.endif
+SUBDIR+= common
+
.include <bsd.arch.inc.mk>
# Pick the machine-dependent subdir based on the target architecture.
diff --git a/sys/boot/common/Makefile b/sys/boot/common/Makefile
new file mode 100644
index 0000000..fcca328
--- /dev/null
+++ b/sys/boot/common/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+.include <src.opts.mk>
+
+MAN+= loader.8
+.if ${MK_ZFS} != "no"
+MAN+= zfsloader.8
+.endif
+
+.include <bsd.prog.mk>
diff --git a/sys/boot/common/Makefile.inc b/sys/boot/common/Makefile.inc
index 54e8617..d647fe3 100644
--- a/sys/boot/common/Makefile.inc
+++ b/sys/boot/common/Makefile.inc
@@ -68,8 +68,3 @@ CFLAGS+= -DBOOT_PROMPT_123
SRCS+= install.c
CFLAGS+=-I${.CURDIR}/../../../../lib/libstand
.endif
-
-MAN+= loader.8
-.if ${MK_ZFS} != "no"
-MAN+= zfsloader.8
-.endif
diff --git a/sys/boot/efi/libefi/Makefile.depend b/sys/boot/efi/libefi/Makefile.depend
new file mode 100644
index 0000000..c77da59
--- /dev/null
+++ b/sys/boot/efi/libefi/Makefile.depend
@@ -0,0 +1,17 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sys/boot/efi/loader/arch/arm64/exec.c b/sys/boot/efi/loader/arch/arm64/exec.c
index 1f72269..d13e97b 100644
--- a/sys/boot/efi/loader/arch/arm64/exec.c
+++ b/sys/boot/efi/loader/arch/arm64/exec.c
@@ -42,6 +42,15 @@ __FBSDID("$FreeBSD$");
#include "loader_efi.h"
#include "cache.h"
+#include "platform/acfreebsd.h"
+#include "acconfig.h"
+#define ACPI_SYSTEM_XFACE
+#include "actypes.h"
+#include "actbl.h"
+
+static EFI_GUID acpi_guid = ACPI_TABLE_GUID;
+static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID;
+
static int elf64_exec(struct preloaded_file *amp);
static int elf64_obj_exec(struct preloaded_file *amp);
@@ -64,12 +73,41 @@ elf64_exec(struct preloaded_file *fp)
vm_offset_t clean_addr;
size_t clean_size;
struct file_metadata *md;
+ ACPI_TABLE_RSDP *rsdp;
EFI_STATUS status;
EFI_PHYSICAL_ADDRESS addr;
Elf_Ehdr *ehdr;
- int err;
+ char buf[24];
+ int err, revision;
void (*entry)(vm_offset_t);
+ rsdp = efi_get_table(&acpi20_guid);
+ if (rsdp == NULL) {
+ rsdp = efi_get_table(&acpi_guid);
+ }
+ if (rsdp != NULL) {
+ sprintf(buf, "0x%016llx", (unsigned long long)rsdp);
+ setenv("hint.acpi.0.rsdp", buf, 1);
+ revision = rsdp->Revision;
+ if (revision == 0)
+ revision = 1;
+ sprintf(buf, "%d", revision);
+ setenv("hint.acpi.0.revision", buf, 1);
+ strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId));
+ buf[sizeof(rsdp->OemId)] = '\0';
+ setenv("hint.acpi.0.oem", buf, 1);
+ sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress);
+ setenv("hint.acpi.0.rsdt", buf, 1);
+ if (revision >= 2) {
+ /* XXX extended checksum? */
+ sprintf(buf, "0x%016llx",
+ (unsigned long long)rsdp->XsdtPhysicalAddress);
+ setenv("hint.acpi.0.xsdt", buf, 1);
+ sprintf(buf, "%d", rsdp->Length);
+ setenv("hint.acpi.0.xsdt_length", buf, 1);
+ }
+ }
+
if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
return(EFTYPE);
diff --git a/sys/boot/fdt/dts/arm/beaglebone-black.dts b/sys/boot/fdt/dts/arm/beaglebone-black.dts
index f5144dd..21cbf83 100644
--- a/sys/boot/fdt/dts/arm/beaglebone-black.dts
+++ b/sys/boot/fdt/dts/arm/beaglebone-black.dts
@@ -29,3 +29,25 @@
#include "am335x-boneblack.dts"
#include "beaglebone-common.dtsi"
+
+&i2c0 {
+ tda998x: hdmi-encoder {
+ compatible = "nxp,tda998x";
+ reg = <0x70>;
+
+ pinctrl-names = "default", "off";
+ pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
+ pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
+ status = "okay";
+ };
+};
+
+&lcdc {
+ hdmi = <&tda998x>;
+};
+
+/ {
+ hdmi {
+ status = "disabled";
+ };
+};
diff --git a/sys/boot/ficl/Makefile.depend b/sys/boot/ficl/Makefile.depend
new file mode 100644
index 0000000..ab9c549
--- /dev/null
+++ b/sys/boot/ficl/Makefile.depend
@@ -0,0 +1,21 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libstand \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+softcore.o: softcore.c
+softcore.po: softcore.c
+.endif
diff --git a/sys/boot/i386/boot0/Makefile.depend b/sys/boot/i386/boot0/Makefile.depend
new file mode 100644
index 0000000..3af2d7f
--- /dev/null
+++ b/sys/boot/i386/boot0/Makefile.depend
@@ -0,0 +1,15 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sys/boot/i386/boot0sio/Makefile.depend b/sys/boot/i386/boot0sio/Makefile.depend
new file mode 100644
index 0000000..3af2d7f
--- /dev/null
+++ b/sys/boot/i386/boot0sio/Makefile.depend
@@ -0,0 +1,15 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sys/boot/i386/boot2/Makefile.depend b/sys/boot/i386/boot2/Makefile.depend
new file mode 100644
index 0000000..3af2d7f
--- /dev/null
+++ b/sys/boot/i386/boot2/Makefile.depend
@@ -0,0 +1,15 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sys/boot/i386/loader/Makefile b/sys/boot/i386/loader/Makefile
index 6e735a4..ade6054 100644
--- a/sys/boot/i386/loader/Makefile
+++ b/sys/boot/i386/loader/Makefile
@@ -5,6 +5,7 @@ MK_SSP= no
LOADER?= loader
PROG= ${LOADER}.sym
+MAN=
INTERNALPROG=
NEWVERSWHAT?= "bootstrap loader" x86
diff --git a/sys/boot/i386/loader/Makefile.depend b/sys/boot/i386/loader/Makefile.depend
new file mode 100644
index 0000000..3af2d7f
--- /dev/null
+++ b/sys/boot/i386/loader/Makefile.depend
@@ -0,0 +1,15 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sys/boot/i386/zfsloader/Makefile.depend b/sys/boot/i386/zfsloader/Makefile.depend
new file mode 100644
index 0000000..3af2d7f
--- /dev/null
+++ b/sys/boot/i386/zfsloader/Makefile.depend
@@ -0,0 +1,15 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sys/boot/mips/beri/loader/Makefile b/sys/boot/mips/beri/loader/Makefile
index d4292cc..a134f3d 100644
--- a/sys/boot/mips/beri/loader/Makefile
+++ b/sys/boot/mips/beri/loader/Makefile
@@ -31,6 +31,7 @@
.include <src.opts.mk>
MK_SSP= no
+MAN=
PROG?= loader
NEWVERSWHAT= "BERI loader" ${MACHINE_CPUARCH}
diff --git a/sys/boot/pc98/loader/Makefile b/sys/boot/pc98/loader/Makefile
index a001c20..9333f3c 100644
--- a/sys/boot/pc98/loader/Makefile
+++ b/sys/boot/pc98/loader/Makefile
@@ -2,6 +2,7 @@
.include <src.opts.mk>
MK_SSP= no
+MAN=
LOADER?= loader
PROG= ${LOADER}.sym
diff --git a/sys/boot/powerpc/kboot/Makefile b/sys/boot/powerpc/kboot/Makefile
index 0ca7d20..4601f29 100644
--- a/sys/boot/powerpc/kboot/Makefile
+++ b/sys/boot/powerpc/kboot/Makefile
@@ -2,6 +2,7 @@
.include <src.opts.mk>
MK_SSP= no
+MAN=
PROG= loader.kboot
NEWVERSWHAT= "kboot loader" ${MACHINE_ARCH}
diff --git a/sys/boot/powerpc/ofw/Makefile b/sys/boot/powerpc/ofw/Makefile
index 65b79ea..6a2fc70 100644
--- a/sys/boot/powerpc/ofw/Makefile
+++ b/sys/boot/powerpc/ofw/Makefile
@@ -2,6 +2,7 @@
.include <src.opts.mk>
MK_SSP= no
+MAN=
PROG= loader
NEWVERSWHAT= "Open Firmware loader" ${MACHINE_ARCH}
diff --git a/sys/boot/powerpc/ps3/Makefile b/sys/boot/powerpc/ps3/Makefile
index 3bb9cb3..861872f 100644
--- a/sys/boot/powerpc/ps3/Makefile
+++ b/sys/boot/powerpc/ps3/Makefile
@@ -2,6 +2,7 @@
.include <src.opts.mk>
MK_SSP= no
+MAN=
PROG= loader.ps3
NEWVERSWHAT= "Playstation 3 loader" ${MACHINE_ARCH}
diff --git a/sys/boot/sparc64/loader/Makefile b/sys/boot/sparc64/loader/Makefile
index ca2853c..5c9bfbb 100644
--- a/sys/boot/sparc64/loader/Makefile
+++ b/sys/boot/sparc64/loader/Makefile
@@ -2,6 +2,7 @@
.include <src.opts.mk>
MK_SSP= no
+MAN=
PROG?= loader
NEWVERSWHAT?= "bootstrap loader" sparc64
diff --git a/sys/boot/uboot/lib/copy.c b/sys/boot/uboot/lib/copy.c
index bb658e3..51416ac 100644
--- a/sys/boot/uboot/lib/copy.c
+++ b/sys/boot/uboot/lib/copy.c
@@ -118,6 +118,13 @@ uboot_loadaddr(u_int type, void *data, uint64_t addr)
this_block = eubldr;
this_size = eblock - eubldr;
}
+ } else if (subldr < sblock && eubldr < eblock) {
+ /* Loader is below or engulfs the sblock */
+ this_block = (eubldr < sblock) ? sblock : eubldr;
+ this_size = eblock - this_block;
+ } else {
+ this_block = 0;
+ this_size = 0;
}
if (biggest_size < this_size) {
biggest_block = this_block;
diff --git a/sys/boot/uboot/lib/glue.c b/sys/boot/uboot/lib/glue.c
index d01e33b..32c4df2 100644
--- a/sys/boot/uboot/lib/glue.c
+++ b/sys/boot/uboot/lib/glue.c
@@ -513,7 +513,7 @@ ub_env_enum(const char *last)
if (!syscall(API_ENV_ENUM, NULL, (uint32_t)last, (uint32_t)&env))
return (NULL);
- if (env == NULL)
+ if (env == NULL || last == env)
/* no more env. variables to enumerate */
return (NULL);
diff --git a/sys/cam/cam.c b/sys/cam/cam.c
index 939dd76..1f627ef 100644
--- a/sys/cam/cam.c
+++ b/sys/cam/cam.c
@@ -157,6 +157,56 @@ cam_strvis(u_int8_t *dst, const u_int8_t *src, int srclen, int dstlen)
*dst = '\0';
}
+void
+cam_strvis_sbuf(struct sbuf *sb, const u_int8_t *src, int srclen,
+ uint32_t flags)
+{
+
+ /* Trim leading/trailing spaces, nulls. */
+ while (srclen > 0 && src[0] == ' ')
+ src++, srclen--;
+ while (srclen > 0
+ && (src[srclen-1] == ' ' || src[srclen-1] == '\0'))
+ srclen--;
+
+ while (srclen > 0) {
+ if (*src < 0x20 || *src >= 0x80) {
+ /* SCSI-II Specifies that these should never occur. */
+ /* non-printable character */
+ switch (flags & CAM_STRVIS_FLAG_NONASCII_MASK) {
+ case CAM_STRVIS_FLAG_NONASCII_ESC:
+ sbuf_printf(sb, "\\%c%c%c",
+ ((*src & 0300) >> 6) + '0',
+ ((*src & 0070) >> 3) + '0',
+ ((*src & 0007) >> 0) + '0');
+ break;
+ case CAM_STRVIS_FLAG_NONASCII_RAW:
+ /*
+ * If we run into a NUL, just transform it
+ * into a space.
+ */
+ if (*src != 0x00)
+ sbuf_putc(sb, *src);
+ else
+ sbuf_putc(sb, ' ');
+ break;
+ case CAM_STRVIS_FLAG_NONASCII_SPC:
+ sbuf_putc(sb, ' ');
+ break;
+ case CAM_STRVIS_FLAG_NONASCII_TRIM:
+ default:
+ break;
+ }
+ } else {
+ /* normal character */
+ sbuf_putc(sb, *src);
+ }
+ src++;
+ srclen--;
+ }
+}
+
+
/*
* Compare string with pattern, returning 0 on match.
* Short pattern matches trailing blanks in name,
diff --git a/sys/cam/cam.h b/sys/cam/cam.h
index e08524b..63f83c7 100644
--- a/sys/cam/cam.h
+++ b/sys/cam/cam.h
@@ -342,6 +342,15 @@ typedef enum {
CAM_EAF_PRINT_RESULT = 0x20
} cam_error_ata_flags;
+typedef enum {
+ CAM_STRVIS_FLAG_NONE = 0x00,
+ CAM_STRVIS_FLAG_NONASCII_MASK = 0x03,
+ CAM_STRVIS_FLAG_NONASCII_TRIM = 0x00,
+ CAM_STRVIS_FLAG_NONASCII_RAW = 0x01,
+ CAM_STRVIS_FLAG_NONASCII_SPC = 0x02,
+ CAM_STRVIS_FLAG_NONASCII_ESC = 0x03
+} cam_strvis_flags;
+
struct cam_status_entry
{
cam_status status_code;
@@ -354,6 +363,7 @@ extern const int num_cam_status_entries;
extern int cam_sort_io_queues;
#endif
union ccb;
+struct sbuf;
#ifdef SYSCTL_DECL /* from sysctl.h */
SYSCTL_DECL(_kern_cam);
@@ -366,6 +376,8 @@ caddr_t cam_quirkmatch(caddr_t target, caddr_t quirk_table, int num_entries,
int entry_size, cam_quirkmatch_t *comp_func);
void cam_strvis(u_int8_t *dst, const u_int8_t *src, int srclen, int dstlen);
+void cam_strvis_sbuf(struct sbuf *sb, const u_int8_t *src, int srclen,
+ uint32_t flags);
int cam_strmatch(const u_int8_t *str, const u_int8_t *pattern, int str_len);
const struct cam_status_entry*
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index 6276774..3d562d0 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -383,8 +383,8 @@ static int ctl_open(struct cdev *dev, int flags, int fmt, struct thread *td);
static int ctl_close(struct cdev *dev, int flags, int fmt, struct thread *td);
static void ctl_ioctl_online(void *arg);
static void ctl_ioctl_offline(void *arg);
-static int ctl_ioctl_lun_enable(void *arg, struct ctl_id targ_id, int lun_id);
-static int ctl_ioctl_lun_disable(void *arg, struct ctl_id targ_id, int lun_id);
+static int ctl_ioctl_lun_enable(void *arg, int lun_id);
+static int ctl_ioctl_lun_disable(void *arg, int lun_id);
static int ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio);
static int ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio);
static int ctl_ioctl_submit_wait(union ctl_io *io);
@@ -399,7 +399,7 @@ static int ctl_ioctl_fill_ooa(struct ctl_lun *lun, uint32_t *cur_fill_num,
static int ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
struct thread *td);
static int ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *lun,
- struct ctl_be_lun *be_lun, struct ctl_id target_id);
+ struct ctl_be_lun *be_lun);
static int ctl_free_lun(struct ctl_lun *lun);
static void ctl_create_lun(struct ctl_be_lun *be_lun);
static struct ctl_port * ctl_io_port(struct ctl_io_hdr *io_hdr);
@@ -1128,13 +1128,6 @@ ctl_init(void)
softc->port_offset = (softc->ha_id - 1) * CTL_MAX_PORTS;
softc->persis_offset = softc->port_offset * CTL_MAX_INIT_PER_PORT;
- /*
- * XXX KDM need to figure out where we want to get our target ID
- * and WWID. Is it different on each port?
- */
- softc->target.id = 0;
- softc->target.wwid[0] = 0x12345678;
- softc->target.wwid[1] = 0x87654321;
STAILQ_INIT(&softc->lun_list);
STAILQ_INIT(&softc->pending_lun_queue);
STAILQ_INIT(&softc->fe_list);
@@ -1647,13 +1640,13 @@ ctl_create_iid(struct ctl_port *port, int iid, uint8_t *buf)
}
static int
-ctl_ioctl_lun_enable(void *arg, struct ctl_id targ_id, int lun_id)
+ctl_ioctl_lun_enable(void *arg, int lun_id)
{
return (0);
}
static int
-ctl_ioctl_lun_disable(void *arg, struct ctl_id targ_id, int lun_id)
+ctl_ioctl_lun_disable(void *arg, int lun_id)
{
return (0);
}
@@ -2478,28 +2471,9 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
mtx_unlock(&softc->ctl_lock);
if (cmd == CTL_ENABLE_PORT) {
- struct ctl_lun *lun;
-
- STAILQ_FOREACH(lun, &softc->lun_list,
- links) {
- port->lun_enable(port->targ_lun_arg,
- lun->target,
- lun->lun);
- }
-
ctl_port_online(port);
} else if (cmd == CTL_DISABLE_PORT) {
- struct ctl_lun *lun;
-
ctl_port_offline(port);
-
- STAILQ_FOREACH(lun, &softc->lun_list,
- links) {
- port->lun_disable(
- port->targ_lun_arg,
- lun->target,
- lun->lun);
- }
}
mtx_lock(&softc->ctl_lock);
@@ -3560,26 +3534,22 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
mtx_unlock(&softc->ctl_lock);
return (ENXIO);
}
+ mtx_unlock(&softc->ctl_lock); // XXX: port_enable sleeps
if (lm->plun < CTL_MAX_LUNS) {
if (lm->lun == UINT32_MAX)
retval = ctl_lun_map_unset(port, lm->plun);
else if (lm->lun < CTL_MAX_LUNS &&
softc->ctl_luns[lm->lun] != NULL)
retval = ctl_lun_map_set(port, lm->plun, lm->lun);
- else {
- mtx_unlock(&softc->ctl_lock);
+ else
return (ENXIO);
- }
} else if (lm->plun == UINT32_MAX) {
if (lm->lun == UINT32_MAX)
retval = ctl_lun_map_deinit(port);
else
retval = ctl_lun_map_init(port);
- } else {
- mtx_unlock(&softc->ctl_lock);
+ } else
return (ENXIO);
- }
- mtx_unlock(&softc->ctl_lock);
break;
}
default: {
@@ -3649,6 +3619,8 @@ ctl_port_idx(int port_num)
int
ctl_lun_map_init(struct ctl_port *port)
{
+ struct ctl_softc *softc = control_softc;
+ struct ctl_lun *lun;
uint32_t i;
if (port->lun_map == NULL)
@@ -3658,17 +3630,27 @@ ctl_lun_map_init(struct ctl_port *port)
return (ENOMEM);
for (i = 0; i < CTL_MAX_LUNS; i++)
port->lun_map[i] = UINT32_MAX;
+ if (port->status & CTL_PORT_STATUS_ONLINE) {
+ STAILQ_FOREACH(lun, &softc->lun_list, links)
+ port->lun_disable(port->targ_lun_arg, lun->lun);
+ }
return (0);
}
int
ctl_lun_map_deinit(struct ctl_port *port)
{
+ struct ctl_softc *softc = control_softc;
+ struct ctl_lun *lun;
if (port->lun_map == NULL)
return (0);
free(port->lun_map, M_CTL);
port->lun_map = NULL;
+ if (port->status & CTL_PORT_STATUS_ONLINE) {
+ STAILQ_FOREACH(lun, &softc->lun_list, links)
+ port->lun_enable(port->targ_lun_arg, lun->lun);
+ }
return (0);
}
@@ -3676,37 +3658,31 @@ int
ctl_lun_map_set(struct ctl_port *port, uint32_t plun, uint32_t glun)
{
int status;
+ uint32_t old;
if (port->lun_map == NULL) {
status = ctl_lun_map_init(port);
if (status != 0)
return (status);
}
+ old = port->lun_map[plun];
port->lun_map[plun] = glun;
+ if ((port->status & CTL_PORT_STATUS_ONLINE) && old >= CTL_MAX_LUNS)
+ port->lun_enable(port->targ_lun_arg, plun);
return (0);
}
int
ctl_lun_map_unset(struct ctl_port *port, uint32_t plun)
{
+ uint32_t old;
if (port->lun_map == NULL)
return (0);
+ old = port->lun_map[plun];
port->lun_map[plun] = UINT32_MAX;
- return (0);
-}
-
-int
-ctl_lun_map_unsetg(struct ctl_port *port, uint32_t glun)
-{
- int i;
-
- if (port->lun_map == NULL)
- return (0);
- for (i = 0; i < CTL_MAX_LUNS; i++) {
- if (port->lun_map[i] == glun)
- port->lun_map[i] = UINT32_MAX;
- }
+ if ((port->status & CTL_PORT_STATUS_ONLINE) && old < CTL_MAX_LUNS)
+ port->lun_disable(port->targ_lun_arg, plun);
return (0);
}
@@ -4532,10 +4508,9 @@ hex2bin(const char *str, uint8_t *buf, int buf_size)
*/
static int
ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
- struct ctl_be_lun *const be_lun, struct ctl_id target_id)
+ struct ctl_be_lun *const be_lun)
{
struct ctl_lun *nlun, *lun;
- struct ctl_port *port;
struct scsi_vpd_id_descriptor *desc;
struct scsi_vpd_id_t10 *t10id;
const char *eui, *naa, *scsiname, *vendor, *value;
@@ -4670,8 +4645,7 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
lun_number = ctl_ffz(ctl_softc->ctl_lun_mask, CTL_MAX_LUNS);
if (lun_number == -1) {
mtx_unlock(&ctl_softc->ctl_lock);
- printf("ctl: can't allocate LUN on target %ju, out of "
- "LUNs\n", (uintmax_t)target_id.id);
+ printf("ctl: can't allocate LUN, out of LUNs\n");
if (lun->flags & CTL_LUN_MALLOCED)
free(lun, M_CTL);
be_lun->lun_config_status(be_lun->be_lun,
@@ -4682,7 +4656,6 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
ctl_set_mask(ctl_softc->ctl_lun_mask, lun_number);
mtx_init(&lun->lun_lock, "CTL LUN", NULL, MTX_DEF);
- lun->target = target_id;
lun->lun = lun_number;
lun->be_lun = be_lun;
/*
@@ -4765,24 +4738,6 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
mtx_unlock(&ctl_softc->ctl_lock);
lun->be_lun->lun_config_status(lun->be_lun->be_lun, CTL_LUN_CONFIG_OK);
-
- /*
- * Run through each registered FETD and bring it online if it isn't
- * already. Enable the target ID if it hasn't been enabled, and
- * enable this particular LUN.
- */
- STAILQ_FOREACH(port, &ctl_softc->port_list, links) {
- int retval;
-
- retval = port->lun_enable(port->targ_lun_arg, target_id,lun_number);
- if (retval != 0) {
- printf("ctl_alloc_lun: FETD %s port %d returned error "
- "%d for lun_enable on target %ju lun %d\n",
- port->port_name, port->targ_port, retval,
- (uintmax_t)target_id.id, lun_number);
- } else
- port->status |= CTL_PORT_STATUS_LUN_ONLINE;
- }
return (0);
}
@@ -4796,7 +4751,6 @@ static int
ctl_free_lun(struct ctl_lun *lun)
{
struct ctl_softc *softc;
- struct ctl_port *port;
struct ctl_lun *nlun;
int i;
@@ -4804,9 +4758,6 @@ ctl_free_lun(struct ctl_lun *lun)
mtx_assert(&softc->ctl_lock, MA_OWNED);
- STAILQ_FOREACH(port, &softc->port_list, links)
- ctl_lun_map_unsetg(port, lun->lun);
-
STAILQ_REMOVE(&softc->lun_list, lun, ctl_lun, links);
ctl_clear_mask(softc->ctl_lun_mask, lun->lun);
@@ -4819,58 +4770,6 @@ ctl_free_lun(struct ctl_lun *lun)
softc->num_luns--;
/*
- * XXX KDM this scheme only works for a single target/multiple LUN
- * setup. It needs to be revamped for a multiple target scheme.
- *
- * XXX KDM this results in port->lun_disable() getting called twice,
- * once when ctl_disable_lun() is called, and a second time here.
- * We really need to re-think the LUN disable semantics. There
- * should probably be several steps/levels to LUN removal:
- * - disable
- * - invalidate
- * - free
- *
- * Right now we only have a disable method when communicating to
- * the front end ports, at least for individual LUNs.
- */
-#if 0
- STAILQ_FOREACH(port, &softc->port_list, links) {
- int retval;
-
- retval = port->lun_disable(port->targ_lun_arg, lun->target,
- lun->lun);
- if (retval != 0) {
- printf("ctl_free_lun: FETD %s port %d returned error "
- "%d for lun_disable on target %ju lun %jd\n",
- port->port_name, port->targ_port, retval,
- (uintmax_t)lun->target.id, (intmax_t)lun->lun);
- }
-
- if (STAILQ_FIRST(&softc->lun_list) == NULL) {
- port->status &= ~CTL_PORT_STATUS_LUN_ONLINE;
-
- retval = port->targ_disable(port->targ_lun_arg,lun->target);
- if (retval != 0) {
- printf("ctl_free_lun: FETD %s port %d "
- "returned error %d for targ_disable on "
- "target %ju\n", port->port_name,
- port->targ_port, retval,
- (uintmax_t)lun->target.id);
- } else
- port->status &= ~CTL_PORT_STATUS_TARG_ONLINE;
-
- if ((port->status & CTL_PORT_STATUS_TARG_ONLINE) != 0)
- continue;
-
-#if 0
- port->port_offline(port->onoff_arg);
- port->status &= ~CTL_PORT_STATUS_ONLINE;
-#endif
- }
- }
-#endif
-
- /*
* Tell the backend to free resources, if this LUN has a backend.
*/
atomic_subtract_int(&lun->be_lun->be->num_luns, 1);
@@ -4906,7 +4805,7 @@ ctl_create_lun(struct ctl_be_lun *be_lun)
/*
* ctl_alloc_lun() should handle all potential failure cases.
*/
- ctl_alloc_lun(softc, NULL, be_lun, softc->target);
+ ctl_alloc_lun(softc, NULL, be_lun);
}
int
@@ -4949,6 +4848,9 @@ ctl_enable_lun(struct ctl_be_lun *be_lun)
for (port = STAILQ_FIRST(&softc->port_list); port != NULL; port = nport) {
nport = STAILQ_NEXT(port, links);
+ if ((port->status & CTL_PORT_STATUS_ONLINE) == 0 ||
+ port->lun_map != NULL)
+ continue;
/*
* Drop the lock while we call the FETD's enable routine.
@@ -4956,20 +4858,14 @@ ctl_enable_lun(struct ctl_be_lun *be_lun)
* case of the internal initiator frontend.
*/
mtx_unlock(&softc->ctl_lock);
- retval = port->lun_enable(port->targ_lun_arg, lun->target,lun->lun);
+ retval = port->lun_enable(port->targ_lun_arg, lun->lun);
mtx_lock(&softc->ctl_lock);
if (retval != 0) {
printf("%s: FETD %s port %d returned error "
- "%d for lun_enable on target %ju lun %jd\n",
- __func__, port->port_name, port->targ_port, retval,
- (uintmax_t)lun->target.id, (intmax_t)lun->lun);
+ "%d for lun_enable on lun %jd\n",
+ __func__, port->port_name, port->targ_port,
+ retval, (intmax_t)lun->lun);
}
-#if 0
- else {
- /* NOTE: TODO: why does lun enable affect port status? */
- port->status |= CTL_PORT_STATUS_LUN_ONLINE;
- }
-#endif
}
mtx_unlock(&softc->ctl_lock);
@@ -4999,6 +4895,9 @@ ctl_disable_lun(struct ctl_be_lun *be_lun)
mtx_unlock(&lun->lun_lock);
STAILQ_FOREACH(port, &softc->port_list, links) {
+ if ((port->status & CTL_PORT_STATUS_ONLINE) == 0 ||
+ port->lun_map != NULL)
+ continue;
mtx_unlock(&softc->ctl_lock);
/*
* Drop the lock before we call the frontend's disable
@@ -5007,14 +4906,13 @@ ctl_disable_lun(struct ctl_be_lun *be_lun)
* XXX KDM what happens if the frontend list changes while
* we're traversing it? It's unlikely, but should be handled.
*/
- retval = port->lun_disable(port->targ_lun_arg, lun->target,
- lun->lun);
+ retval = port->lun_disable(port->targ_lun_arg, lun->lun);
mtx_lock(&softc->ctl_lock);
if (retval != 0) {
printf("%s: FETD %s port %d returned error "
- "%d for lun_disable on target %ju lun %jd\n",
- __func__, port->port_name, port->targ_port, retval,
- (uintmax_t)lun->target.id, (intmax_t)lun->lun);
+ "%d for lun_disable on lun %jd\n",
+ __func__, port->port_name, port->targ_port,
+ retval, (intmax_t)lun->lun);
}
}
@@ -9450,11 +9348,16 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
well_known = 0;
cdb = (struct scsi_report_luns *)ctsio->cdb;
+ port = ctl_io_port(&ctsio->io_hdr);
CTL_DEBUG_PRINT(("ctl_report_luns\n"));
mtx_lock(&softc->ctl_lock);
- num_luns = softc->num_luns;
+ num_luns = 0;
+ for (targ_lun_id = 0; targ_lun_id < CTL_MAX_LUNS; targ_lun_id++) {
+ if (ctl_lun_map_from_port(port, targ_lun_id) < CTL_MAX_LUNS)
+ num_luns++;
+ }
mtx_unlock(&softc->ctl_lock);
switch (cdb->select_report) {
@@ -9497,7 +9400,6 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
request_lun = (struct ctl_lun *)
ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
- port = ctl_io_port(&ctsio->io_hdr);
lun_datalen = sizeof(*lun_data) +
(num_luns * sizeof(struct scsi_report_luns_lundata));
diff --git a/sys/cam/ctl/ctl_frontend.c b/sys/cam/ctl/ctl_frontend.c
index c38e527..e22b9d4 100644
--- a/sys/cam/ctl/ctl_frontend.c
+++ b/sys/cam/ctl/ctl_frontend.c
@@ -301,6 +301,20 @@ ctl_port_set_wwns(struct ctl_port *port, int wwnn_valid, uint64_t wwnn,
void
ctl_port_online(struct ctl_port *port)
{
+ struct ctl_softc *softc = control_softc;
+ struct ctl_lun *lun;
+ uint32_t l;
+
+ if (port->lun_map) {
+ for (l = 0; l < CTL_MAX_LUNS; l++) {
+ if (ctl_lun_map_from_port(port, l) >= CTL_MAX_LUNS)
+ continue;
+ port->lun_enable(port->targ_lun_arg, l);
+ }
+ } else {
+ STAILQ_FOREACH(lun, &softc->lun_list, links)
+ port->lun_enable(port->targ_lun_arg, lun->lun);
+ }
port->port_online(port->onoff_arg);
/* XXX KDM need a lock here? */
port->status |= CTL_PORT_STATUS_ONLINE;
@@ -309,7 +323,21 @@ ctl_port_online(struct ctl_port *port)
void
ctl_port_offline(struct ctl_port *port)
{
+ struct ctl_softc *softc = control_softc;
+ struct ctl_lun *lun;
+ uint32_t l;
+
port->port_offline(port->onoff_arg);
+ if (port->lun_map) {
+ for (l = 0; l < CTL_MAX_LUNS; l++) {
+ if (ctl_lun_map_from_port(port, l) >= CTL_MAX_LUNS)
+ continue;
+ port->lun_disable(port->targ_lun_arg, l);
+ }
+ } else {
+ STAILQ_FOREACH(lun, &softc->lun_list, links)
+ port->lun_disable(port->targ_lun_arg, lun->lun);
+ }
/* XXX KDM need a lock here? */
port->status &= ~CTL_PORT_STATUS_ONLINE;
}
diff --git a/sys/cam/ctl/ctl_frontend.h b/sys/cam/ctl/ctl_frontend.h
index f1cc1c4..470d7a7 100644
--- a/sys/cam/ctl/ctl_frontend.h
+++ b/sys/cam/ctl/ctl_frontend.h
@@ -41,16 +41,14 @@
typedef enum {
CTL_PORT_STATUS_NONE = 0x00,
- CTL_PORT_STATUS_ONLINE = 0x01,
- CTL_PORT_STATUS_TARG_ONLINE = 0x02,
- CTL_PORT_STATUS_LUN_ONLINE = 0x04
+ CTL_PORT_STATUS_ONLINE = 0x01
} ctl_port_status;
typedef int (*fe_init_t)(void);
typedef void (*fe_shutdown_t)(void);
typedef void (*port_func_t)(void *onoff_arg);
typedef int (*port_info_func_t)(void *onoff_arg, struct sbuf *sb);
-typedef int (*lun_func_t)(void *arg, struct ctl_id targ_id, int lun_id);
+typedef int (*lun_func_t)(void *arg, int lun_id);
typedef int (*fe_ioctl_t)(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
struct thread *td);
diff --git a/sys/cam/ctl/ctl_frontend_cam_sim.c b/sys/cam/ctl/ctl_frontend_cam_sim.c
index e779e48..3abc572 100644
--- a/sys/cam/ctl/ctl_frontend_cam_sim.c
+++ b/sys/cam/ctl/ctl_frontend_cam_sim.c
@@ -99,8 +99,8 @@ int cfcs_init(void);
static void cfcs_poll(struct cam_sim *sim);
static void cfcs_online(void *arg);
static void cfcs_offline(void *arg);
-static int cfcs_lun_enable(void *arg, struct ctl_id target_id, int lun_id);
-static int cfcs_lun_disable(void *arg, struct ctl_id target_id, int lun_id);
+static int cfcs_lun_enable(void *arg, int lun_id);
+static int cfcs_lun_disable(void *arg, int lun_id);
static void cfcs_datamove(union ctl_io *io);
static void cfcs_done(union ctl_io *io);
void cfcs_action(struct cam_sim *sim, union ccb *ccb);
@@ -303,12 +303,12 @@ cfcs_offline(void *arg)
}
static int
-cfcs_lun_enable(void *arg, struct ctl_id target_id, int lun_id)
+cfcs_lun_enable(void *arg, int lun_id)
{
return (0);
}
static int
-cfcs_lun_disable(void *arg, struct ctl_id target_id, int lun_id)
+cfcs_lun_disable(void *arg, int lun_id)
{
return (0);
}
diff --git a/sys/cam/ctl/ctl_frontend_internal.c b/sys/cam/ctl/ctl_frontend_internal.c
index 23bd0cf..4768292 100644
--- a/sys/cam/ctl/ctl_frontend_internal.c
+++ b/sys/cam/ctl/ctl_frontend_internal.c
@@ -144,7 +144,6 @@ typedef enum {
} cfi_lun_state;
struct cfi_lun {
- struct ctl_id target_id;
int lun_id;
struct scsi_inquiry_data inq_data;
uint64_t num_blocks;
@@ -192,8 +191,8 @@ int cfi_init(void);
void cfi_shutdown(void) __unused;
static void cfi_online(void *arg);
static void cfi_offline(void *arg);
-static int cfi_lun_enable(void *arg, struct ctl_id target_id, int lun_id);
-static int cfi_lun_disable(void *arg, struct ctl_id target_id, int lun_id);
+static int cfi_lun_enable(void *arg, int lun_id);
+static int cfi_lun_disable(void *arg, int lun_id);
static void cfi_datamove(union ctl_io *io);
static cfi_error_action cfi_checkcond_parse(union ctl_io *io,
struct cfi_lun_io *lun_io);
@@ -324,7 +323,7 @@ cfi_offline(void *arg)
}
static int
-cfi_lun_enable(void *arg, struct ctl_id target_id, int lun_id)
+cfi_lun_enable(void *arg, int lun_id)
{
struct cfi_softc *softc;
struct cfi_lun *lun;
@@ -335,8 +334,7 @@ cfi_lun_enable(void *arg, struct ctl_id target_id, int lun_id)
found = 0;
mtx_lock(&softc->lock);
STAILQ_FOREACH(lun, &softc->lun_list, links) {
- if ((lun->target_id.id == target_id.id)
- && (lun->lun_id == lun_id)) {
+ if (lun->lun_id == lun_id) {
found = 1;
break;
}
@@ -356,7 +354,6 @@ cfi_lun_enable(void *arg, struct ctl_id target_id, int lun_id)
return (1);
}
- lun->target_id = target_id;
lun->lun_id = lun_id;
lun->cur_tag_num = 0;
lun->state = CFI_LUN_INQUIRY;
@@ -373,7 +370,7 @@ cfi_lun_enable(void *arg, struct ctl_id target_id, int lun_id)
}
static int
-cfi_lun_disable(void *arg, struct ctl_id target_id, int lun_id)
+cfi_lun_disable(void *arg, int lun_id)
{
struct cfi_softc *softc;
struct cfi_lun *lun;
@@ -391,8 +388,7 @@ cfi_lun_disable(void *arg, struct ctl_id target_id, int lun_id)
*/
mtx_lock(&softc->lock);
STAILQ_FOREACH(lun, &softc->lun_list, links) {
- if ((lun->target_id.id == target_id.id)
- && (lun->lun_id == lun_id)) {
+ if (lun->lun_id == lun_id) {
found = 1;
break;
}
@@ -403,8 +399,7 @@ cfi_lun_disable(void *arg, struct ctl_id target_id, int lun_id)
mtx_unlock(&softc->lock);
if (found == 0) {
- printf("%s: can't find target %ju lun %d\n", __func__,
- (uintmax_t)target_id.id, lun_id);
+ printf("%s: can't find lun %d\n", __func__, lun_id);
return (1);
}
@@ -700,7 +695,7 @@ cfi_init_io(union ctl_io *io, struct cfi_lun *lun,
io->io_hdr.nexus.initid.id = 7;
io->io_hdr.nexus.targ_port = lun->softc->port.targ_port;
- io->io_hdr.nexus.targ_target.id = lun->target_id.id;
+ io->io_hdr.nexus.targ_target.id = 0;
io->io_hdr.nexus.targ_lun = lun->lun_id;
io->io_hdr.retries = retries;
lun_io = (struct cfi_lun_io *)io->io_hdr.port_priv;
@@ -1008,8 +1003,7 @@ cfi_lun_probe(struct cfi_lun *lun, int have_lock)
M_CTL_CFI, M_NOWAIT);
if (dataptr == NULL) {
printf("%s: unable to allocate SCSI read capacity "
- "buffer for target %ju lun %d\n", __func__,
- (uintmax_t)lun->target_id.id, lun->lun_id);
+ "buffer for lun %d\n", __func__, lun->lun_id);
return;
}
if (lun->state == CFI_LUN_READCAPACITY) {
diff --git a/sys/cam/ctl/ctl_frontend_iscsi.c b/sys/cam/ctl/ctl_frontend_iscsi.c
index 2742c3d..652c961 100644
--- a/sys/cam/ctl/ctl_frontend_iscsi.c
+++ b/sys/cam/ctl/ctl_frontend_iscsi.c
@@ -147,10 +147,8 @@ int cfiscsi_init(void);
static void cfiscsi_online(void *arg);
static void cfiscsi_offline(void *arg);
static int cfiscsi_info(void *arg, struct sbuf *sb);
-static int cfiscsi_lun_enable(void *arg,
- struct ctl_id target_id, int lun_id);
-static int cfiscsi_lun_disable(void *arg,
- struct ctl_id target_id, int lun_id);
+static int cfiscsi_lun_enable(void *arg, int lun_id);
+static int cfiscsi_lun_disable(void *arg, int lun_id);
static int cfiscsi_ioctl(struct cdev *dev,
u_long cmd, caddr_t addr, int flag, struct thread *td);
static void cfiscsi_datamove(union ctl_io *io);
@@ -2373,14 +2371,14 @@ cfiscsi_target_find_or_create(struct cfiscsi_softc *softc, const char *name,
}
static int
-cfiscsi_lun_enable(void *arg, struct ctl_id target_id, int lun_id)
+cfiscsi_lun_enable(void *arg, int lun_id)
{
return (0);
}
static int
-cfiscsi_lun_disable(void *arg, struct ctl_id target_id, int lun_id)
+cfiscsi_lun_disable(void *arg, int lun_id)
{
return (0);
diff --git a/sys/cam/ctl/ctl_private.h b/sys/cam/ctl/ctl_private.h
index 428142c..8a00b5c 100644
--- a/sys/cam/ctl/ctl_private.h
+++ b/sys/cam/ctl/ctl_private.h
@@ -397,7 +397,6 @@ struct ctl_devid {
struct tpc_list;
struct ctl_lun {
struct mtx lun_lock;
- struct ctl_id target;
uint64_t lun;
ctl_lun_flags flags;
ctl_lun_serseq serseq;
@@ -460,7 +459,6 @@ struct ctl_softc {
struct mtx ctl_lock;
struct cdev *dev;
int open_count;
- struct ctl_id target;
int num_disks;
int num_luns;
ctl_gen_flags flags;
@@ -494,6 +492,7 @@ struct ctl_softc {
struct ctl_thread threads[CTL_MAX_THREADS];
TAILQ_HEAD(tpc_tokens, tpc_token) tpc_tokens;
struct callout tpc_timeout;
+ struct mtx tpc_lock;
};
#ifdef _KERNEL
@@ -507,7 +506,6 @@ int ctl_lun_map_init(struct ctl_port *port);
int ctl_lun_map_deinit(struct ctl_port *port);
int ctl_lun_map_set(struct ctl_port *port, uint32_t plun, uint32_t glun);
int ctl_lun_map_unset(struct ctl_port *port, uint32_t plun);
-int ctl_lun_map_unsetg(struct ctl_port *port, uint32_t glun);
uint32_t ctl_lun_map_from_port(struct ctl_port *port, uint32_t plun);
uint32_t ctl_lun_map_to_port(struct ctl_port *port, uint32_t glun);
int ctl_pool_create(struct ctl_softc *ctl_softc, const char *pool_name,
diff --git a/sys/cam/ctl/ctl_tpc.c b/sys/cam/ctl/ctl_tpc.c
index fee5b90..490cddd 100644
--- a/sys/cam/ctl/ctl_tpc.c
+++ b/sys/cam/ctl/ctl_tpc.c
@@ -167,6 +167,7 @@ tpc_timeout(void *arg)
}
/* Free inactive ROD tokens with expired timeout. */
+ mtx_lock(&softc->tpc_lock);
TAILQ_FOREACH_SAFE(token, &softc->tpc_tokens, links, ttoken) {
if (token->active ||
time_uptime < token->last_active + token->timeout + 1)
@@ -175,6 +176,7 @@ tpc_timeout(void *arg)
free(token->params, M_CTL);
free(token, M_CTL);
}
+ mtx_unlock(&softc->tpc_lock);
callout_schedule(&softc->tpc_timeout, hz);
}
@@ -182,6 +184,7 @@ void
ctl_tpc_init(struct ctl_softc *softc)
{
+ mtx_init(&softc->tpc_lock, "CTL TPC mutex", NULL, MTX_DEF);
TAILQ_INIT(&softc->tpc_tokens);
callout_init_mtx(&softc->tpc_timeout, &softc->ctl_lock, 0);
callout_reset(&softc->tpc_timeout, hz, tpc_timeout, softc);
@@ -195,13 +198,14 @@ ctl_tpc_shutdown(struct ctl_softc *softc)
callout_drain(&softc->tpc_timeout);
/* Free ROD tokens. */
- mtx_lock(&softc->ctl_lock);
+ mtx_lock(&softc->tpc_lock);
while ((token = TAILQ_FIRST(&softc->tpc_tokens)) != NULL) {
TAILQ_REMOVE(&softc->tpc_tokens, token, links);
free(token->params, M_CTL);
free(token, M_CTL);
}
- mtx_unlock(&softc->ctl_lock);
+ mtx_unlock(&softc->tpc_lock);
+ mtx_destroy(&softc->tpc_lock);
}
void
@@ -227,7 +231,7 @@ ctl_tpc_lun_shutdown(struct ctl_lun *lun)
}
/* Free ROD tokens for this LUN. */
- mtx_assert(&softc->ctl_lock, MA_OWNED);
+ mtx_lock(&softc->tpc_lock);
TAILQ_FOREACH_SAFE(token, &softc->tpc_tokens, links, ttoken) {
if (token->lun != lun->lun || token->active)
continue;
@@ -235,6 +239,7 @@ ctl_tpc_lun_shutdown(struct ctl_lun *lun)
free(token->params, M_CTL);
free(token, M_CTL);
}
+ mtx_unlock(&softc->tpc_lock);
}
int
@@ -1394,10 +1399,10 @@ done:
free(list->params, M_CTL);
list->params = NULL;
if (list->token) {
- mtx_lock(&softc->ctl_lock);
+ mtx_lock(&softc->tpc_lock);
if (--list->token->active == 0)
list->token->last_active = time_uptime;
- mtx_unlock(&softc->ctl_lock);
+ mtx_unlock(&softc->tpc_lock);
list->token = NULL;
}
mtx_lock(&lun->lun_lock);
@@ -1991,9 +1996,9 @@ ctl_populate_token(struct ctl_scsiio *ctsio)
list->curseg = 0;
list->completed = 1;
list->last_active = time_uptime;
- mtx_lock(&softc->ctl_lock);
+ mtx_lock(&softc->tpc_lock);
TAILQ_INSERT_TAIL(&softc->tpc_tokens, token, links);
- mtx_unlock(&softc->ctl_lock);
+ mtx_unlock(&softc->tpc_lock);
ctl_set_success(ctsio);
ctl_done((union ctl_io *)ctsio);
return (CTL_RETVAL_COMPLETE);
@@ -2100,7 +2105,7 @@ ctl_write_using_token(struct ctl_scsiio *ctsio)
return (CTL_RETVAL_COMPLETE);
}
- mtx_lock(&softc->ctl_lock);
+ mtx_lock(&softc->tpc_lock);
TAILQ_FOREACH(token, &softc->tpc_tokens, links) {
if (memcmp(token->token, data->rod_token,
sizeof(data->rod_token)) == 0)
@@ -2112,7 +2117,7 @@ ctl_write_using_token(struct ctl_scsiio *ctsio)
if (data->flags & EC_WUT_DEL_TKN)
token->timeout = 0;
}
- mtx_unlock(&softc->ctl_lock);
+ mtx_unlock(&softc->tpc_lock);
if (token == NULL) {
mtx_lock(&lun->lun_lock);
TAILQ_REMOVE(&lun->tpc_lists, list, links);
@@ -2254,10 +2259,10 @@ ctl_report_all_rod_tokens(struct ctl_scsiio *ctsio)
retval = CTL_RETVAL_COMPLETE;
tokens = 0;
- mtx_lock(&softc->ctl_lock);
+ mtx_lock(&softc->tpc_lock);
TAILQ_FOREACH(token, &softc->tpc_tokens, links)
tokens++;
- mtx_unlock(&softc->ctl_lock);
+ mtx_unlock(&softc->tpc_lock);
if (tokens > 512)
tokens = 512;
@@ -2282,7 +2287,7 @@ ctl_report_all_rod_tokens(struct ctl_scsiio *ctsio)
data = (struct scsi_report_all_rod_tokens_data *)ctsio->kern_data_ptr;
i = 0;
- mtx_lock(&softc->ctl_lock);
+ mtx_lock(&softc->tpc_lock);
TAILQ_FOREACH(token, &softc->tpc_tokens, links) {
if (i >= tokens)
break;
@@ -2290,7 +2295,7 @@ ctl_report_all_rod_tokens(struct ctl_scsiio *ctsio)
token->token, 96);
i++;
}
- mtx_unlock(&softc->ctl_lock);
+ mtx_unlock(&softc->tpc_lock);
scsi_ulto4b(sizeof(*data) - 4 + i * 96, data->available_data);
/*
printf("RART tokens=%d\n", i);
diff --git a/sys/cam/ctl/ctl_tpc_local.c b/sys/cam/ctl/ctl_tpc_local.c
index a8f675b..d0319ee 100644
--- a/sys/cam/ctl/ctl_tpc_local.c
+++ b/sys/cam/ctl/ctl_tpc_local.c
@@ -69,8 +69,8 @@ static int tpcl_init(void);
static void tpcl_shutdown(void);
static void tpcl_online(void *arg);
static void tpcl_offline(void *arg);
-static int tpcl_lun_enable(void *arg, struct ctl_id target_id, int lun_id);
-static int tpcl_lun_disable(void *arg, struct ctl_id target_id, int lun_id);
+static int tpcl_lun_enable(void *arg, int lun_id);
+static int tpcl_lun_disable(void *arg, int lun_id);
static void tpcl_datamove(union ctl_io *io);
static void tpcl_done(union ctl_io *io);
@@ -152,14 +152,14 @@ tpcl_offline(void *arg)
}
static int
-tpcl_lun_enable(void *arg, struct ctl_id target_id, int lun_id)
+tpcl_lun_enable(void *arg, int lun_id)
{
return (0);
}
static int
-tpcl_lun_disable(void *arg, struct ctl_id target_id, int lun_id)
+tpcl_lun_disable(void *arg, int lun_id)
{
return (0);
diff --git a/sys/cam/ctl/scsi_ctl.c b/sys/cam/ctl/scsi_ctl.c
index 74ec3df..6bd0196 100644
--- a/sys/cam/ctl/scsi_ctl.c
+++ b/sys/cam/ctl/scsi_ctl.c
@@ -104,10 +104,10 @@ struct ctlfe_lun_softc {
uint64_t ccbs_freed;
uint64_t ctios_sent;
uint64_t ctios_returned;
- uint64_t atios_sent;
- uint64_t atios_returned;
- uint64_t inots_sent;
- uint64_t inots_returned;
+ uint64_t atios_alloced;
+ uint64_t atios_freed;
+ uint64_t inots_alloced;
+ uint64_t inots_freed;
/* bus_dma_tag_t dma_tag; */
TAILQ_HEAD(, ccb_hdr) work_queue;
STAILQ_ENTRY(ctlfe_lun_softc) links;
@@ -202,10 +202,8 @@ static void ctlfedone(struct cam_periph *periph,
static void ctlfe_onoffline(void *arg, int online);
static void ctlfe_online(void *arg);
static void ctlfe_offline(void *arg);
-static int ctlfe_lun_enable(void *arg, struct ctl_id targ_id,
- int lun_id);
-static int ctlfe_lun_disable(void *arg, struct ctl_id targ_id,
- int lun_id);
+static int ctlfe_lun_enable(void *arg, int lun_id);
+static int ctlfe_lun_disable(void *arg, int lun_id);
static void ctlfe_dump_sim(struct cam_sim *sim);
static void ctlfe_dump_queue(struct ctlfe_lun_softc *softc);
static void ctlfe_datamove(union ctl_io *io);
@@ -546,6 +544,7 @@ ctlferegister(struct cam_periph *periph, void *arg)
status = CAM_RESRC_UNAVAIL;
break;
}
+ softc->atios_alloced++;
new_ccb->ccb_h.io_ptr = new_io;
xpt_setup_ccb(&new_ccb->ccb_h, periph->path, /*priority*/ 1);
@@ -553,7 +552,6 @@ ctlferegister(struct cam_periph *periph, void *arg)
new_ccb->ccb_h.cbfcnp = ctlfedone;
new_ccb->ccb_h.flags |= CAM_UNLOCKED;
xpt_action(new_ccb);
- softc->atios_sent++;
status = new_ccb->ccb_h.status;
if ((status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
ctl_free_io(new_io);
@@ -591,6 +589,7 @@ ctlferegister(struct cam_periph *periph, void *arg)
status = CAM_RESRC_UNAVAIL;
break;
}
+ softc->inots_alloced++;
new_ccb->ccb_h.io_ptr = new_io;
xpt_setup_ccb(&new_ccb->ccb_h, periph->path, /*priority*/ 1);
@@ -598,7 +597,6 @@ ctlferegister(struct cam_periph *periph, void *arg)
new_ccb->ccb_h.cbfcnp = ctlfedone;
new_ccb->ccb_h.flags |= CAM_UNLOCKED;
xpt_action(new_ccb);
- softc->inots_sent++;
status = new_ccb->ccb_h.status;
if ((status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
/*
@@ -650,10 +648,6 @@ ctlfeoninvalidate(struct cam_periph *periph)
* XXX KDM what do we do now?
*/
}
- xpt_print(periph->path, "LUN removed, %ju ATIOs outstanding, %ju "
- "INOTs outstanding, %d refs\n", softc->atios_sent -
- softc->atios_returned, softc->inots_sent -
- softc->inots_returned, periph->refcount);
bus_softc = softc->parent_softc;
mtx_lock(&bus_softc->lun_softc_mtx);
@@ -666,13 +660,20 @@ ctlfecleanup(struct cam_periph *periph)
{
struct ctlfe_lun_softc *softc;
- xpt_print(periph->path, "%s: Called\n", __func__);
-
softc = (struct ctlfe_lun_softc *)periph->softc;
- /*
- * XXX KDM is there anything else that needs to be done here?
- */
+ KASSERT(softc->ccbs_freed == softc->ccbs_alloced, ("%s: "
+ "ccbs_freed %ju != ccbs_alloced %ju", __func__,
+ softc->ccbs_freed, softc->ccbs_alloced));
+ KASSERT(softc->ctios_returned == softc->ctios_sent, ("%s: "
+ "ctios_returned %ju != ctios_sent %ju", __func__,
+ softc->ctios_returned, softc->ctios_sent));
+ KASSERT(softc->atios_freed == softc->atios_alloced, ("%s: "
+ "atios_freed %ju != atios_alloced %ju", __func__,
+ softc->atios_freed, softc->atios_alloced));
+ KASSERT(softc->inots_freed == softc->inots_alloced, ("%s: "
+ "inots_freed %ju != inots_alloced %ju", __func__,
+ softc->inots_freed, softc->inots_alloced));
free(softc, M_CTLFE);
}
@@ -845,15 +846,6 @@ ctlfestart(struct cam_periph *periph, union ccb *start_ccb)
atio->ccb_h.target_lun = CAM_LUN_WILDCARD;
}
- if ((atio->ccb_h.status & CAM_DEV_QFRZN) != 0) {
- cam_release_devq(periph->path,
- /*relsim_flags*/0,
- /*reduction*/0,
- /*timeout*/0,
- /*getcount_only*/0);
- atio->ccb_h.status &= ~CAM_DEV_QFRZN;
- }
-
if (atio->ccb_h.func_code != XPT_ACCEPT_TARGET_IO) {
xpt_print(periph->path, "%s: func_code "
"is %#x\n", __func__,
@@ -871,7 +863,6 @@ ctlfestart(struct cam_periph *periph, union ccb *start_ccb)
* Send the ATIO back down to the SIM.
*/
xpt_action((union ccb *)atio);
- softc->atios_sent++;
/*
* If we still have work to do, ask for
@@ -964,15 +955,6 @@ ctlfestart(struct cam_periph *periph, union ccb *start_ccb)
xpt_action(start_ccb);
cam_periph_lock(periph);
- if ((atio->ccb_h.status & CAM_DEV_QFRZN) != 0) {
- cam_release_devq(periph->path,
- /*relsim_flags*/0,
- /*reduction*/0,
- /*timeout*/0,
- /*getcount_only*/0);
- atio->ccb_h.status &= ~CAM_DEV_QFRZN;
- }
-
/*
* If we still have work to do, ask for another CCB.
*/
@@ -989,11 +971,11 @@ ctlfe_free_ccb(struct cam_periph *periph, union ccb *ccb)
switch (ccb->ccb_h.func_code) {
case XPT_ACCEPT_TARGET_IO:
- softc->atios_returned++;
+ softc->atios_freed++;
break;
case XPT_IMMEDIATE_NOTIFY:
case XPT_NOTIFY_ACKNOWLEDGE:
- softc->inots_returned++;
+ softc->inots_freed++;
break;
default:
break;
@@ -1002,20 +984,20 @@ ctlfe_free_ccb(struct cam_periph *periph, union ccb *ccb)
ctl_free_io(ccb->ccb_h.io_ptr);
free(ccb, M_CTLFE);
- KASSERT(softc->atios_returned <= softc->atios_sent, ("%s: "
- "atios_returned %ju > atios_sent %ju", __func__,
- softc->atios_returned, softc->atios_sent));
- KASSERT(softc->inots_returned <= softc->inots_sent, ("%s: "
- "inots_returned %ju > inots_sent %ju", __func__,
- softc->inots_returned, softc->inots_sent));
+ KASSERT(softc->atios_freed <= softc->atios_alloced, ("%s: "
+ "atios_freed %ju > atios_alloced %ju", __func__,
+ softc->atios_freed, softc->atios_alloced));
+ KASSERT(softc->inots_freed <= softc->inots_alloced, ("%s: "
+ "inots_freed %ju > inots_alloced %ju", __func__,
+ softc->inots_freed, softc->inots_alloced));
/*
* If we have received all of our CCBs, we can release our
* reference on the peripheral driver. It will probably go away
* now.
*/
- if ((softc->atios_returned == softc->atios_sent)
- && (softc->inots_returned == softc->inots_sent)) {
+ if ((softc->atios_freed == softc->atios_alloced)
+ && (softc->inots_freed == softc->inots_alloced)) {
cam_periph_release_locked(periph);
}
}
@@ -1105,6 +1087,19 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb)
done_ccb->ccb_h.func_code);
#endif
+ /*
+ * At this point CTL has no known use case for device queue freezes.
+ * In case some SIM think different -- drop its freeze right here.
+ */
+ if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
+ cam_release_devq(periph->path,
+ /*relsim_flags*/0,
+ /*reduction*/0,
+ /*timeout*/0,
+ /*getcount_only*/0);
+ done_ccb->ccb_h.status &= ~CAM_DEV_QFRZN;
+ }
+
softc = (struct ctlfe_lun_softc *)periph->softc;
bus_softc = softc->parent_softc;
mtx = cam_periph_mtx(periph);
@@ -1135,8 +1130,6 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb)
atio = &done_ccb->atio;
- softc->atios_returned++;
-
resubmit:
/*
* Allocate a ctl_io, pass it to CTL, and wait for the
@@ -1291,7 +1284,6 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb)
if (periph->flags & CAM_PERIPH_INVALID) {
ctlfe_free_ccb(periph, (union ccb *)atio);
} else {
- softc->atios_sent++;
mtx_unlock(mtx);
xpt_action((union ccb *)atio);
return;
@@ -1418,14 +1410,9 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb)
union ctl_io *io;
struct ccb_immediate_notify *inot;
cam_status status;
- int frozen, send_ctl_io;
+ int send_ctl_io;
inot = &done_ccb->cin1;
-
- softc->inots_returned++;
-
- frozen = (done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0;
-
printf("%s: got XPT_IMMEDIATE_NOTIFY status %#x tag %#x "
"seq %#x\n", __func__, inot->ccb_h.status,
inot->tag_id, inot->seq_id);
@@ -1527,14 +1514,6 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb)
done_ccb->ccb_h.func_code = XPT_NOTIFY_ACKNOWLEDGE;
xpt_action(done_ccb);
}
-
- if (frozen != 0) {
- cam_release_devq(periph->path,
- /*relsim_flags*/ 0,
- /*opening reduction*/ 0,
- /*timeout*/ 0,
- /*getcount_only*/ 0);
- }
break;
}
case XPT_NOTIFY_ACKNOWLEDGE:
@@ -1543,7 +1522,6 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb)
*/
done_ccb->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY;
xpt_action(done_ccb);
- softc->inots_sent++;
break;
case XPT_SET_SIM_KNOB:
case XPT_GET_SIM_KNOB:
@@ -1820,7 +1798,7 @@ ctlfe_offline(void *arg)
* CTL. So we only need to create a path/periph for this particular bus.
*/
static int
-ctlfe_lun_enable(void *arg, struct ctl_id targ_id, int lun_id)
+ctlfe_lun_enable(void *arg, int lun_id)
{
struct ctlfe_softc *bus_softc;
struct ctlfe_lun_softc *softc;
@@ -1831,8 +1809,7 @@ ctlfe_lun_enable(void *arg, struct ctl_id targ_id, int lun_id)
bus_softc = (struct ctlfe_softc *)arg;
status = xpt_create_path(&path, /*periph*/ NULL,
- bus_softc->path_id,
- targ_id.id, lun_id);
+ bus_softc->path_id, 0, lun_id);
/* XXX KDM need some way to return status to CTL here? */
if (status != CAM_REQ_CMP) {
printf("%s: could not create path, status %#x\n", __func__,
@@ -1883,7 +1860,7 @@ ctlfe_lun_enable(void *arg, struct ctl_id targ_id, int lun_id)
* on every bus that is attached to CTL.
*/
static int
-ctlfe_lun_disable(void *arg, struct ctl_id targ_id, int lun_id)
+ctlfe_lun_disable(void *arg, int lun_id)
{
struct ctlfe_softc *softc;
struct ctlfe_lun_softc *lun_softc;
@@ -1896,15 +1873,14 @@ ctlfe_lun_disable(void *arg, struct ctl_id targ_id, int lun_id)
path = lun_softc->periph->path;
- if ((xpt_path_target_id(path) == targ_id.id)
+ if ((xpt_path_target_id(path) == 0)
&& (xpt_path_lun_id(path) == lun_id)) {
break;
}
}
if (lun_softc == NULL) {
mtx_unlock(&softc->lun_softc_mtx);
- printf("%s: can't find target %d lun %d\n", __func__,
- targ_id.id, lun_id);
+ printf("%s: can't find lun %d\n", __func__, lun_id);
return (1);
}
cam_periph_acquire(lun_softc->periph);
@@ -2043,7 +2019,6 @@ ctlfe_done(union ctl_io *io)
if (periph->flags & CAM_PERIPH_INVALID) {
ctlfe_free_ccb(periph, ccb);
} else {
- softc->atios_sent++;
cam_periph_unlock(periph);
xpt_action(ccb);
return;
diff --git a/sys/cam/scsi/scsi_all.c b/sys/cam/scsi/scsi_all.c
index a429259..8f27fd9 100644
--- a/sys/cam/scsi/scsi_all.c
+++ b/sys/cam/scsi/scsi_all.c
@@ -6453,6 +6453,830 @@ bailout:
return (retval);
}
+struct scsi_attrib_table_entry scsi_mam_attr_table[] = {
+ { SMA_ATTR_REM_CAP_PARTITION, SCSI_ATTR_FLAG_NONE,
+ "Remaining Capacity in Partition",
+ /*suffix*/ "MB", /*to_str*/ scsi_attrib_int_sbuf,/*parse_str*/ NULL },
+ { SMA_ATTR_MAX_CAP_PARTITION, SCSI_ATTR_FLAG_NONE,
+ "Maximum Capacity in Partition",
+ /*suffix*/"MB", /*to_str*/ scsi_attrib_int_sbuf, /*parse_str*/ NULL },
+ { SMA_ATTR_TAPEALERT_FLAGS, SCSI_ATTR_FLAG_HEX,
+ "TapeAlert Flags",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, /*parse_str*/ NULL },
+ { SMA_ATTR_LOAD_COUNT, SCSI_ATTR_FLAG_NONE,
+ "Load Count",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, /*parse_str*/ NULL },
+ { SMA_ATTR_MAM_SPACE_REMAINING, SCSI_ATTR_FLAG_NONE,
+ "MAM Space Remaining",
+ /*suffix*/"bytes", /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_DEV_ASSIGNING_ORG, SCSI_ATTR_FLAG_NONE,
+ "Assigning Organization",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_FORMAT_DENSITY_CODE, SCSI_ATTR_FLAG_HEX,
+ "Format Density Code",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, /*parse_str*/ NULL },
+ { SMA_ATTR_INITIALIZATION_COUNT, SCSI_ATTR_FLAG_NONE,
+ "Initialization Count",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, /*parse_str*/ NULL },
+ { SMA_ATTR_VOLUME_ID, SCSI_ATTR_FLAG_NONE,
+ "Volume Identifier",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_VOLUME_CHANGE_REF, SCSI_ATTR_FLAG_HEX,
+ "Volume Change Reference",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_DEV_SERIAL_LAST_LOAD, SCSI_ATTR_FLAG_NONE,
+ "Device Vendor/Serial at Last Load",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_vendser_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_DEV_SERIAL_LAST_LOAD_1, SCSI_ATTR_FLAG_NONE,
+ "Device Vendor/Serial at Last Load - 1",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_vendser_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_DEV_SERIAL_LAST_LOAD_2, SCSI_ATTR_FLAG_NONE,
+ "Device Vendor/Serial at Last Load - 2",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_vendser_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_DEV_SERIAL_LAST_LOAD_3, SCSI_ATTR_FLAG_NONE,
+ "Device Vendor/Serial at Last Load - 3",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_vendser_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_TOTAL_MB_WRITTEN_LT, SCSI_ATTR_FLAG_NONE,
+ "Total MB Written in Medium Life",
+ /*suffix*/ "MB", /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_TOTAL_MB_READ_LT, SCSI_ATTR_FLAG_NONE,
+ "Total MB Read in Medium Life",
+ /*suffix*/ "MB", /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_TOTAL_MB_WRITTEN_CUR, SCSI_ATTR_FLAG_NONE,
+ "Total MB Written in Current/Last Load",
+ /*suffix*/ "MB", /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_TOTAL_MB_READ_CUR, SCSI_ATTR_FLAG_NONE,
+ "Total MB Read in Current/Last Load",
+ /*suffix*/ "MB", /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_FIRST_ENC_BLOCK, SCSI_ATTR_FLAG_NONE,
+ "Logical Position of First Encrypted Block",
+ /*suffix*/ NULL, /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_NEXT_UNENC_BLOCK, SCSI_ATTR_FLAG_NONE,
+ "Logical Position of First Unencrypted Block after First "
+ "Encrypted Block",
+ /*suffix*/ NULL, /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MEDIUM_USAGE_HIST, SCSI_ATTR_FLAG_NONE,
+ "Medium Usage History",
+ /*suffix*/ NULL, /*to_str*/ NULL,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_PART_USAGE_HIST, SCSI_ATTR_FLAG_NONE,
+ "Partition Usage History",
+ /*suffix*/ NULL, /*to_str*/ NULL,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_MANUF, SCSI_ATTR_FLAG_NONE,
+ "Medium Manufacturer",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_SERIAL, SCSI_ATTR_FLAG_NONE,
+ "Medium Serial Number",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_LENGTH, SCSI_ATTR_FLAG_NONE,
+ "Medium Length",
+ /*suffix*/"m", /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_WIDTH, SCSI_ATTR_FLAG_FP | SCSI_ATTR_FLAG_DIV_10 |
+ SCSI_ATTR_FLAG_FP_1DIGIT,
+ "Medium Width",
+ /*suffix*/"mm", /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_ASSIGNING_ORG, SCSI_ATTR_FLAG_NONE,
+ "Assigning Organization",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_DENSITY_CODE, SCSI_ATTR_FLAG_HEX,
+ "Medium Density Code",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_MANUF_DATE, SCSI_ATTR_FLAG_NONE,
+ "Medium Manufacture Date",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MAM_CAPACITY, SCSI_ATTR_FLAG_NONE,
+ "MAM Capacity",
+ /*suffix*/"bytes", /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_TYPE, SCSI_ATTR_FLAG_HEX,
+ "Medium Type",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_TYPE_INFO, SCSI_ATTR_FLAG_HEX,
+ "Medium Type Information",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_SERIAL_NUM, SCSI_ATTR_FLAG_NONE,
+ "Medium Serial Number",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_APP_VENDOR, SCSI_ATTR_FLAG_NONE,
+ "Application Vendor",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_APP_NAME, SCSI_ATTR_FLAG_NONE,
+ "Application Name",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_APP_VERSION, SCSI_ATTR_FLAG_NONE,
+ "Application Version",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_USER_MED_TEXT_LABEL, SCSI_ATTR_FLAG_NONE,
+ "User Medium Text Label",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_text_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_LAST_WRITTEN_TIME, SCSI_ATTR_FLAG_NONE,
+ "Date and Time Last Written",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_TEXT_LOCAL_ID, SCSI_ATTR_FLAG_HEX,
+ "Text Localization Identifier",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_BARCODE, SCSI_ATTR_FLAG_NONE,
+ "Barcode",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_HOST_OWNER_NAME, SCSI_ATTR_FLAG_NONE,
+ "Owning Host Textual Name",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_text_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MEDIA_POOL, SCSI_ATTR_FLAG_NONE,
+ "Media Pool",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_text_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_PART_USER_LABEL, SCSI_ATTR_FLAG_NONE,
+ "Partition User Text Label",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_LOAD_UNLOAD_AT_PART, SCSI_ATTR_FLAG_NONE,
+ "Load/Unload at Partition",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_APP_FORMAT_VERSION, SCSI_ATTR_FLAG_NONE,
+ "Application Format Version",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_VOL_COHERENCY_INFO, SCSI_ATTR_FLAG_NONE,
+ "Volume Coherency Information",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_volcoh_sbuf,
+ /*parse_str*/ NULL },
+ { 0x0ff1, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM Creation",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x0ff2, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM C3",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x0ff3, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM RW",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x0ff4, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM SDC List",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x0ff7, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM Post Scan",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x0ffe, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM Checksum",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x17f1, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM Creation",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x17f2, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM C3",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x17f3, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM RW",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x17f4, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM SDC List",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x17f7, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM Post Scan",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x17ff, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM Checksum",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+};
+
+/*
+ * Print out Volume Coherency Information (Attribute 0x080c).
+ * This field has two variable length members, including one at the
+ * beginning, so it isn't practical to have a fixed structure definition.
+ * This is current as of SSC4r03 (see section 4.2.21.3), dated March 25,
+ * 2013.
+ */
+int
+scsi_attrib_volcoh_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len)
+{
+ size_t avail_len;
+ uint32_t field_size;
+ uint64_t tmp_val;
+ uint8_t *cur_ptr;
+ int retval;
+ int vcr_len, as_len;
+
+ retval = 0;
+ tmp_val = 0;
+
+ field_size = scsi_2btoul(hdr->length);
+ avail_len = valid_len - sizeof(*hdr);
+ if (field_size > avail_len) {
+ if (error_str != NULL) {
+ snprintf(error_str, error_str_len, "Available "
+ "length of attribute ID 0x%.4x %zu < field "
+ "length %u", scsi_2btoul(hdr->id), avail_len,
+ field_size);
+ }
+ retval = 1;
+ goto bailout;
+ } else if (field_size == 0) {
+ /*
+ * It isn't clear from the spec whether a field length of
+ * 0 is invalid here. It probably is, but be lenient here
+ * to avoid inconveniencing the user.
+ */
+ goto bailout;
+ }
+ cur_ptr = hdr->attribute;
+ vcr_len = *cur_ptr;
+ cur_ptr++;
+
+ sbuf_printf(sb, "\n\tVolume Change Reference Value:");
+
+ switch (vcr_len) {
+ case 0:
+ if (error_str != NULL) {
+ snprintf(error_str, error_str_len, "Volume Change "
+ "Reference value has length of 0");
+ }
+ retval = 1;
+ goto bailout;
+ break; /*NOTREACHED*/
+ case 1:
+ tmp_val = *cur_ptr;
+ break;
+ case 2:
+ tmp_val = scsi_2btoul(cur_ptr);
+ break;
+ case 3:
+ tmp_val = scsi_3btoul(cur_ptr);
+ break;
+ case 4:
+ tmp_val = scsi_4btoul(cur_ptr);
+ break;
+ case 8:
+ tmp_val = scsi_8btou64(cur_ptr);
+ break;
+ default:
+ sbuf_printf(sb, "\n");
+ sbuf_hexdump(sb, cur_ptr, vcr_len, NULL, 0);
+ break;
+ }
+ if (vcr_len <= 8)
+ sbuf_printf(sb, " 0x%jx\n", (uintmax_t)tmp_val);
+
+ cur_ptr += vcr_len;
+ tmp_val = scsi_8btou64(cur_ptr);
+ sbuf_printf(sb, "\tVolume Coherency Count: %ju\n", (uintmax_t)tmp_val);
+
+ cur_ptr += sizeof(tmp_val);
+ tmp_val = scsi_8btou64(cur_ptr);
+ sbuf_printf(sb, "\tVolume Coherency Set Identifier: 0x%jx\n",
+ (uintmax_t)tmp_val);
+
+ /*
+ * Figure out how long the Application Client Specific Information
+ * is and produce a hexdump.
+ */
+ cur_ptr += sizeof(tmp_val);
+ as_len = scsi_2btoul(cur_ptr);
+ cur_ptr += sizeof(uint16_t);
+ sbuf_printf(sb, "\tApplication Client Specific Information: ");
+ if (((as_len == SCSI_LTFS_VER0_LEN)
+ || (as_len == SCSI_LTFS_VER1_LEN))
+ && (strncmp(cur_ptr, SCSI_LTFS_STR_NAME, SCSI_LTFS_STR_LEN) == 0)) {
+ sbuf_printf(sb, "LTFS\n");
+ cur_ptr += SCSI_LTFS_STR_LEN + 1;
+ if (cur_ptr[SCSI_LTFS_UUID_LEN] != '\0')
+ cur_ptr[SCSI_LTFS_UUID_LEN] = '\0';
+ sbuf_printf(sb, "\tLTFS UUID: %s\n", cur_ptr);
+ cur_ptr += SCSI_LTFS_UUID_LEN + 1;
+ /* XXX KDM check the length */
+ sbuf_printf(sb, "\tLTFS Version: %d\n", *cur_ptr);
+ } else {
+ sbuf_printf(sb, "Unknown\n");
+ sbuf_hexdump(sb, cur_ptr, as_len, NULL, 0);
+ }
+
+bailout:
+ return (retval);
+}
+
+int
+scsi_attrib_vendser_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len)
+{
+ size_t avail_len;
+ uint32_t field_size;
+ struct scsi_attrib_vendser *vendser;
+ cam_strvis_flags strvis_flags;
+ int retval = 0;
+
+ field_size = scsi_2btoul(hdr->length);
+ avail_len = valid_len - sizeof(*hdr);
+ if (field_size > avail_len) {
+ if (error_str != NULL) {
+ snprintf(error_str, error_str_len, "Available "
+ "length of attribute ID 0x%.4x %zu < field "
+ "length %u", scsi_2btoul(hdr->id), avail_len,
+ field_size);
+ }
+ retval = 1;
+ goto bailout;
+ } else if (field_size == 0) {
+ /*
+ * A field size of 0 doesn't make sense here. The device
+ * can at least give you the vendor ID, even if it can't
+ * give you the serial number.
+ */
+ if (error_str != NULL) {
+ snprintf(error_str, error_str_len, "The length of "
+ "attribute ID 0x%.4x is 0",
+ scsi_2btoul(hdr->id));
+ }
+ retval = 1;
+ goto bailout;
+ }
+ vendser = (struct scsi_attrib_vendser *)hdr->attribute;
+
+ switch (output_flags & SCSI_ATTR_OUTPUT_NONASCII_MASK) {
+ case SCSI_ATTR_OUTPUT_NONASCII_TRIM:
+ strvis_flags = CAM_STRVIS_FLAG_NONASCII_TRIM;
+ break;
+ case SCSI_ATTR_OUTPUT_NONASCII_RAW:
+ strvis_flags = CAM_STRVIS_FLAG_NONASCII_RAW;
+ break;
+ case SCSI_ATTR_OUTPUT_NONASCII_ESC:
+ default:
+ strvis_flags = CAM_STRVIS_FLAG_NONASCII_ESC;
+ break;;
+ }
+ cam_strvis_sbuf(sb, vendser->vendor, sizeof(vendser->vendor),
+ strvis_flags);
+ sbuf_putc(sb, ' ');
+ cam_strvis_sbuf(sb, vendser->serial_num, sizeof(vendser->serial_num),
+ strvis_flags);
+bailout:
+ return (retval);
+}
+
+int
+scsi_attrib_hexdump_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len)
+{
+ uint32_t field_size;
+ ssize_t avail_len;
+ uint32_t print_len;
+ uint8_t *num_ptr;
+ int retval = 0;
+
+ field_size = scsi_2btoul(hdr->length);
+ avail_len = valid_len - sizeof(*hdr);
+ print_len = MIN(avail_len, field_size);
+ num_ptr = hdr->attribute;
+
+ if (print_len > 0) {
+ sbuf_printf(sb, "\n");
+ sbuf_hexdump(sb, num_ptr, print_len, NULL, 0);
+ }
+
+ return (retval);
+}
+
+int
+scsi_attrib_int_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len)
+{
+ uint64_t print_number;
+ size_t avail_len;
+ uint32_t number_size;
+ int retval = 0;
+
+ number_size = scsi_2btoul(hdr->length);
+
+ avail_len = valid_len - sizeof(*hdr);
+ if (avail_len < number_size) {
+ if (error_str != NULL) {
+ snprintf(error_str, error_str_len, "Available "
+ "length of attribute ID 0x%.4x %zu < field "
+ "length %u", scsi_2btoul(hdr->id), avail_len,
+ number_size);
+ }
+ retval = 1;
+ goto bailout;
+ }
+
+ switch (number_size) {
+ case 0:
+ /*
+ * We don't treat this as an error, since there may be
+ * scenarios where a device reports a field but then gives
+ * a length of 0. See the note in scsi_attrib_ascii_sbuf().
+ */
+ goto bailout;
+ break; /*NOTREACHED*/
+ case 1:
+ print_number = hdr->attribute[0];
+ break;
+ case 2:
+ print_number = scsi_2btoul(hdr->attribute);
+ break;
+ case 3:
+ print_number = scsi_3btoul(hdr->attribute);
+ break;
+ case 4:
+ print_number = scsi_4btoul(hdr->attribute);
+ break;
+ case 8:
+ print_number = scsi_8btou64(hdr->attribute);
+ break;
+ default:
+ /*
+ * If we wind up here, the number is too big to print
+ * normally, so just do a hexdump.
+ */
+ retval = scsi_attrib_hexdump_sbuf(sb, hdr, valid_len,
+ flags, output_flags,
+ error_str, error_str_len);
+ goto bailout;
+ break;
+ }
+
+ if (flags & SCSI_ATTR_FLAG_FP) {
+#ifndef _KERNEL
+ long double num_float;
+
+ num_float = (long double)print_number;
+
+ if (flags & SCSI_ATTR_FLAG_DIV_10)
+ num_float /= 10;
+
+ sbuf_printf(sb, "%.*Lf", (flags & SCSI_ATTR_FLAG_FP_1DIGIT) ?
+ 1 : 0, num_float);
+#else /* _KERNEL */
+ sbuf_printf(sb, "%ju", (flags & SCSI_ATTR_FLAG_DIV_10) ?
+ (print_number / 10) : print_number);
+#endif /* _KERNEL */
+ } else if (flags & SCSI_ATTR_FLAG_HEX) {
+ sbuf_printf(sb, "0x%jx", (uintmax_t)print_number);
+ } else
+ sbuf_printf(sb, "%ju", (uintmax_t)print_number);
+
+bailout:
+ return (retval);
+}
+
+int
+scsi_attrib_ascii_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len)
+{
+ size_t avail_len;
+ uint32_t field_size, print_size;
+ int retval = 0;
+
+ avail_len = valid_len - sizeof(*hdr);
+ field_size = scsi_2btoul(hdr->length);
+ print_size = MIN(avail_len, field_size);
+
+ if (print_size > 0) {
+ cam_strvis_flags strvis_flags;
+
+ switch (output_flags & SCSI_ATTR_OUTPUT_NONASCII_MASK) {
+ case SCSI_ATTR_OUTPUT_NONASCII_TRIM:
+ strvis_flags = CAM_STRVIS_FLAG_NONASCII_TRIM;
+ break;
+ case SCSI_ATTR_OUTPUT_NONASCII_RAW:
+ strvis_flags = CAM_STRVIS_FLAG_NONASCII_RAW;
+ break;
+ case SCSI_ATTR_OUTPUT_NONASCII_ESC:
+ default:
+ strvis_flags = CAM_STRVIS_FLAG_NONASCII_ESC;
+ break;
+ }
+ cam_strvis_sbuf(sb, hdr->attribute, print_size, strvis_flags);
+ } else if (avail_len < field_size) {
+ /*
+ * We only report an error if the user didn't allocate
+ * enough space to hold the full value of this field. If
+ * the field length is 0, that is allowed by the spec.
+ * e.g. in SPC-4r37, section 7.4.2.2.5, VOLUME IDENTIFIER
+ * "This attribute indicates the current volume identifier
+ * (see SMC-3) of the medium. If the device server supports
+ * this attribute but does not have access to the volume
+ * identifier, the device server shall report this attribute
+ * with an attribute length value of zero."
+ */
+ if (error_str != NULL) {
+ snprintf(error_str, error_str_len, "Available "
+ "length of attribute ID 0x%.4x %zu < field "
+ "length %u", scsi_2btoul(hdr->id), avail_len,
+ field_size);
+ }
+ retval = 1;
+ }
+
+ return (retval);
+}
+
+int
+scsi_attrib_text_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len)
+{
+ size_t avail_len;
+ uint32_t field_size, print_size;
+ int retval = 0;
+ int esc_text = 1;
+
+ avail_len = valid_len - sizeof(*hdr);
+ field_size = scsi_2btoul(hdr->length);
+ print_size = MIN(avail_len, field_size);
+
+ if ((output_flags & SCSI_ATTR_OUTPUT_TEXT_MASK) ==
+ SCSI_ATTR_OUTPUT_TEXT_RAW)
+ esc_text = 0;
+
+ if (print_size > 0) {
+ uint32_t i;
+
+ for (i = 0; i < print_size; i++) {
+ if (hdr->attribute[i] == '\0')
+ continue;
+ else if (((unsigned char)hdr->attribute[i] < 0x80)
+ || (esc_text == 0))
+ sbuf_putc(sb, hdr->attribute[i]);
+ else
+ sbuf_printf(sb, "%%%02x",
+ (unsigned char)hdr->attribute[i]);
+ }
+ } else if (avail_len < field_size) {
+ /*
+ * We only report an error if the user didn't allocate
+ * enough space to hold the full value of this field.
+ */
+ if (error_str != NULL) {
+ snprintf(error_str, error_str_len, "Available "
+ "length of attribute ID 0x%.4x %zu < field "
+ "length %u", scsi_2btoul(hdr->id), avail_len,
+ field_size);
+ }
+ retval = 1;
+ }
+
+ return (retval);
+}
+
+struct scsi_attrib_table_entry *
+scsi_find_attrib_entry(struct scsi_attrib_table_entry *table,
+ size_t num_table_entries, uint32_t id)
+{
+ uint32_t i;
+
+ for (i = 0; i < num_table_entries; i++) {
+ if (table[i].id == id)
+ return (&table[i]);
+ }
+
+ return (NULL);
+}
+
+struct scsi_attrib_table_entry *
+scsi_get_attrib_entry(uint32_t id)
+{
+ return (scsi_find_attrib_entry(scsi_mam_attr_table,
+ sizeof(scsi_mam_attr_table) / sizeof(scsi_mam_attr_table[0]),
+ id));
+}
+
+int
+scsi_attrib_value_sbuf(struct sbuf *sb, uint32_t valid_len,
+ struct scsi_mam_attribute_header *hdr, uint32_t output_flags,
+ char *error_str, size_t error_str_len)
+{
+ int retval;
+
+ switch (hdr->byte2 & SMA_FORMAT_MASK) {
+ case SMA_FORMAT_ASCII:
+ retval = scsi_attrib_ascii_sbuf(sb, hdr, valid_len,
+ SCSI_ATTR_FLAG_NONE, output_flags, error_str,error_str_len);
+ break;
+ case SMA_FORMAT_BINARY:
+ if (scsi_2btoul(hdr->length) <= 8)
+ retval = scsi_attrib_int_sbuf(sb, hdr, valid_len,
+ SCSI_ATTR_FLAG_NONE, output_flags, error_str,
+ error_str_len);
+ else
+ retval = scsi_attrib_hexdump_sbuf(sb, hdr, valid_len,
+ SCSI_ATTR_FLAG_NONE, output_flags, error_str,
+ error_str_len);
+ break;
+ case SMA_FORMAT_TEXT:
+ retval = scsi_attrib_text_sbuf(sb, hdr, valid_len,
+ SCSI_ATTR_FLAG_NONE, output_flags, error_str,
+ error_str_len);
+ break;
+ default:
+ if (error_str != NULL) {
+ snprintf(error_str, error_str_len, "Unknown attribute "
+ "format 0x%x", hdr->byte2 & SMA_FORMAT_MASK);
+ }
+ retval = 1;
+ goto bailout;
+ break; /*NOTREACHED*/
+ }
+
+ sbuf_trim(sb);
+
+bailout:
+
+ return (retval);
+}
+
+void
+scsi_attrib_prefix_sbuf(struct sbuf *sb, uint32_t output_flags,
+ struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, const char *desc)
+{
+ int need_space = 0;
+ uint32_t len;
+ uint32_t id;
+
+ /*
+ * We can't do anything if we don't have enough valid data for the
+ * header.
+ */
+ if (valid_len < sizeof(*hdr))
+ return;
+
+ id = scsi_2btoul(hdr->id);
+ /*
+ * Note that we print out the value of the attribute listed in the
+ * header, regardless of whether we actually got that many bytes
+ * back from the device through the controller. A truncated result
+ * could be the result of a failure to ask for enough data; the
+ * header indicates how many bytes are allocated for this attribute
+ * in the MAM.
+ */
+ len = scsi_2btoul(hdr->length);
+
+ if ((output_flags & SCSI_ATTR_OUTPUT_FIELD_MASK) ==
+ SCSI_ATTR_OUTPUT_FIELD_NONE)
+ return;
+
+ if ((output_flags & SCSI_ATTR_OUTPUT_FIELD_DESC)
+ && (desc != NULL)) {
+ sbuf_printf(sb, "%s", desc);
+ need_space = 1;
+ }
+
+ if (output_flags & SCSI_ATTR_OUTPUT_FIELD_NUM) {
+ sbuf_printf(sb, "%s(0x%.4x)", (need_space) ? " " : "", id);
+ need_space = 0;
+ }
+
+ if (output_flags & SCSI_ATTR_OUTPUT_FIELD_SIZE) {
+ sbuf_printf(sb, "%s[%d]", (need_space) ? " " : "", len);
+ need_space = 0;
+ }
+ if (output_flags & SCSI_ATTR_OUTPUT_FIELD_RW) {
+ sbuf_printf(sb, "%s(%s)", (need_space) ? " " : "",
+ (hdr->byte2 & SMA_READ_ONLY) ? "RO" : "RW");
+ }
+ sbuf_printf(sb, ": ");
+}
+
+int
+scsi_attrib_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, struct scsi_attrib_table_entry *user_table,
+ size_t num_user_entries, int prefer_user_table,
+ uint32_t output_flags, char *error_str, int error_str_len)
+{
+ int retval;
+ struct scsi_attrib_table_entry *table1 = NULL, *table2 = NULL;
+ struct scsi_attrib_table_entry *entry = NULL;
+ size_t table1_size = 0, table2_size = 0;
+ uint32_t id;
+
+ retval = 0;
+
+ if (valid_len < sizeof(*hdr)) {
+ retval = 1;
+ goto bailout;
+ }
+
+ id = scsi_2btoul(hdr->id);
+
+ if (user_table != NULL) {
+ if (prefer_user_table != 0) {
+ table1 = user_table;
+ table1_size = num_user_entries;
+ table2 = scsi_mam_attr_table;
+ table2_size = sizeof(scsi_mam_attr_table) /
+ sizeof(scsi_mam_attr_table[0]);
+ } else {
+ table1 = scsi_mam_attr_table;
+ table1_size = sizeof(scsi_mam_attr_table) /
+ sizeof(scsi_mam_attr_table[0]);
+ table2 = user_table;
+ table2_size = num_user_entries;
+ }
+ } else {
+ table1 = scsi_mam_attr_table;
+ table1_size = sizeof(scsi_mam_attr_table) /
+ sizeof(scsi_mam_attr_table[0]);
+ }
+
+ entry = scsi_find_attrib_entry(table1, table1_size, id);
+ if (entry != NULL) {
+ scsi_attrib_prefix_sbuf(sb, output_flags, hdr, valid_len,
+ entry->desc);
+ if (entry->to_str == NULL)
+ goto print_default;
+ retval = entry->to_str(sb, hdr, valid_len, entry->flags,
+ output_flags, error_str, error_str_len);
+ goto bailout;
+ }
+ if (table2 != NULL) {
+ entry = scsi_find_attrib_entry(table2, table2_size, id);
+ if (entry != NULL) {
+ if (entry->to_str == NULL)
+ goto print_default;
+
+ scsi_attrib_prefix_sbuf(sb, output_flags, hdr,
+ valid_len, entry->desc);
+ retval = entry->to_str(sb, hdr, valid_len, entry->flags,
+ output_flags, error_str,
+ error_str_len);
+ goto bailout;
+ }
+ }
+
+ scsi_attrib_prefix_sbuf(sb, output_flags, hdr, valid_len, NULL);
+
+print_default:
+ retval = scsi_attrib_value_sbuf(sb, valid_len, hdr, output_flags,
+ error_str, error_str_len);
+bailout:
+ if (retval == 0) {
+ if ((entry != NULL)
+ && (entry->suffix != NULL))
+ sbuf_printf(sb, " %s", entry->suffix);
+
+ sbuf_trim(sb);
+ sbuf_printf(sb, "\n");
+ }
+
+ return (retval);
+}
+
void
scsi_test_unit_ready(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
@@ -7403,6 +8227,74 @@ scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
timeout);
}
+void
+scsi_read_attribute(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ u_int8_t tag_action, u_int8_t service_action,
+ uint32_t element, u_int8_t elem_type, int logical_volume,
+ int partition, u_int32_t first_attribute, int cache,
+ u_int8_t *data_ptr, u_int32_t length, int sense_len,
+ u_int32_t timeout)
+{
+ struct scsi_read_attribute *scsi_cmd;
+
+ scsi_cmd = (struct scsi_read_attribute *)&csio->cdb_io.cdb_bytes;
+ bzero(scsi_cmd, sizeof(*scsi_cmd));
+
+ scsi_cmd->opcode = READ_ATTRIBUTE;
+ scsi_cmd->service_action = service_action,
+ scsi_ulto2b(element, scsi_cmd->element);
+ scsi_cmd->elem_type = elem_type;
+ scsi_cmd->logical_volume = logical_volume;
+ scsi_cmd->partition = partition;
+ scsi_ulto2b(first_attribute, scsi_cmd->first_attribute);
+ scsi_ulto4b(length, scsi_cmd->length);
+ if (cache != 0)
+ scsi_cmd->cache |= SRA_CACHE;
+
+ cam_fill_csio(csio,
+ retries,
+ cbfcnp,
+ /*flags*/CAM_DIR_IN,
+ tag_action,
+ /*data_ptr*/data_ptr,
+ /*dxfer_len*/length,
+ sense_len,
+ sizeof(*scsi_cmd),
+ timeout);
+}
+
+void
+scsi_write_attribute(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ u_int8_t tag_action, uint32_t element, int logical_volume,
+ int partition, int wtc, u_int8_t *data_ptr,
+ u_int32_t length, int sense_len, u_int32_t timeout)
+{
+ struct scsi_write_attribute *scsi_cmd;
+
+ scsi_cmd = (struct scsi_write_attribute *)&csio->cdb_io.cdb_bytes;
+ bzero(scsi_cmd, sizeof(*scsi_cmd));
+
+ scsi_cmd->opcode = WRITE_ATTRIBUTE;
+ if (wtc != 0)
+ scsi_cmd->byte2 = SWA_WTC;
+ scsi_ulto3b(element, scsi_cmd->element);
+ scsi_cmd->logical_volume = logical_volume;
+ scsi_cmd->partition = partition;
+ scsi_ulto4b(length, scsi_cmd->length);
+
+ cam_fill_csio(csio,
+ retries,
+ cbfcnp,
+ /*flags*/CAM_DIR_OUT,
+ tag_action,
+ /*data_ptr*/data_ptr,
+ /*dxfer_len*/length,
+ sense_len,
+ sizeof(*scsi_cmd),
+ timeout);
+}
void
scsi_persistent_reserve_in(struct ccb_scsiio *csio, uint32_t retries,
diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h
index f70b094..e446f6c 100644
--- a/sys/cam/scsi/scsi_all.h
+++ b/sys/cam/scsi/scsi_all.h
@@ -996,6 +996,216 @@ struct scsi_write_buffer
u_int8_t control;
};
+struct scsi_read_attribute
+{
+ u_int8_t opcode;
+ u_int8_t service_action;
+#define SRA_SA_ATTR_VALUES 0x00
+#define SRA_SA_ATTR_LIST 0x01
+#define SRA_SA_LOG_VOL_LIST 0x02
+#define SRA_SA_PART_LIST 0x03
+#define SRA_SA_RESTRICTED 0x04
+#define SRA_SA_SUPPORTED_ATTRS 0x05
+#define SRA_SA_MASK 0x1f
+ u_int8_t element[2];
+ u_int8_t elem_type;
+ u_int8_t logical_volume;
+ u_int8_t reserved1;
+ u_int8_t partition;
+ u_int8_t first_attribute[2];
+ u_int8_t length[4];
+ u_int8_t cache;
+#define SRA_CACHE 0x01
+ u_int8_t control;
+};
+
+struct scsi_write_attribute
+{
+ u_int8_t opcode;
+ u_int8_t byte2;
+#define SWA_WTC 0x01
+ u_int8_t element[3];
+ u_int8_t logical_volume;
+ u_int8_t reserved1;
+ u_int8_t partition;
+ u_int8_t reserved2[2];
+ u_int8_t length[4];
+ u_int8_t reserved3;
+ u_int8_t control;
+};
+
+
+struct scsi_read_attribute_values
+{
+ u_int8_t length[4];
+ u_int8_t attribute_0[0];
+};
+
+struct scsi_mam_attribute_header
+{
+ u_int8_t id[2];
+ /*
+ * Attributes obtained from SPC-4r36g (section 7.4.2.2) and
+ * SSC-4r03 (section 4.2.21).
+ */
+#define SMA_ATTR_ID_DEVICE_MIN 0x0000
+
+#define SMA_ATTR_REM_CAP_PARTITION 0x0000
+#define SMA_ATTR_MAX_CAP_PARTITION 0x0001
+#define SMA_ATTR_TAPEALERT_FLAGS 0x0002
+#define SMA_ATTR_LOAD_COUNT 0x0003
+#define SMA_ATTR_MAM_SPACE_REMAINING 0x0004
+
+#define SMA_ATTR_DEV_ASSIGNING_ORG 0x0005
+#define SMA_ATTR_FORMAT_DENSITY_CODE 0x0006
+#define SMA_ATTR_INITIALIZATION_COUNT 0x0007
+#define SMA_ATTR_VOLUME_ID 0x0008
+#define SMA_ATTR_VOLUME_CHANGE_REF 0x0009
+
+#define SMA_ATTR_DEV_SERIAL_LAST_LOAD 0x020a
+#define SMA_ATTR_DEV_SERIAL_LAST_LOAD_1 0x020b
+#define SMA_ATTR_DEV_SERIAL_LAST_LOAD_2 0x020c
+#define SMA_ATTR_DEV_SERIAL_LAST_LOAD_3 0x020d
+
+#define SMA_ATTR_TOTAL_MB_WRITTEN_LT 0x0220
+#define SMA_ATTR_TOTAL_MB_READ_LT 0x0221
+#define SMA_ATTR_TOTAL_MB_WRITTEN_CUR 0x0222
+#define SMA_ATTR_TOTAL_MB_READ_CUR 0x0223
+#define SMA_ATTR_FIRST_ENC_BLOCK 0x0224
+#define SMA_ATTR_NEXT_UNENC_BLOCK 0x0225
+
+#define SMA_ATTR_MEDIUM_USAGE_HIST 0x0340
+#define SMA_ATTR_PART_USAGE_HIST 0x0341
+
+#define SMA_ATTR_ID_DEVICE_MAX 0x03ff
+
+#define SMA_ATTR_ID_MEDIUM_MIN 0x0400
+
+#define SMA_ATTR_MED_MANUF 0x0400
+#define SMA_ATTR_MED_SERIAL 0x0401
+
+#define SMA_ATTR_MED_LENGTH 0x0402
+#define SMA_ATTR_MED_WIDTH 0x0403
+#define SMA_ATTR_MED_ASSIGNING_ORG 0x0404
+#define SMA_ATTR_MED_DENSITY_CODE 0x0405
+
+#define SMA_ATTR_MED_MANUF_DATE 0x0406
+#define SMA_ATTR_MAM_CAPACITY 0x0407
+#define SMA_ATTR_MED_TYPE 0x0408
+#define SMA_ATTR_MED_TYPE_INFO 0x0409
+#define SMA_ATTR_MED_SERIAL_NUM 0x040a
+
+#define SMA_ATTR_ID_MEDIUM_MAX 0x07ff
+
+#define SMA_ATTR_ID_HOST_MIN 0x0800
+
+#define SMA_ATTR_APP_VENDOR 0x0800
+#define SMA_ATTR_APP_NAME 0x0801
+#define SMA_ATTR_APP_VERSION 0x0802
+#define SMA_ATTR_USER_MED_TEXT_LABEL 0x0803
+#define SMA_ATTR_LAST_WRITTEN_TIME 0x0804
+#define SMA_ATTR_TEXT_LOCAL_ID 0x0805
+#define SMA_ATTR_BARCODE 0x0806
+#define SMA_ATTR_HOST_OWNER_NAME 0x0807
+#define SMA_ATTR_MEDIA_POOL 0x0808
+#define SMA_ATTR_PART_USER_LABEL 0x0809
+#define SMA_ATTR_LOAD_UNLOAD_AT_PART 0x080a
+#define SMA_ATTR_APP_FORMAT_VERSION 0x080b
+#define SMA_ATTR_VOL_COHERENCY_INFO 0x080c
+
+#define SMA_ATTR_ID_HOST_MAX 0x0bff
+
+#define SMA_ATTR_VENDOR_DEVICE_MIN 0x0c00
+#define SMA_ATTR_VENDOR_DEVICE_MAX 0x0fff
+#define SMA_ATTR_VENDOR_MEDIUM_MIN 0x1000
+#define SMA_ATTR_VENDOR_MEDIUM_MAX 0x13ff
+#define SMA_ATTR_VENDOR_HOST_MIN 0x1400
+#define SMA_ATTR_VENDOR_HOST_MAX 0x17ff
+ u_int8_t byte2;
+#define SMA_FORMAT_BINARY 0x00
+#define SMA_FORMAT_ASCII 0x01
+#define SMA_FORMAT_TEXT 0x02
+#define SMA_FORMAT_MASK 0x03
+#define SMA_READ_ONLY 0x80
+ u_int8_t length[2];
+ u_int8_t attribute[0];
+};
+
+struct scsi_attrib_list_header {
+ u_int8_t length[4];
+ u_int8_t first_attr_0[0];
+};
+
+struct scsi_attrib_lv_list {
+ u_int8_t length[2];
+ u_int8_t first_lv_number;
+ u_int8_t num_logical_volumes;
+};
+
+struct scsi_attrib_vendser {
+ uint8_t vendor[8];
+ uint8_t serial_num[32];
+};
+
+/*
+ * These values are used to decode the Volume Coherency Information
+ * Attribute (0x080c) for LTFS-format coherency information.
+ * Although the Application Client Specific lengths are different for
+ * Version 0 and Version 1, the data is in fact the same. The length
+ * difference was due to a code bug.
+ */
+#define SCSI_LTFS_VER0_LEN 42
+#define SCSI_LTFS_VER1_LEN 43
+#define SCSI_LTFS_UUID_LEN 36
+#define SCSI_LTFS_STR_NAME "LTFS"
+#define SCSI_LTFS_STR_LEN 4
+
+typedef enum {
+ SCSI_ATTR_FLAG_NONE = 0x00,
+ SCSI_ATTR_FLAG_HEX = 0x01,
+ SCSI_ATTR_FLAG_FP = 0x02,
+ SCSI_ATTR_FLAG_DIV_10 = 0x04,
+ SCSI_ATTR_FLAG_FP_1DIGIT = 0x08
+} scsi_attrib_flags;
+
+typedef enum {
+ SCSI_ATTR_OUTPUT_NONE = 0x00,
+ SCSI_ATTR_OUTPUT_TEXT_MASK = 0x03,
+ SCSI_ATTR_OUTPUT_TEXT_RAW = 0x00,
+ SCSI_ATTR_OUTPUT_TEXT_ESC = 0x01,
+ SCSI_ATTR_OUTPUT_TEXT_RSV1 = 0x02,
+ SCSI_ATTR_OUTPUT_TEXT_RSV2 = 0x03,
+ SCSI_ATTR_OUTPUT_NONASCII_MASK = 0x0c,
+ SCSI_ATTR_OUTPUT_NONASCII_TRIM = 0x00,
+ SCSI_ATTR_OUTPUT_NONASCII_ESC = 0x04,
+ SCSI_ATTR_OUTPUT_NONASCII_RAW = 0x08,
+ SCSI_ATTR_OUTPUT_NONASCII_RSV1 = 0x0c,
+ SCSI_ATTR_OUTPUT_FIELD_MASK = 0xf0,
+ SCSI_ATTR_OUTPUT_FIELD_ALL = 0xf0,
+ SCSI_ATTR_OUTPUT_FIELD_NONE = 0x00,
+ SCSI_ATTR_OUTPUT_FIELD_DESC = 0x10,
+ SCSI_ATTR_OUTPUT_FIELD_NUM = 0x20,
+ SCSI_ATTR_OUTPUT_FIELD_SIZE = 0x40,
+ SCSI_ATTR_OUTPUT_FIELD_RW = 0x80
+} scsi_attrib_output_flags;
+
+struct sbuf;
+
+struct scsi_attrib_table_entry
+{
+ u_int32_t id;
+ u_int32_t flags;
+ const char *desc;
+ const char *suffix;
+ int (*to_str)(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len);
+ int (*parse_str)(char *str, struct scsi_mam_attribute_header *hdr,
+ uint32_t alloc_len, uint32_t flags, char *error_str,
+ int error_str_len);
+};
+
struct scsi_rw_6
{
u_int8_t opcode;
@@ -1750,6 +1960,8 @@ struct ata_pass_16 {
#define READ_16 0x88
#define COMPARE_AND_WRITE 0x89
#define WRITE_16 0x8A
+#define READ_ATTRIBUTE 0x8C
+#define WRITE_ATTRIBUTE 0x8D
#define WRITE_VERIFY_16 0x8E
#define VERIFY_16 0x8F
#define SYNCHRONIZE_CACHE_16 0x91
@@ -3272,8 +3484,6 @@ struct cam_device;
extern const char *scsi_sense_key_text[];
-struct sbuf;
-
__BEGIN_DECLS
void scsi_sense_desc(int sense_key, int asc, int ascq,
struct scsi_inquiry_data *inq_data,
@@ -3465,6 +3675,63 @@ int scsi_parse_transportid(char *transportid_str,
#endif
char *error_str, int error_str_len);
+
+int scsi_attrib_volcoh_sbuf(struct sbuf *sb,
+ struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len);
+
+int scsi_attrib_vendser_sbuf(struct sbuf *sb,
+ struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len);
+
+int scsi_attrib_hexdump_sbuf(struct sbuf *sb,
+ struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len);
+
+int scsi_attrib_int_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len);
+
+int scsi_attrib_ascii_sbuf(struct sbuf *sb,
+ struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len);
+
+int scsi_attrib_text_sbuf(struct sbuf *sb,
+ struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len);
+
+struct scsi_attrib_table_entry *scsi_find_attrib_entry(
+ struct scsi_attrib_table_entry *table,
+ size_t num_table_entries, uint32_t id);
+
+struct scsi_attrib_table_entry *scsi_get_attrib_entry(uint32_t id);
+
+int scsi_attrib_value_sbuf(struct sbuf *sb, uint32_t valid_len,
+ struct scsi_mam_attribute_header *hdr,
+ uint32_t output_flags, char *error_str,
+ size_t error_str_len);
+
+void scsi_attrib_prefix_sbuf(struct sbuf *sb, uint32_t output_flags,
+ struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, const char *desc);
+
+int scsi_attrib_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len,
+ struct scsi_attrib_table_entry *user_table,
+ size_t num_user_entries, int prefer_user_table,
+ uint32_t output_flags, char *error_str, int error_str_len);
+
void scsi_test_unit_ready(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *,
union ccb *),
@@ -3659,6 +3926,18 @@ void scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int start, int load_eject,
int immediate, u_int8_t sense_len, u_int32_t timeout);
+void scsi_read_attribute(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ u_int8_t tag_action, u_int8_t service_action,
+ uint32_t element, u_int8_t elem_type,
+ int logical_volume, int partition,
+ u_int32_t first_attribute, int cache, u_int8_t *data_ptr,
+ u_int32_t length, int sense_len, u_int32_t timeout);
+void scsi_write_attribute(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ u_int8_t tag_action, uint32_t element,
+ int logical_volume, int partition, int wtc, u_int8_t *data_ptr,
+ u_int32_t length, int sense_len, u_int32_t timeout);
void scsi_security_protocol_in(struct ccb_scsiio *csio, uint32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
index 30ca7b9..affda74 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
@@ -1826,7 +1826,7 @@ arc_hdr_destroy(arc_buf_hdr_t *hdr)
if (l2hdr != NULL) {
trim_map_free(l2hdr->b_dev->l2ad_vdev, l2hdr->b_daddr,
- hdr->b_size, 0);
+ l2hdr->b_asize, 0);
list_remove(l2hdr->b_dev->l2ad_buflist, hdr);
arc_buf_l2_cdata_free(hdr);
ARCSTAT_INCR(arcstat_l2_size, -hdr->b_size);
@@ -3868,7 +3868,7 @@ arc_release(arc_buf_t *buf, void *tag)
vdev_space_update(l2hdr->b_dev->l2ad_vdev,
-l2hdr->b_asize, 0, 0);
trim_map_free(l2hdr->b_dev->l2ad_vdev, l2hdr->b_daddr,
- hdr->b_size, 0);
+ l2hdr->b_asize, 0);
kmem_free(l2hdr, sizeof (l2arc_buf_hdr_t));
ARCSTAT_INCR(arcstat_l2_size, -buf_size);
mutex_exit(&l2arc_buflist_mtx);
@@ -4813,7 +4813,7 @@ l2arc_write_done(zio_t *zio)
bytes_dropped += abl2->b_asize;
hdr->b_l2hdr = NULL;
trim_map_free(abl2->b_dev->l2ad_vdev, abl2->b_daddr,
- hdr->b_size, 0);
+ abl2->b_asize, 0);
kmem_free(abl2, sizeof (l2arc_buf_hdr_t));
ARCSTAT_INCR(arcstat_l2_size, -hdr->b_size);
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c
index ea3c688..2b55290 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
*/
@@ -1298,6 +1298,16 @@ dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
dbuf_dirty_record_t *dr, **drp;
ASSERT(txg != 0);
+
+ /*
+ * Due to our use of dn_nlevels below, this can only be called
+ * in open context, unless we are operating on the MOS.
+ * From syncing context, dn_nlevels may be different from the
+ * dn_nlevels used when dbuf was dirtied.
+ */
+ ASSERT(db->db_objset ==
+ dmu_objset_pool(db->db_objset)->dp_meta_objset ||
+ txg != spa_syncing_txg(dmu_objset_spa(db->db_objset)));
ASSERT(db->db_blkid != DMU_BONUS_BLKID);
ASSERT0(db->db_level);
ASSERT(MUTEX_HELD(&db->db_mtx));
@@ -1320,11 +1330,8 @@ dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
ASSERT(db->db.db_size != 0);
- /*
- * Any space we accounted for in dp_dirty_* will be cleaned up by
- * dsl_pool_sync(). This is relatively rare so the discrepancy
- * is not a big deal.
- */
+ dsl_pool_undirty_space(dmu_objset_pool(dn->dn_objset),
+ dr->dr_accounted, txg);
*drp = dr->dr_next;
@@ -1339,7 +1346,7 @@ dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
list_remove(&dr->dr_parent->dt.di.dr_children, dr);
mutex_exit(&dr->dr_parent->dt.di.dr_mtx);
} else if (db->db_blkid == DMU_SPILL_BLKID ||
- db->db_level+1 == dn->dn_nlevels) {
+ db->db_level + 1 == dn->dn_nlevels) {
ASSERT(db->db_blkptr == NULL || db->db_parent == dn->dn_dbuf);
mutex_enter(&dn->dn_mtx);
list_remove(&dn->dn_dirty_records[txg & TXG_MASK], dr);
@@ -1356,11 +1363,6 @@ dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
VERIFY(arc_buf_remove_ref(dr->dt.dl.dr_data, db));
}
- if (db->db_level != 0) {
- mutex_destroy(&dr->dt.di.dr_mtx);
- list_destroy(&dr->dt.di.dr_children);
- }
-
kmem_free(dr, sizeof (dbuf_dirty_record_t));
ASSERT(db->db_dirtycnt > 0);
@@ -2318,7 +2320,7 @@ dbuf_sync_indirect(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
zio = dr->dr_zio;
mutex_enter(&dr->dt.di.dr_mtx);
- dbuf_sync_list(&dr->dt.di.dr_children, tx);
+ dbuf_sync_list(&dr->dt.di.dr_children, db->db_level - 1, tx);
ASSERT(list_head(&dr->dt.di.dr_children) == NULL);
mutex_exit(&dr->dt.di.dr_mtx);
zio_nowait(zio);
@@ -2464,7 +2466,7 @@ dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
}
void
-dbuf_sync_list(list_t *list, dmu_tx_t *tx)
+dbuf_sync_list(list_t *list, int level, dmu_tx_t *tx)
{
dbuf_dirty_record_t *dr;
@@ -2481,6 +2483,10 @@ dbuf_sync_list(list_t *list, dmu_tx_t *tx)
DMU_META_DNODE_OBJECT);
break;
}
+ if (dr->dr_dbuf->db_blkid != DMU_BONUS_BLKID &&
+ dr->dr_dbuf->db_blkid != DMU_SPILL_BLKID) {
+ VERIFY3U(dr->dr_dbuf->db_level, ==, level);
+ }
list_remove(list, dr);
if (dr->dr_dbuf->db_level > 0)
dbuf_sync_indirect(dr, tx);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
index adee4f8..fd6e800 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
@@ -855,6 +855,10 @@ dmu_send_estimate(dsl_dataset_t *ds, dsl_dataset_t *fromds, uint64_t *sizep)
if (!dsl_dataset_is_snapshot(ds))
return (SET_ERROR(EINVAL));
+ /* fromsnap, if provided, must be a snapshot */
+ if (fromds != NULL && !dsl_dataset_is_snapshot(fromds))
+ return (SET_ERROR(EINVAL));
+
/*
* fromsnap must be an earlier snapshot from the same fs as tosnap,
* or the origin's fs.
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c
index 1f42704..dff9fab 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
*/
#include <sys/dmu.h>
@@ -686,7 +686,7 @@ dmu_tx_hold_free(dmu_tx_t *tx, uint64_t object, uint64_t off, uint64_t len)
uint64_t ibyte = i << shift;
err = dnode_next_offset(dn, 0, &ibyte, 2, 1, 0);
i = ibyte >> shift;
- if (err == ESRCH)
+ if (err == ESRCH || i > end)
break;
if (err) {
tx->tx_err = err;
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
index 938b5d6..a6e0197 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@@ -1492,6 +1492,16 @@ out:
rw_downgrade(&dn->dn_struct_rwlock);
}
+static void
+dnode_dirty_l1(dnode_t *dn, uint64_t l1blkid, dmu_tx_t *tx)
+{
+ dmu_buf_impl_t *db = dbuf_hold_level(dn, 1, l1blkid, FTAG);
+ if (db != NULL) {
+ dmu_buf_will_dirty(&db->db, tx);
+ dbuf_rele(db, FTAG);
+ }
+}
+
void
dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx)
{
@@ -1612,27 +1622,67 @@ dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx)
nblks += 1;
/*
- * Dirty the first and last indirect blocks, as they (and/or their
- * parents) will need to be written out if they were only
- * partially freed. Interior indirect blocks will be themselves freed,
- * by free_children(), so they need not be dirtied. Note that these
- * interior blocks have already been prefetched by dmu_tx_hold_free().
+ * Dirty all the indirect blocks in this range. Note that only
+ * the first and last indirect blocks can actually be written
+ * (if they were partially freed) -- they must be dirtied, even if
+ * they do not exist on disk yet. The interior blocks will
+ * be freed by free_children(), so they will not actually be written.
+ * Even though these interior blocks will not be written, we
+ * dirty them for two reasons:
+ *
+ * - It ensures that the indirect blocks remain in memory until
+ * syncing context. (They have already been prefetched by
+ * dmu_tx_hold_free(), so we don't have to worry about reading
+ * them serially here.)
+ *
+ * - The dirty space accounting will put pressure on the txg sync
+ * mechanism to begin syncing, and to delay transactions if there
+ * is a large amount of freeing. Even though these indirect
+ * blocks will not be written, we could need to write the same
+ * amount of space if we copy the freed BPs into deadlists.
*/
if (dn->dn_nlevels > 1) {
uint64_t first, last;
first = blkid >> epbs;
- if (db = dbuf_hold_level(dn, 1, first, FTAG)) {
- dmu_buf_will_dirty(&db->db, tx);
- dbuf_rele(db, FTAG);
- }
+ dnode_dirty_l1(dn, first, tx);
if (trunc)
last = dn->dn_maxblkid >> epbs;
else
last = (blkid + nblks - 1) >> epbs;
- if (last > first && (db = dbuf_hold_level(dn, 1, last, FTAG))) {
- dmu_buf_will_dirty(&db->db, tx);
- dbuf_rele(db, FTAG);
+ if (last != first)
+ dnode_dirty_l1(dn, last, tx);
+
+ int shift = dn->dn_datablkshift + dn->dn_indblkshift -
+ SPA_BLKPTRSHIFT;
+ for (uint64_t i = first + 1; i < last; i++) {
+ /*
+ * Set i to the blockid of the next non-hole
+ * level-1 indirect block at or after i. Note
+ * that dnode_next_offset() operates in terms of
+ * level-0-equivalent bytes.
+ */
+ uint64_t ibyte = i << shift;
+ int err = dnode_next_offset(dn, DNODE_FIND_HAVELOCK,
+ &ibyte, 2, 1, 0);
+ i = ibyte >> shift;
+ if (i >= last)
+ break;
+
+ /*
+ * Normally we should not see an error, either
+ * from dnode_next_offset() or dbuf_hold_level()
+ * (except for ESRCH from dnode_next_offset).
+ * If there is an i/o error, then when we read
+ * this block in syncing context, it will use
+ * ZIO_FLAG_MUSTSUCCEED, and thus hang/panic according
+ * to the "failmode" property. dnode_next_offset()
+ * doesn't have a flag to indicate MUSTSUCCEED.
+ */
+ if (err != 0)
+ break;
+
+ dnode_dirty_l1(dn, i, tx);
}
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c
index 63bfc94..418d318 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@@ -712,7 +712,7 @@ dnode_sync(dnode_t *dn, dmu_tx_t *tx)
mutex_exit(&dn->dn_mtx);
}
- dbuf_sync_list(list, tx);
+ dbuf_sync_list(list, dn->dn_phys->dn_nlevels - 1, tx);
if (!DMU_OBJECT_IS_SPECIAL(dn->dn_object)) {
ASSERT3P(list_head(list), ==, NULL);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
index 8700f4c..7c89454 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
@@ -2256,6 +2256,8 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
return (error);
ASSERT(spa->spa_root_vdev == rvd);
+ ASSERT3U(spa->spa_min_ashift, >=, SPA_MINBLOCKSHIFT);
+ ASSERT3U(spa->spa_max_ashift, <=, SPA_MAXBLOCKSHIFT);
if (type != SPA_IMPORT_ASSEMBLE) {
ASSERT(spa_guid(spa) == pool_guid);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c
index d072dc3..994fb1c 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
*/
@@ -719,6 +719,9 @@ spa_add(const char *name, nvlist_t *config, const char *altroot)
spa->spa_debug = ((zfs_flags & ZFS_DEBUG_SPA) != 0);
+ spa->spa_min_ashift = INT_MAX;
+ spa->spa_max_ashift = 0;
+
/*
* As a pool is being created, treat all features as disabled by
* setting SPA_FEATURE_DISABLED for all entries in the feature
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dbuf.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dbuf.h
index 8be8ed6b..319406a 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dbuf.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dbuf.h
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
*/
@@ -287,7 +287,7 @@ void dbuf_evict(dmu_buf_impl_t *db);
void dbuf_setdirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
void dbuf_unoverride(dbuf_dirty_record_t *dr);
-void dbuf_sync_list(list_t *list, dmu_tx_t *tx);
+void dbuf_sync_list(list_t *list, int level, dmu_tx_t *tx);
void dbuf_release_bp(dmu_buf_impl_t *db);
void dbuf_free_range(struct dnode *dn, uint64_t start, uint64_t end,
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h
index d1737e1..c656013 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
*/
@@ -147,6 +147,8 @@ struct spa {
objset_t *spa_meta_objset; /* copy of dp->dp_meta_objset */
txg_list_t spa_vdev_txg_list; /* per-txg dirty vdev list */
vdev_t *spa_root_vdev; /* top-level vdev container */
+ int spa_min_ashift; /* of vdevs in normal class */
+ int spa_max_ashift; /* of vdevs in normal class */
uint64_t spa_config_guid; /* config pool guid */
uint64_t spa_load_guid; /* spa_load initialized guid */
uint64_t spa_last_synced_guid; /* last synced guid */
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h
index e7515d5..c14ac21 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
*/
#ifndef _SYS_VDEV_IMPL_H
@@ -225,7 +225,7 @@ struct vdev {
boolean_t vdev_isl2cache; /* was a l2cache device */
vdev_queue_t vdev_queue; /* I/O deadline schedule queue */
vdev_cache_t vdev_cache; /* physical block cache */
- spa_aux_vdev_t *vdev_aux; /* for l2cache vdevs */
+ spa_aux_vdev_t *vdev_aux; /* for l2cache and spares vdevs */
zio_t *vdev_probe_zio; /* root of current probe */
vdev_aux_t vdev_label_aux; /* on-disk aux state */
struct trim_map *vdev_trimmap; /* map on outstanding trims */
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
index a3ec38e..c434f0c 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
@@ -21,8 +21,8 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
* Copyright 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
*/
@@ -278,8 +278,9 @@ vdev_add_child(vdev_t *pvd, vdev_t *cvd)
size_t oldsize, newsize;
uint64_t id = cvd->vdev_id;
vdev_t **newchild;
+ spa_t *spa = cvd->vdev_spa;
- ASSERT(spa_config_held(cvd->vdev_spa, SCL_ALL, RW_WRITER) == SCL_ALL);
+ ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL);
ASSERT(cvd->vdev_parent == NULL);
cvd->vdev_parent = pvd;
@@ -1398,6 +1399,17 @@ vdev_open(vdev_t *vd)
}
/*
+ * Track the min and max ashift values for normal data devices.
+ */
+ if (vd->vdev_top == vd && vd->vdev_ashift != 0 &&
+ !vd->vdev_islog && vd->vdev_aux == NULL) {
+ if (vd->vdev_ashift > spa->spa_max_ashift)
+ spa->spa_max_ashift = vd->vdev_ashift;
+ if (vd->vdev_ashift < spa->spa_min_ashift)
+ spa->spa_min_ashift = vd->vdev_ashift;
+ }
+
+ /*
* If a leaf vdev has a DTL, and seems healthy, then kick off a
* resilver. But don't do this if we are doing a reopen for a scrub,
* since this would just restart the scrub we are already doing.
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
index 5800db0..e3b6581 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
@@ -25,12 +25,11 @@
* All rights reserved.
* Copyright 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
* Copyright 2014 Xin Li <delphij@FreeBSD.org>. All rights reserved.
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2014, Joyent, Inc. All rights reserved.
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
* Copyright (c) 2013 Steven Hartland. All rights reserved.
- * Copyright (c) 2014, Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -5240,6 +5239,7 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc)
static int
zfs_ioc_hold(const char *pool, nvlist_t *args, nvlist_t *errlist)
{
+ nvpair_t *pair;
nvlist_t *holds;
int cleanup_fd = -1;
int error;
@@ -5249,6 +5249,19 @@ zfs_ioc_hold(const char *pool, nvlist_t *args, nvlist_t *errlist)
if (error != 0)
return (SET_ERROR(EINVAL));
+ /* make sure the user didn't pass us any invalid (empty) tags */
+ for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL;
+ pair = nvlist_next_nvpair(holds, pair)) {
+ char *htag;
+
+ error = nvpair_value_string(pair, &htag);
+ if (error != 0)
+ return (SET_ERROR(error));
+
+ if (strlen(htag) == 0)
+ return (SET_ERROR(EINVAL));
+ }
+
if (nvlist_lookup_int32(args, "cleanup_fd", &cleanup_fd) == 0) {
error = zfs_onexit_fd_hold(cleanup_fd, &minor);
if (error != 0)
@@ -5362,11 +5375,19 @@ zfs_ioc_space_snaps(const char *lastsnap, nvlist_t *innvl, nvlist_t *outnvl)
return (error);
error = dsl_dataset_hold(dp, lastsnap, FTAG, &new);
+ if (error == 0 && !dsl_dataset_is_snapshot(new)) {
+ dsl_dataset_rele(new, FTAG);
+ error = SET_ERROR(EINVAL);
+ }
if (error != 0) {
dsl_pool_rele(dp, FTAG);
return (error);
}
error = dsl_dataset_hold(dp, firstsnap, FTAG, &old);
+ if (error == 0 && !dsl_dataset_is_snapshot(old)) {
+ dsl_dataset_rele(old, FTAG);
+ error = SET_ERROR(EINVAL);
+ }
if (error != 0) {
dsl_dataset_rele(new, FTAG);
dsl_pool_rele(dp, FTAG);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
index 5bd6725..1038a87 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
@@ -5734,8 +5734,6 @@ zfs_getpages(struct vnode *vp, vm_page_t *m, int count, int reqpage)
object = mreq->object;
error = 0;
- KASSERT(vp->v_object == object, ("mismatching object"));
-
if (pcount > 1 && zp->z_blksz > PAGESIZE) {
startoff = rounddown(IDX_TO_OFF(mreq->pindex), zp->z_blksz);
reqstart = OFF_TO_IDX(round_page(startoff));
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
index e3b314f..3d30082 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
@@ -1797,7 +1797,6 @@ log:
void
zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
{
- zfsvfs_t zfsvfs;
uint64_t moid, obj, sa_obj, version;
uint64_t sense = ZFS_CASE_SENSITIVE;
uint64_t norm = 0;
@@ -1805,6 +1804,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
int error;
int i;
znode_t *rootzp = NULL;
+ zfsvfs_t *zfsvfs;
vattr_t vattr;
znode_t *zp;
zfs_acl_ids_t acl_ids;
@@ -1880,7 +1880,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
vattr.va_uid = crgetuid(cr);
vattr.va_gid = crgetgid(cr);
- bzero(&zfsvfs, sizeof (zfsvfs_t));
+ zfsvfs = kmem_zalloc(sizeof (zfsvfs_t), KM_SLEEP);
rootzp = kmem_cache_alloc(znode_cache, KM_SLEEP);
ASSERT(!POINTER_IS_VALID(rootzp->z_zfsvfs));
@@ -1889,15 +1889,15 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
rootzp->z_atime_dirty = 0;
rootzp->z_is_sa = USE_SA(version, os);
- zfsvfs.z_os = os;
- zfsvfs.z_parent = &zfsvfs;
- zfsvfs.z_version = version;
- zfsvfs.z_use_fuids = USE_FUIDS(version, os);
- zfsvfs.z_use_sa = USE_SA(version, os);
- zfsvfs.z_norm = norm;
+ zfsvfs->z_os = os;
+ zfsvfs->z_parent = zfsvfs;
+ zfsvfs->z_version = version;
+ zfsvfs->z_use_fuids = USE_FUIDS(version, os);
+ zfsvfs->z_use_sa = USE_SA(version, os);
+ zfsvfs->z_norm = norm;
error = sa_setup(os, sa_obj, zfs_attr_table, ZPL_END,
- &zfsvfs.z_attr_table);
+ &zfsvfs->z_attr_table);
ASSERT(error == 0);
@@ -1906,16 +1906,16 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
* insensitive.
*/
if (sense == ZFS_CASE_INSENSITIVE || sense == ZFS_CASE_MIXED)
- zfsvfs.z_norm |= U8_TEXTPREP_TOUPPER;
+ zfsvfs->z_norm |= U8_TEXTPREP_TOUPPER;
- mutex_init(&zfsvfs.z_znodes_lock, NULL, MUTEX_DEFAULT, NULL);
- list_create(&zfsvfs.z_all_znodes, sizeof (znode_t),
+ mutex_init(&zfsvfs->z_znodes_lock, NULL, MUTEX_DEFAULT, NULL);
+ list_create(&zfsvfs->z_all_znodes, sizeof (znode_t),
offsetof(znode_t, z_link_node));
for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
- mutex_init(&zfsvfs.z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&zfsvfs->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL);
- rootzp->z_zfsvfs = &zfsvfs;
+ rootzp->z_zfsvfs = zfsvfs;
VERIFY(0 == zfs_acl_ids_create(rootzp, IS_ROOT_NODE, &vattr,
cr, NULL, &acl_ids));
zfs_mknode(rootzp, &vattr, tx, cr, IS_ROOT_NODE, &zp, &acl_ids);
@@ -1932,12 +1932,13 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
* Create shares directory
*/
- error = zfs_create_share_dir(&zfsvfs, tx);
+ error = zfs_create_share_dir(zfsvfs, tx);
ASSERT(error == 0);
for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
- mutex_destroy(&zfsvfs.z_hold_mtx[i]);
+ mutex_destroy(&zfsvfs->z_hold_mtx[i]);
+ kmem_free(zfsvfs, sizeof (zfsvfs_t));
}
#endif /* _KERNEL */
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
index afda3e4..ae4d00c 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
* Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
*/
@@ -1264,19 +1264,23 @@ zio_write_bp_init(zio_t *zio)
return (ZIO_PIPELINE_CONTINUE);
} else {
/*
- * Round up compressed size to MINBLOCKSIZE and
- * zero the tail.
+ * Round up compressed size up to the ashift
+ * of the smallest-ashift device, and zero the tail.
+ * This ensures that the compressed size of the BP
+ * (and thus compressratio property) are correct,
+ * in that we charge for the padding used to fill out
+ * the last sector.
*/
- size_t rounded =
- P2ROUNDUP(psize, (size_t)SPA_MINBLOCKSIZE);
- if (rounded > psize) {
- bzero((char *)cbuf + psize, rounded - psize);
- psize = rounded;
- }
- if (psize == lsize) {
+ ASSERT3U(spa->spa_min_ashift, >=, SPA_MINBLOCKSHIFT);
+ size_t rounded = (size_t)P2ROUNDUP(psize,
+ 1ULL << spa->spa_min_ashift);
+ if (rounded >= lsize) {
compress = ZIO_COMPRESS_OFF;
zio_buf_free(cbuf, lsize);
+ psize = lsize;
} else {
+ bzero((char *)cbuf + psize, rounded - psize);
+ psize = rounded;
zio_push_transform(zio, cbuf,
psize, lsize, NULL);
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/sysmacros.h b/sys/cddl/contrib/opensolaris/uts/common/sys/sysmacros.h
index 3003514..aa84f36 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/sysmacros.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/sysmacros.h
@@ -32,6 +32,9 @@
#include <sys/param.h>
#include <sys/isa_defs.h>
+#if defined(__FreeBSD__) && defined(_KERNEL)
+#include <sys/libkern.h>
+#endif
#ifdef __cplusplus
extern "C" {
@@ -382,6 +385,9 @@ extern unsigned char bcd_to_byte[256];
static __inline int
highbit(ulong_t i)
{
+#if defined(__FreeBSD__) && defined(_KERNEL) && defined(HAVE_INLINE_FLSL)
+ return (flsl(i));
+#else
register int h = 1;
if (i == 0)
@@ -407,6 +413,7 @@ highbit(ulong_t i)
h += 1;
}
return (h);
+#endif
}
/*
@@ -416,6 +423,9 @@ highbit(ulong_t i)
static __inline int
highbit64(uint64_t i)
{
+#if defined(__FreeBSD__) && defined(_KERNEL) && defined(HAVE_INLINE_FLSLL)
+ return (flsll(i));
+#else
int h = 1;
if (i == 0)
@@ -439,6 +449,7 @@ highbit64(uint64_t i)
h += 1;
}
return (h);
+#endif
}
#ifdef __cplusplus
diff --git a/sys/cddl/dev/dtrace/arm/dtrace_asm.S b/sys/cddl/dev/dtrace/arm/dtrace_asm.S
index 06e91d2..fd0ce6c 100644
--- a/sys/cddl/dev/dtrace/arm/dtrace_asm.S
+++ b/sys/cddl/dev/dtrace/arm/dtrace_asm.S
@@ -28,7 +28,6 @@
#define _ASM
#define _LOCORE
-#define LOCORE
#include <sys/cpuvar_defs.h>
#include <sys/dtrace.h>
diff --git a/sys/compat/linux/linux_event.c b/sys/compat/linux/linux_event.c
index 4031588..fcb5753 100644
--- a/sys/compat/linux/linux_event.c
+++ b/sys/compat/linux/linux_event.c
@@ -260,6 +260,8 @@ epoll_to_kevent(struct thread *td, struct file *epfp,
*kev_flags |= EV_CLEAR;
if ((levents & LINUX_EPOLLERR) != 0)
*kev_flags |= EV_ERROR;
+ if ((levents & LINUX_EPOLLRDHUP) != 0)
+ *kev_flags |= EV_EOF;
/* flags related to what event is registered */
if ((levents & LINUX_EPOLL_EVRD) != 0) {
@@ -309,6 +311,8 @@ kevent_to_epoll(struct kevent *kevent, struct epoll_event *l_event)
switch (kevent->filter) {
case EVFILT_READ:
l_event->events = LINUX_EPOLLIN|LINUX_EPOLLRDNORM|LINUX_EPOLLPRI;
+ if ((kevent->flags & EV_EOF) != 0)
+ l_event->events |= LINUX_EPOLLRDHUP;
break;
case EVFILT_WRITE:
l_event->events = LINUX_EPOLLOUT|LINUX_EPOLLWRNORM;
diff --git a/sys/compat/linux/linux_event.h b/sys/compat/linux/linux_event.h
index 0c030ad..9b7d37b 100644
--- a/sys/compat/linux/linux_event.h
+++ b/sys/compat/linux/linux_event.h
@@ -49,7 +49,7 @@
|LINUX_EPOLLHUP|LINUX_EPOLLERR|LINUX_EPOLLPRI)
#define LINUX_EPOLL_EVWR (LINUX_EPOLLOUT|LINUX_EPOLLWRNORM)
#define LINUX_EPOLL_EVSUP (LINUX_EPOLLET|LINUX_EPOLLONESHOT \
- |LINUX_EPOLL_EVRD|LINUX_EPOLL_EVWR)
+ |LINUX_EPOLL_EVRD|LINUX_EPOLL_EVWR|LINUX_EPOLLRDHUP)
#define LINUX_EPOLL_CTL_ADD 1
#define LINUX_EPOLL_CTL_DEL 2
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c
index 9251a20..1e5e37a 100644
--- a/sys/compat/linux/linux_file.c
+++ b/sys/compat/linux/linux_file.c
@@ -348,8 +348,7 @@ getdents_common(struct thread *td, struct linux_getdents64_args *args,
} else
justone = 0;
- error = getvnode(td->td_proc->p_fd, args->fd,
- cap_rights_init(&rights, CAP_READ), &fp);
+ error = getvnode(td, args->fd, cap_rights_init(&rights, CAP_READ), &fp);
if (error != 0)
return (error);
diff --git a/sys/compat/linux/linux_fork.c b/sys/compat/linux/linux_fork.c
index 0fd47fd..394c26f 100644
--- a/sys/compat/linux/linux_fork.c
+++ b/sys/compat/linux/linux_fork.c
@@ -298,7 +298,7 @@ linux_clone_thread(struct thread *td, struct linux_clone_args *args)
__rangeof(struct thread, td_startcopy, td_endcopy));
newtd->td_proc = p;
- newtd->td_ucred = crhold(td->td_ucred);
+ thread_cow_get(newtd, td);
/* create the emuldata */
linux_proc_init(td, newtd, args->flags);
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 65d27ba..fa5feaf 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -383,7 +383,7 @@ linux_uselib(struct thread *td, struct linux_uselib_args *args)
*/
PROC_LOCK(td->td_proc);
if (a_out->a_text > maxtsiz ||
- a_out->a_data + bss_size > lim_cur(td->td_proc, RLIMIT_DATA) ||
+ a_out->a_data + bss_size > lim_cur_proc(td->td_proc, RLIMIT_DATA) ||
racct_set(td->td_proc, RACCT_DATA, a_out->a_data +
bss_size) != 0) {
PROC_UNLOCK(td->td_proc);
@@ -1420,7 +1420,6 @@ int
linux_old_getrlimit(struct thread *td, struct linux_old_getrlimit_args *args)
{
struct l_rlimit rlim;
- struct proc *p = td->td_proc;
struct rlimit bsd_rlim;
u_int which;
@@ -1437,9 +1436,7 @@ linux_old_getrlimit(struct thread *td, struct linux_old_getrlimit_args *args)
if (which == -1)
return (EINVAL);
- PROC_LOCK(p);
- lim_rlimit(p, which, &bsd_rlim);
- PROC_UNLOCK(p);
+ lim_rlimit(td, which, &bsd_rlim);
#ifdef COMPAT_LINUX32
rlim.rlim_cur = (unsigned int)bsd_rlim.rlim_cur;
@@ -1464,7 +1461,6 @@ int
linux_getrlimit(struct thread *td, struct linux_getrlimit_args *args)
{
struct l_rlimit rlim;
- struct proc *p = td->td_proc;
struct rlimit bsd_rlim;
u_int which;
@@ -1481,9 +1477,7 @@ linux_getrlimit(struct thread *td, struct linux_getrlimit_args *args)
if (which == -1)
return (EINVAL);
- PROC_LOCK(p);
- lim_rlimit(p, which, &bsd_rlim);
- PROC_UNLOCK(p);
+ lim_rlimit(td, which, &bsd_rlim);
rlim.rlim_cur = (l_ulong)bsd_rlim.rlim_cur;
rlim.rlim_max = (l_ulong)bsd_rlim.rlim_max;
@@ -2204,7 +2198,7 @@ linux_prlimit64(struct thread *td, struct linux_prlimit64_args *args)
if (args->old != NULL) {
PROC_LOCK(p);
- lim_rlimit(p, which, &rlim);
+ lim_rlimit_proc(p, which, &rlim);
PROC_UNLOCK(p);
if (rlim.rlim_cur == RLIM_INFINITY)
lrlim.rlim_cur = LINUX_RLIM_INFINITY;
diff --git a/sys/compat/svr4/imgact_svr4.c b/sys/compat/svr4/imgact_svr4.c
index f3bb09e..e61b49b 100644
--- a/sys/compat/svr4/imgact_svr4.c
+++ b/sys/compat/svr4/imgact_svr4.c
@@ -109,7 +109,7 @@ exec_svr4_imgact(imgp)
*/
PROC_LOCK(imgp->proc);
if (a_out->a_text > maxtsiz ||
- a_out->a_data + bss_size > lim_cur(imgp->proc, RLIMIT_DATA) ||
+ a_out->a_data + bss_size > lim_cur_proc(imgp->proc, RLIMIT_DATA) ||
racct_set(imgp->proc, RACCT_DATA, a_out->a_data + bss_size) != 0) {
PROC_UNLOCK(imgp->proc);
return (ENOMEM);
diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c
index c0da170..ec4504e 100644
--- a/sys/compat/svr4/svr4_misc.c
+++ b/sys/compat/svr4/svr4_misc.c
@@ -262,8 +262,7 @@ svr4_sys_getdents64(td, uap)
DPRINTF(("svr4_sys_getdents64(%d, *, %d)\n",
uap->fd, uap->nbytes));
- error = getvnode(td->td_proc->p_fd, uap->fd,
- cap_rights_init(&rights, CAP_READ), &fp);
+ error = getvnode(td, uap->fd, cap_rights_init(&rights, CAP_READ), &fp);
if (error != 0)
return (error);
@@ -442,8 +441,7 @@ svr4_sys_getdents(td, uap)
if (uap->nbytes < 0)
return (EINVAL);
- error = getvnode(td->td_proc->p_fd, uap->fd,
- cap_rights_init(&rights, CAP_READ), &fp);
+ error = getvnode(td, uap->fd, cap_rights_init(&rights, CAP_READ), &fp);
if (error != 0)
return (error);
@@ -622,7 +620,7 @@ svr4_sys_fchroot(td, uap)
struct thread *td;
struct svr4_sys_fchroot_args *uap;
{
- struct filedesc *fdp = td->td_proc->p_fd;
+ cap_rights_t rights;
struct vnode *vp;
struct file *fp;
int error;
@@ -630,7 +628,7 @@ svr4_sys_fchroot(td, uap)
if ((error = priv_check(td, PRIV_VFS_FCHROOT)) != 0)
return error;
/* XXX: we have the chroot priv... what cap might we need? all? */
- if ((error = getvnode(fdp, uap->fd, 0, &fp)) != 0)
+ if ((error = getvnode(td, uap->fd, cap_rights_init(&rights), &fp)) != 0)
return error;
vp = fp->f_vnode;
VREF(vp);
@@ -910,9 +908,7 @@ svr4_sys_ulimit(td, uap)
switch (uap->cmd) {
case SVR4_GFILLIM:
- PROC_LOCK(td->td_proc);
- *retval = lim_cur(td->td_proc, RLIMIT_FSIZE) / 512;
- PROC_UNLOCK(td->td_proc);
+ *retval = lim_cur(td, RLIMIT_FSIZE) / 512;
if (*retval == -1)
*retval = 0x7fffffff;
return 0;
@@ -922,17 +918,13 @@ svr4_sys_ulimit(td, uap)
struct rlimit krl;
krl.rlim_cur = uap->newlimit * 512;
- PROC_LOCK(td->td_proc);
- krl.rlim_max = lim_max(td->td_proc, RLIMIT_FSIZE);
- PROC_UNLOCK(td->td_proc);
+ krl.rlim_max = lim_max(td, RLIMIT_FSIZE);
error = kern_setrlimit(td, RLIMIT_FSIZE, &krl);
if (error)
return error;
- PROC_LOCK(td->td_proc);
- *retval = lim_cur(td->td_proc, RLIMIT_FSIZE);
- PROC_UNLOCK(td->td_proc);
+ *retval = lim_cur(td, RLIMIT_FSIZE);
if (*retval == -1)
*retval = 0x7fffffff;
return 0;
@@ -943,9 +935,7 @@ svr4_sys_ulimit(td, uap)
struct vmspace *vm = td->td_proc->p_vmspace;
register_t r;
- PROC_LOCK(td->td_proc);
- r = lim_cur(td->td_proc, RLIMIT_DATA);
- PROC_UNLOCK(td->td_proc);
+ r = lim_cur(td, RLIMIT_DATA);
if (r == -1)
r = 0x7fffffff;
@@ -957,9 +947,7 @@ svr4_sys_ulimit(td, uap)
}
case SVR4_GDESLIM:
- PROC_LOCK(td->td_proc);
- *retval = lim_cur(td->td_proc, RLIMIT_NOFILE);
- PROC_UNLOCK(td->td_proc);
+ *retval = lim_cur(td, RLIMIT_NOFILE);
if (*retval == -1)
*retval = 0x7fffffff;
return 0;
diff --git a/sys/compat/svr4/svr4_resource.c b/sys/compat/svr4/svr4_resource.c
index efa0bcf..667ee88 100644
--- a/sys/compat/svr4/svr4_resource.c
+++ b/sys/compat/svr4/svr4_resource.c
@@ -130,9 +130,7 @@ svr4_sys_getrlimit(td, uap)
if (rl == -1)
return EINVAL;
- PROC_LOCK(td->td_proc);
- lim_rlimit(td->td_proc, rl, &blim);
- PROC_UNLOCK(td->td_proc);
+ lim_rlimit(td, rl, &blim);
/*
* Our infinity, is their maxfiles.
@@ -181,9 +179,7 @@ svr4_sys_setrlimit(td, uap)
if ((error = copyin(uap->rlp, &slim, sizeof(slim))) != 0)
return error;
- PROC_LOCK(td->td_proc);
- lim_rlimit(td->td_proc, rl, &curlim);
- PROC_UNLOCK(td->td_proc);
+ lim_rlimit(td, rl, &curlim);
/*
* if the limit is SVR4_RLIM_INFINITY, then we set it to our
@@ -228,9 +224,7 @@ svr4_sys_getrlimit64(td, uap)
if (rl == -1)
return EINVAL;
- PROC_LOCK(td->td_proc);
- lim_rlimit(td->td_proc, rl, &blim);
- PROC_UNLOCK(td->td_proc);
+ lim_rlimit(td, rl, &blim);
/*
* Our infinity, is their maxfiles.
@@ -279,9 +273,7 @@ svr4_sys_setrlimit64(td, uap)
if ((error = copyin(uap->rlp, &slim, sizeof(slim))) != 0)
return error;
- PROC_LOCK(td->td_proc);
- lim_rlimit(td->td_proc, rl, &curlim);
- PROC_UNLOCK(td->td_proc);
+ lim_rlimit(td, rl, &curlim);
/*
* if the limit is SVR4_RLIM64_INFINITY, then we set it to our
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 90fc66e..554a234 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -2645,6 +2645,8 @@ device usb
device udbp
# USB Fm Radio
device ufm
+# USB temperature meter
+device ugold
# USB LED
device uled
# Human Interface Device (anything with buttons and dials)
diff --git a/sys/conf/files b/sys/conf/files
index aa97dde..65606b0 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -104,11 +104,12 @@ 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 compile-with "${ZFS_C}"
-cddl/compat/opensolaris/kern/opensolaris_cmn_err.c optional zfs compile-with "${ZFS_C}"
-cddl/compat/opensolaris/kern/opensolaris_kmem.c optional zfs compile-with "${ZFS_C}"
-cddl/compat/opensolaris/kern/opensolaris_misc.c optional zfs compile-with "${ZFS_C}"
-cddl/compat/opensolaris/kern/opensolaris_sunddi.c optional zfs compile-with "${ZFS_C}"
+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_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}"
@@ -118,7 +119,6 @@ cddl/compat/opensolaris/kern/opensolaris_lookup.c optional zfs compile-with "$
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_taskq.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}"
@@ -242,6 +242,17 @@ cddl/contrib/opensolaris/uts/common/zmod/trees.c optional zfs compile-with "${
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}"
+# dtrace specific
+cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c optional dtrace compile-with "${DTRACE_C}" \
+ warning "kernel contains CDDL licensed DTRACE"
+cddl/dev/dtmalloc/dtmalloc.c optional dtmalloc | dtraceall compile-with "${CDDL_C}"
+cddl/dev/lockstat/lockstat.c optional dtrace_lockstat | 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/freebsd32/freebsd32_capability.c optional compat_freebsd32
compat/freebsd32/freebsd32_ioctl.c optional compat_freebsd32
compat/freebsd32/freebsd32_misc.c optional compat_freebsd32
@@ -2534,6 +2545,7 @@ dev/usb/serial/usb_serial.c optional ucom | u3g | uark | ubsa | ubser | \
#
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
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index f1a4e97..08fb59b 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -138,7 +138,12 @@ amd64/amd64/uio_machdep.c standard
amd64/amd64/uma_machdep.c standard
amd64/amd64/vm_machdep.c standard
amd64/pci/pci_cfgreg.c optional pci
-cddl/contrib/opensolaris/common/atomic/amd64/opensolaris_atomic.S optional zfs compile-with "${ZFS_S}"
+cddl/contrib/opensolaris/common/atomic/amd64/opensolaris_atomic.S optional zfs | dtrace compile-with "${ZFS_S}"
+cddl/dev/dtrace/amd64/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}"
+cddl/dev/dtrace/amd64/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}"
+cddl/dev/fbt/x86/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}"
+cddl/dev/dtrace/x86/dis_tables.c optional dtrace_fbt | dtraceall compile-with "${DTRACE_C}"
+cddl/dev/dtrace/amd64/instr_size.c optional dtrace_fbt | dtraceall compile-with "${DTRACE_C}"
crypto/aesni/aeskeys_amd64.S optional aesni
crypto/aesni/aesni.c optional aesni
aesni_ghash.o optional aesni \
diff --git a/sys/conf/files.arm b/sys/conf/files.arm
index a406d33..f49f4551 100644
--- a/sys/conf/files.arm
+++ b/sys/conf/files.arm
@@ -78,7 +78,10 @@ board_id.h standard \
compile-with "${AWK} -f $S/arm/conf/genboardid.awk $S/arm/conf/mach-types > board_id.h" \
no-obj no-implicit-rule before-depend \
clean "board_id.h"
-cddl/compat/opensolaris/kern/opensolaris_atomic.c optional zfs compile-with "${ZFS_C}"
+cddl/compat/opensolaris/kern/opensolaris_atomic.c optional zfs | dtrace compile-with "${CDDL_C}"
+cddl/dev/dtrace/arm/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}"
+cddl/dev/dtrace/arm/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}"
+cddl/dev/fbt/arm/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}"
crypto/blowfish/bf_enc.c optional crypto | ipsec
crypto/des/des_enc.c optional crypto | ipsec | netsmb
dev/fb/fb.c optional sc
diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
index 8bdc93a..a32d8d6 100644
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -2,6 +2,9 @@
arm/arm/devmap.c standard
arm/arm/generic_timer.c standard
arm/arm/pmu.c standard
+arm64/acpica/acpi_machdep.c optional acpi
+arm64/acpica/OsdEnvironment.c optional acpi
+arm64/acpica/acpi_wakeup.c optional acpi
arm64/arm64/autoconf.c standard
arm64/arm64/bcopy.c standard
arm64/arm64/bus_machdep.c standard
@@ -20,6 +23,8 @@ arm64/arm64/dump_machdep.c standard
arm64/arm64/elf_machdep.c standard
arm64/arm64/exception.S standard
arm64/arm64/gic.c standard
+arm64/arm64/gic_acpi.c optional acpi
+arm64/arm64/gic_fdt.c optional fdt
arm64/arm64/gic_v3.c standard
arm64/arm64/gic_v3_fdt.c optional fdt
arm64/arm64/identcpu.c standard
@@ -38,12 +43,15 @@ arm64/arm64/swtch.S standard
arm64/arm64/sys_machdep.c standard
arm64/arm64/trap.c standard
arm64/arm64/uio_machdep.c standard
+arm64/arm64/unwind.c optional ddb | kdtrace_hooks
arm64/arm64/vfp.c standard
arm64/arm64/vm_machdep.c standard
+dev/acpica/acpi_if.m optional acpi
dev/fdt/fdt_arm64.c optional fdt
dev/hwpmc/hwpmc_arm64.c optional hwpmc
dev/hwpmc/hwpmc_arm64_md.c optional hwpmc
dev/ofw/ofw_cpu.c optional fdt
+dev/pci/pci_host_generic.c optional pci fdt
dev/psci/psci.c optional psci
dev/psci/psci_arm64.S optional psci
dev/uart/uart_cpu_fdt.c optional uart fdt
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index 928b10d..ebfce072 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -78,7 +78,12 @@ hptrr_lib.o optional hptrr \
compile-with "uudecode < $S/dev/hptrr/i386-elf.hptrr_lib.o.uu" \
no-implicit-rule
#
-cddl/contrib/opensolaris/common/atomic/i386/opensolaris_atomic.S optional zfs compile-with "${ZFS_S}"
+cddl/contrib/opensolaris/common/atomic/i386/opensolaris_atomic.S optional zfs | dtrace compile-with "${ZFS_S}"
+cddl/dev/dtrace/i386/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}"
+cddl/dev/dtrace/i386/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}"
+cddl/dev/fbt/x86/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}"
+cddl/dev/dtrace/x86/dis_tables.c optional dtrace_fbt | dtraceall compile-with "${DTRACE_C}"
+cddl/dev/dtrace/i386/instr_size.c optional dtrace_fbt | dtraceall compile-with "${DTRACE_C}"
compat/linprocfs/linprocfs.c optional linprocfs
compat/linsysfs/linsysfs.c optional linsysfs
compat/linux/linux_event.c optional compat_linux
diff --git a/sys/conf/files.mips b/sys/conf/files.mips
index 4bc6775a1..f476307 100644
--- a/sys/conf/files.mips
+++ b/sys/conf/files.mips
@@ -61,6 +61,8 @@ libkern/flsll.c standard
libkern/memmove.c standard
libkern/cmpdi2.c optional mips | mipsel
libkern/ucmpdi2.c optional mips | mipsel
+libkern/ashldi3.c standard
+libkern/ashrdi3.c standard
# cfe support
dev/cfe/cfe_api.c optional cfe
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc
index 4158f2c..167fa42 100644
--- a/sys/conf/files.powerpc
+++ b/sys/conf/files.powerpc
@@ -15,8 +15,11 @@ font.h optional sc \
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 compile-with "${ZFS_C}"
-cddl/contrib/opensolaris/common/atomic/powerpc64/opensolaris_atomic.S optional zfs powerpc64 compile-with "${ZFS_S}"
+cddl/compat/opensolaris/kern/opensolaris_atomic.c optional zfs powerpc | dtrace powerpc 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
crypto/des/des_enc.c optional crypto | ipsec | netsmb
dev/bm/if_bm.c optional bm powermac
diff --git a/sys/conf/kern.post.mk b/sys/conf/kern.post.mk
index 8f7abaf..28ea453 100644
--- a/sys/conf/kern.post.mk
+++ b/sys/conf/kern.post.mk
@@ -184,11 +184,11 @@ genassym.o: $S/$M/$M/genassym.c
${SYSTEM_OBJS} genassym.o vers.o: opt_global.h
-# We have "special" -I include paths for opensolaris/zfs files in 'depend'.
-CFILES_NOZFS= ${CFILES:N*/opensolaris/*}
-SFILES_NOZFS= ${SFILES:N*/opensolaris/*}
-CFILES_ZFS= ${CFILES:M*/opensolaris/*}
-SFILES_ZFS= ${SFILES:M*/opensolaris/*}
+# We have "special" -I include paths for zfs/dtrace files in 'depend'.
+CFILES_NOCDDL= ${CFILES:N*/cddl/*:N*fs/nfsclient/nfs_clkdtrace*}
+SFILES_NOCDDL= ${SFILES:N*/cddl/*}
+CFILES_CDDL= ${CFILES:M*/cddl/*}
+SFILES_CDDL= ${SFILES:M*/cddl/*}
kernel-depend: .depend
# The argument list can be very long, so use make -V and xargs to
@@ -198,13 +198,13 @@ SRCS= assym.s vnode_if.h ${BEFORE_DEPEND} ${CFILES} \
${MFILES:T:S/.m$/.h/}
.depend: .PRECIOUS ${SRCS}
rm -f .newdep
- ${MAKE} -V CFILES_NOZFS -V SYSTEM_CFILES -V GEN_CFILES | \
+ ${MAKE} -V CFILES_NOCDDL -V SYSTEM_CFILES -V GEN_CFILES | \
MKDEP_CPP="${CC} -E" CC="${CC}" xargs mkdep -a -f .newdep ${CFLAGS}
- ${MAKE} -V CFILES_ZFS | \
- MKDEP_CPP="${CC} -E" CC="${CC}" xargs mkdep -a -f .newdep ${ZFS_CFLAGS}
- ${MAKE} -V SFILES_NOZFS | \
+ ${MAKE} -V CFILES_CDDL | \
+ MKDEP_CPP="${CC} -E" CC="${CC}" xargs mkdep -a -f .newdep ${ZFS_CFLAGS} ${FBT_CFLAGS} ${DTRACE_CFLAGS}
+ ${MAKE} -V SFILES_NOCDDL | \
MKDEP_CPP="${CC} -E" xargs mkdep -a -f .newdep ${ASM_CFLAGS}
- ${MAKE} -V SFILES_ZFS | \
+ ${MAKE} -V SFILES_CDDL | \
MKDEP_CPP="${CC} -E" xargs mkdep -a -f .newdep ${ZFS_ASM_CFLAGS}
rm -f .depend
mv .newdep .depend
diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk
index 8c3b9c6..3081edc 100644
--- a/sys/conf/kern.pre.mk
+++ b/sys/conf/kern.pre.mk
@@ -139,13 +139,34 @@ NORMAL_FW= uudecode -o ${.TARGET} ${.ALLSRC}
NORMAL_FWO= ${LD} -b binary --no-warn-mismatch -d -warn-common -r \
-o ${.TARGET} ${.ALLSRC:M*.fw}
+# Common for dtrace / zfs
+CDDL_CFLAGS= -DFREEBSD_NAMECACHE -nostdinc -I$S/cddl/compat/opensolaris -I$S/cddl/contrib/opensolaris/uts/common -I$S -I$S/cddl/contrib/opensolaris/common ${CFLAGS} -Wno-unknown-pragmas -Wno-missing-prototypes -Wno-undef -Wno-strict-prototypes -Wno-cast-qual -Wno-parentheses -Wno-redundant-decls -Wno-missing-braces -Wno-uninitialized -Wno-unused -Wno-inline -Wno-switch -Wno-pointer-arith -Wno-unknown-pragmas
+CDDL_CFLAGS+= -include $S/cddl/compat/opensolaris/sys/debug_compat.h
+CDDL_C= ${CC} -c ${CDDL_CFLAGS} ${WERROR} ${PROF} ${.IMPSRC}
+
# Special flags for managing the compat compiles for ZFS
-ZFS_CFLAGS= -DFREEBSD_NAMECACHE -DBUILDING_ZFS -nostdinc -I$S/cddl/compat/opensolaris -I$S/cddl/contrib/opensolaris/uts/common/fs/zfs -I$S/cddl/contrib/opensolaris/uts/common/zmod -I$S/cddl/contrib/opensolaris/uts/common -I$S -I$S/cddl/contrib/opensolaris/common/zfs -I$S/cddl/contrib/opensolaris/common ${CFLAGS} -Wno-unknown-pragmas -Wno-missing-prototypes -Wno-undef -Wno-strict-prototypes -Wno-cast-qual -Wno-parentheses -Wno-redundant-decls -Wno-missing-braces -Wno-uninitialized -Wno-unused -Wno-inline -Wno-switch -Wno-pointer-arith -Wno-unknown-pragmas
-ZFS_CFLAGS+= -include $S/cddl/compat/opensolaris/sys/debug_compat.h
+ZFS_CFLAGS= -DBUILDING_ZFS -I$S/cddl/contrib/opensolaris/uts/common/fs/zfs -I$S/cddl/contrib/opensolaris/uts/common/zmod -I$S/cddl/contrib/opensolaris/common/zfs ${CDDL_CFLAGS}
ZFS_ASM_CFLAGS= -x assembler-with-cpp -DLOCORE ${ZFS_CFLAGS}
ZFS_C= ${CC} -c ${ZFS_CFLAGS} ${WERROR} ${PROF} ${.IMPSRC}
ZFS_S= ${CC} -c ${ZFS_ASM_CFLAGS} ${WERROR} ${.IMPSRC}
+# Special flags for managing the compat compiles for DTrace
+DTRACE_CFLAGS= -DBUILDING_DTRACE ${CDDL_CFLAGS} -I$S/cddl/dev/dtrace -I$S/cddl/dev/dtrace/${MACHINE_CPUARCH}
+.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386"
+DTRACE_CFLAGS+= -I$S/cddl/contrib/opensolaris/uts/intel -I$S/cddl/dev/dtrace/x86
+.endif
+DTRACE_CFLAGS+= -I$S/cddl/contrib/opensolaris/common/util -I$S -DDIS_MEM -DSMP
+DTRACE_ASM_CFLAGS= -x assembler-with-cpp -DLOCORE ${DTRACE_CFLAGS}
+DTRACE_C= ${CC} -c ${DTRACE_CFLAGS} ${CDDL_CFLAGS} ${WERROR} ${PROF} ${.IMPSRC}
+DTRACE_S= ${CC} -c ${DTRACE_ASM_CFLAGS} ${CDDL_CFLAGS} ${WERROR} ${.IMPSRC}
+
+# Special flags for managing the compat compiles for DTrace/FBT
+FBT_CFLAGS= -DBUILDING_DTRACE -nostdinc -I$S/cddl/dev/fbt/${MACHINE_CPUARCH} -I$S/cddl/dev/fbt -I$S/cddl/compat/opensolaris -I$S/cddl/contrib/opensolaris/uts/common -I$S ${CDDL_CFLAGS}
+.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386"
+FBT_CFLAGS+= -I$S/cddl/dev/fbt/x86
+.endif
+FBT_C= ${CC} -c ${FBT_CFLAGS} ${CDDL_CFLAGS} ${WERROR} ${PROF} ${.IMPSRC}
+
.if ${MK_CTF} != "no"
NORMAL_CTFCONVERT= ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.elif ${MAKE_VERSION} >= 5201111300
diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk
index 9009745..284fe3f 100644
--- a/sys/conf/kmod.mk
+++ b/sys/conf/kmod.mk
@@ -239,7 +239,7 @@ beforedepend: ${_ILINKS}
# causes all the modules to be rebuilt when the directory pointed to changes.
.for _link in ${_ILINKS}
.if !exists(${.OBJDIR}/${_link})
-${OBJS}: ${.OBJDIR}/${_link}
+${OBJS}: ${_link}
.endif
.endfor
@@ -253,12 +253,10 @@ SYSDIR= ${_dir}
.error "can't find kernel source tree"
.endif
-.for _link in ${_ILINKS}
-.PHONY: ${_link}
-${_link}: ${.OBJDIR}/${_link}
+.NOPATH: ${_ILINKS}
-${.OBJDIR}/${_link}:
- @case ${.TARGET:T} in \
+${_ILINKS}:
+ @case ${.TARGET} in \
machine) \
path=${SYSDIR}/${MACHINE}/include ;; \
*) \
@@ -267,7 +265,6 @@ ${.OBJDIR}/${_link}:
path=`(cd $$path && /bin/pwd)` ; \
${ECHO} ${.TARGET:T} "->" $$path ; \
ln -sf $$path ${.TARGET:T}
-.endfor
CLEANFILES+= ${PROG} ${KMOD}.kld ${OBJS}
diff --git a/sys/contrib/dev/acpica/acpica_prep.sh b/sys/contrib/dev/acpica/acpica_prep.sh
index faf850e..e6bf575 100755
--- a/sys/contrib/dev/acpica/acpica_prep.sh
+++ b/sys/contrib/dev/acpica/acpica_prep.sh
@@ -19,20 +19,20 @@ fulldirs="common compiler components include os_specific"
# files to remove
stripdirs="generate libraries tests tools"
stripfiles="Makefile README accygwin.h acdragonfly.h acdragonflyex.h \
- acefi.h achaiku.h acintel.h aclinux.h aclinuxex.h acmacosx.h \
- acmsvc.h acnetbsd.h acos2.h acwin.h acwin64.h new_table.txt \
- osbsdtbl.c osefitbl.c osefixf.c osfreebsdtbl.c oslinuxtbl.c \
- osunixdir.c osunixmap.c oswindir.c oswintbl.c oswinxf.c \
- readme.txt utclib.c"
+ acefi.h acefiex.h achaiku.h acintel.h aclinux.h aclinuxex.h \
+ acmacosx.h acmsvc.h acnetbsd.h acos2.h acwin.h acwin64.h \
+ new_table.txt osbsdtbl.c osefitbl.c osefixf.c osfreebsdtbl.c \
+ oslinuxtbl.c osunixdir.c osunixmap.c oswindir.c oswintbl.c \
+ oswinxf.c readme.txt utclib.c"
# include files to canonify
-src_headers="acapps.h acbuffer.h accommon.h acconfig.h acdebug.h \
- acdisasm.h acdispat.h acevents.h acexcep.h acglobal.h achware.h \
- acinterp.h aclocal.h acmacros.h acnames.h acnamesp.h acobject.h \
- acopcode.h acoutput.h acparser.h acpi.h acpiosxf.h acpixf.h \
- acpredef.h acresrc.h acrestyp.h acstruct.h actables.h actbl.h \
- actbl1.h actbl2.h actbl3.h actypes.h acutils.h amlcode.h \
- amlresrc.h platform/acenv.h platform/acenvex.h \
+src_headers="acapps.h acbuffer.h acclib.h accommon.h acconfig.h \
+ acdebug.h acdisasm.h acdispat.h acevents.h acexcep.h acglobal.h \
+ achware.h acinterp.h aclocal.h acmacros.h acnames.h acnamesp.h \
+ acobject.h acopcode.h acoutput.h acparser.h acpi.h acpiosxf.h \
+ acpixf.h acpredef.h acresrc.h acrestyp.h acstruct.h actables.h \
+ actbl.h actbl1.h actbl2.h actbl3.h actypes.h acutils.h acuuid.h \
+ amlcode.h amlresrc.h platform/acenv.h platform/acenvex.h \
platform/acfreebsd.h platform/acgcc.h"
comp_headers="aslcompiler.h asldefine.h aslglobal.h aslmessages.h \
aslsupport.l asltypes.h dtcompiler.h dttemplate.h preprocess.h"
diff --git a/sys/contrib/dev/acpica/changes.txt b/sys/contrib/dev/acpica/changes.txt
index 511652f..9abe735 100644
--- a/sys/contrib/dev/acpica/changes.txt
+++ b/sys/contrib/dev/acpica/changes.txt
@@ -1,5 +1,130 @@
----------------------------------------
-08 April 2015. Summary of changes for version 20150515:
+19 June 2015. Summary of changes for version 20150619:
+
+Two regressions in version 20150616 have been addressed:
+
+Fixes some problems/issues with the C library macro removal (ACPI_STRLEN,
+etc.) This update changes ACPICA to only use the standard headers for
+functions, or the prototypes for the local versions of the C library
+functions. Across the source code, this required some additional casts
+for some Clib invocations for portability. Moved all local prototypes to
+a new file, acclib.h
+
+Fixes several problems with recent changes to the handling of the FACS
+table that could cause some systems not to boot.
+
+
+----------------------------------------
+16 June 2015. Summary of changes for version 20150616:
+
+
+1) ACPICA kernel-resident subsystem:
+
+Across the entire ACPICA source code base, the various macros for the C
+library functions (such as ACPI_STRLEN, etc.) have been removed and
+replaced by the standard C library names (strlen, etc.) The original
+purpose for these macros is no longer applicable. This simplification
+reduces the number of macros used in the ACPICA source code
+significantly, improving readability and maintainability.
+
+Implemented support for a new ACPI table, the OSDT. This table, the
+"override" SDT, can be loaded directly by the host OS at boot time. It
+enables the replacement of existing namespace objects that were installed
+via the DSDT and/or SSDTs. The primary purpose for this is to replace
+buggy or incorrect ASL/AML code obtained via the BIOS. The OSDT is slated
+for inclusion in a future version of the ACPI Specification. Lv Zheng/Bob
+Moore.
+
+Added support for systems with (improperly) two FACS tables -- a "32-bit"
+table (via FADT 32-bit legacy field) and a "64-bit" table (via the 64-bit
+X field). This change will support both automatically. There continues to
+be systems found with this issue. This support requires a change to the
+AcpiSetFirmwareWakingVector interface. Also, a public global variable has
+been added to allow the host to select which FACS is desired
+(AcpiGbl_Use32BitFacsAddresses). See the ACPICA reference for more
+details Lv Zheng.
+
+Added a new feature to allow for systems that do not contain an FACS.
+Although this is already supported on hardware-reduced platforms, the
+feature has been extended for all platforms. The reasoning is that we do
+not want to abort the entire ACPICA initialization just because the
+system is seriously buggy and has no FACS.
+
+Fixed a problem where the GUID strings for NFIT tables (in acuuid.h) were
+not correctly transcribed from the ACPI specification in ACPICA version
+20150515.
+
+Implemented support for the _CLS object in the AcpiGetObjectInfo external
+interface.
+
+Updated the definitions of the TCPA and TPM2 ACPI tables to the more
+recent TCG ACPI Specification, December 14, 2014. Table disassembler and
+compiler also updated. Note: The TCPA "server" table is not supported by
+the disassembler/table-compiler at this time.
+
+ACPI 6.0: Added definitions for the new GIC version field in the MADT.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and
+has a much larger code and data size.
+
+ Current Release:
+ Non-Debug Version: 100.6K Code, 27.6K Data, 128.2K Total
+ Debug Version: 196.2K Code, 81.0K Data, 277.2K Total
+ Previous Release:
+ Non-Debug Version: 99.9K Code, 27.5K Data, 127.4K Total
+ Debug Version: 195.2K Code, 80.8K Data, 276.0K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Disassembler: Fixed a problem with the new symbolic operator disassembler
+where incorrect ASL code could be emitted in some cases for the "non-
+commutative" operators -- Subtract, Divide, Modulo, ShiftLeft, and
+ShiftRight. The actual problem cases seem to be rather unusual in common
+ASL code, however. David Box.
+
+Modified the linux version of acpidump to obtain ACPI tables from not
+just /dev/mem (which may not exist) and /sys/firmware/acpi/tables. Lv
+Zheng.
+
+iASL: Fixed a problem where the user preprocessor output file (.i)
+contained extra data that was not expected. The compiler was using this
+file as a temporary file and passed through #line directives in order to
+keep compiler error messages in sync with the input file and line number
+across multiple include files. The (.i) is no longer a temporary file as
+the compiler uses a new, different file for the original purpose.
+
+iASL: Fixed a problem where comments within the original ASL source code
+file were not passed through to the preprocessor output file, nor any
+listing files.
+
+iASL: Fixed some issues for the handling of the "#include" preprocessor
+directive and the similar (but not the same) "Include" ASL operator.
+
+iASL: Add support for the new OSDT in both the disassembler and compiler.
+
+iASL: Fixed a problem with the constant folding support where a Buffer
+object could be incorrectly generated (incorrectly formed) during a
+conversion to a Store() operator.
+
+AcpiHelp: Updated for new NFIT GUIDs, "External" AML opcode, and new
+description text for the _REV predefined name. _REV now permanently
+returns 2, as per the ACPI 6.0 specification.
+
+Debugger: Enhanced the output of the Debug ASL object for references
+produced by the Index operator. For Buffers and strings, only output the
+actual byte pointed to by the index. For packages, only print the single
+package element decoded by the index. Previously, the entire
+buffer/string/package was emitted.
+
+iASL/Table-compiler: Fixed a regression where the "generic" data types
+were no longer recognized, causing errors.
+
+
+----------------------------------------
+15 May 2015. Summary of changes for version 20150515:
This release implements most of ACPI 6.0 as described below.
@@ -34,7 +159,7 @@ iASL disassembler and table compiler: Added ACPI 6.0 changes to existing
tables: FADT, MADT.
iASL preprocessor: Added a new directive to enable inclusion of binary
-blobs into ASL code. The new directive is #includebinary. It takes a
+blobs into ASL code. The new directive is #includebuffer. It takes a
binary file as input and emits a named ascii buffer object into the ASL
code.
diff --git a/sys/contrib/dev/acpica/common/adisasm.c b/sys/contrib/dev/acpica/common/adisasm.c
index 5d0cee2..5942476 100644
--- a/sys/contrib/dev/acpica/common/adisasm.c
+++ b/sys/contrib/dev/acpica/common/adisasm.c
@@ -243,7 +243,7 @@ AdAmlDisassemble (
while (ExternalFileList)
{
ExternalFilename = ExternalFileList->Path;
- if (!ACPI_STRCMP (ExternalFilename, Filename))
+ if (!strcmp (ExternalFilename, Filename))
{
/* Next external file */
diff --git a/sys/contrib/dev/acpica/common/ahids.c b/sys/contrib/dev/acpica/common/ahids.c
index 038d9f6..1af6b41 100644
--- a/sys/contrib/dev/acpica/common/ahids.c
+++ b/sys/contrib/dev/acpica/common/ahids.c
@@ -230,7 +230,7 @@ AcpiAhMatchHardwareId (
for (Info = AslDeviceIds; Info->Name; Info++)
{
- if (!ACPI_STRCMP (HardwareId, Info->Name))
+ if (!strcmp (HardwareId, Info->Name))
{
return (Info);
}
diff --git a/sys/contrib/dev/acpica/common/ahpredef.c b/sys/contrib/dev/acpica/common/ahpredef.c
index 1454880..3026ce3 100644
--- a/sys/contrib/dev/acpica/common/ahpredef.c
+++ b/sys/contrib/dev/acpica/common/ahpredef.c
@@ -249,7 +249,7 @@ const AH_PREDEFINED_NAME AslPredefinedInfo[] =
AH_PREDEF ("_RBW", "Register Bit Width", "Resource Descriptor field"),
AH_PREDEF ("_RDI", "Resource Dependencies for Idle", "Returns a list of dependencies for idle states"),
AH_PREDEF ("_REG", "Region Availability", "Inform AML code of an operation region availability change"),
- AH_PREDEF ("_REV", "Supported ACPI Revision", "Returns the revision of the ACPI specification that is implemented"),
+ AH_PREDEF ("_REV", "Supported Integer Width", "Returns the supported integer width (<= 1: 32 bits only, >=2: both 32 and 64 bits"),
AH_PREDEF ("_RMV", "Removal Status", "Returns a device's removal ability status (docking)"),
AH_PREDEF ("_RNG", "Range", "Memory range type, Resource Descriptor field"),
AH_PREDEF ("_RST", "Device Reset", "Executes a reset on a device"),
diff --git a/sys/contrib/dev/acpica/common/ahuuids.c b/sys/contrib/dev/acpica/common/ahuuids.c
index eeec8b8..46b52eb 100644
--- a/sys/contrib/dev/acpica/common/ahuuids.c
+++ b/sys/contrib/dev/acpica/common/ahuuids.c
@@ -122,7 +122,7 @@ AcpiAhMatchUuid (
AcpiUtConvertStringToUuid (Info->String, UuidBuffer);
- if (!ACPI_MEMCMP (Data, UuidBuffer, UUID_BUFFER_LENGTH))
+ if (!memcmp (Data, UuidBuffer, UUID_BUFFER_LENGTH))
{
return (Info->Description);
}
diff --git a/sys/contrib/dev/acpica/common/dmextern.c b/sys/contrib/dev/acpica/common/dmextern.c
index 2ea54ad..22d54e9 100644
--- a/sys/contrib/dev/acpica/common/dmextern.c
+++ b/sys/contrib/dev/acpica/common/dmextern.c
@@ -224,7 +224,7 @@ AcpiDmNormalizeParentPrefix (
return (NULL);
}
- Length = (ACPI_STRLEN (ParentPath) + ACPI_STRLEN (Path) + 1);
+ Length = (strlen (ParentPath) + strlen (Path) + 1);
if (ParentPath[1])
{
/*
@@ -253,7 +253,7 @@ AcpiDmNormalizeParentPrefix (
*
* Copy the parent path
*/
- ACPI_STRCPY (Fullpath, &ParentPath[Index]);
+ strcpy (Fullpath, &ParentPath[Index]);
/*
* Add dot separator
@@ -261,12 +261,12 @@ AcpiDmNormalizeParentPrefix (
*/
if (ParentPath[1])
{
- ACPI_STRCAT (Fullpath, ".");
+ strcat (Fullpath, ".");
}
/* Copy child path (carat parent prefix(es) were skipped above) */
- ACPI_STRCAT (Fullpath, Path);
+ strcat (Fullpath, Path);
Cleanup:
ACPI_FREE (ParentPath);
@@ -648,13 +648,13 @@ AcpiDmAddNodeToExternalList (
if ((*ExternalPath == AML_ROOT_PREFIX) && (ExternalPath[1]))
{
- Temp = ACPI_ALLOCATE_ZEROED (ACPI_STRLEN (ExternalPath) + 1);
+ Temp = ACPI_ALLOCATE_ZEROED (strlen (ExternalPath) + 1);
if (!Temp)
{
return_VOID;
}
- ACPI_STRCPY (Temp, &ExternalPath[1]);
+ strcpy (Temp, &ExternalPath[1]);
ACPI_FREE (ExternalPath);
ExternalPath = Temp;
}
@@ -806,7 +806,7 @@ AcpiDmCreateNewExternal (
NextExternal = AcpiGbl_ExternalList;
while (NextExternal)
{
- if (!ACPI_STRCMP (ExternalPath, NextExternal->Path))
+ if (!strcmp (ExternalPath, NextExternal->Path))
{
/* Duplicate method, check that the Value (ArgCount) is the same */
@@ -849,7 +849,7 @@ AcpiDmCreateNewExternal (
NewExternal->Value = Value;
NewExternal->Path = ExternalPath;
NewExternal->Type = Type;
- NewExternal->Length = (UINT16) ACPI_STRLEN (ExternalPath);
+ NewExternal->Length = (UINT16) strlen (ExternalPath);
NewExternal->InternalPath = InternalPath;
/* Link the new descriptor into the global list, alphabetically ordered */
diff --git a/sys/contrib/dev/acpica/common/dmrestag.c b/sys/contrib/dev/acpica/common/dmrestag.c
index c457658..4296039 100644
--- a/sys/contrib/dev/acpica/common/dmrestag.c
+++ b/sys/contrib/dev/acpica/common/dmrestag.c
@@ -679,10 +679,10 @@ AcpiGetTagPathname (
* end up in the final compiled AML, it's just an appearance issue for the
* disassembled code.
*/
- Pathname[ACPI_STRLEN (Pathname) - ACPI_NAME_SIZE] = 0;
- ACPI_STRNCAT (Pathname, ResourceNode->Name.Ascii, ACPI_NAME_SIZE);
- ACPI_STRCAT (Pathname, ".");
- ACPI_STRNCAT (Pathname, Tag, ACPI_NAME_SIZE);
+ Pathname[strlen (Pathname) - ACPI_NAME_SIZE] = 0;
+ strncat (Pathname, ResourceNode->Name.Ascii, ACPI_NAME_SIZE);
+ strcat (Pathname, ".");
+ strncat (Pathname, Tag, ACPI_NAME_SIZE);
/* Internalize the namepath to AML format */
diff --git a/sys/contrib/dev/acpica/common/dmtable.c b/sys/contrib/dev/acpica/common/dmtable.c
index 3820c94..0b1f68e 100644
--- a/sys/contrib/dev/acpica/common/dmtable.c
+++ b/sys/contrib/dev/acpica/common/dmtable.c
@@ -528,7 +528,7 @@ AcpiDmDumpDataTable (
TableData = AcpiDmGetTableData (Table->Signature);
if (!TableData)
{
- if (!ACPI_STRNCMP (Table->Signature, "OEM", 3))
+ if (!strncmp (Table->Signature, "OEM", 3))
{
AcpiOsPrintf ("\n**** OEM-defined ACPI table [%4.4s], unknown contents\n\n",
Table->Signature);
@@ -856,7 +856,7 @@ AcpiDmDumpTable (
case ACPI_DMT_STRING:
- ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1;
+ ByteLength = strlen (ACPI_CAST_PTR (char, Target)) + 1;
break;
case ACPI_DMT_GAS:
diff --git a/sys/contrib/dev/acpica/common/dmtbdump.c b/sys/contrib/dev/acpica/common/dmtbdump.c
index 94358e8..67d0f1c 100644
--- a/sys/contrib/dev/acpica/common/dmtbdump.c
+++ b/sys/contrib/dev/acpica/common/dmtbdump.c
@@ -155,7 +155,7 @@ AcpiDmDumpUnicode (
for (i = 0; i < Length; i += 2)
{
- if (!ACPI_IS_PRINT (Buffer[i]))
+ if (!isprint (Buffer[i]))
{
goto DumpRawBuffer;
}
@@ -1701,7 +1701,7 @@ AcpiDmDumpIort (
InfoTable = AcpiDmTableInfoIort1;
Length = ACPI_OFFSET (ACPI_IORT_NAMED_COMPONENT, DeviceName);
String = ACPI_ADD_PTR (char, IortNode, NodeOffset + Length);
- Length += ACPI_STRLEN (String) + 1;
+ Length += strlen (String) + 1;
break;
case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
@@ -3344,7 +3344,7 @@ AcpiDmDumpStao (
while (Offset < Table->Length)
{
Namepath = ACPI_ADD_PTR (char, Table, Offset);
- StringLength = ACPI_STRLEN (Namepath) + 1;
+ StringLength = strlen (Namepath) + 1;
AcpiDmLineHeader (Offset, StringLength, "Namestring");
AcpiOsPrintf ("\"%s\"\n", Namepath);
diff --git a/sys/contrib/dev/acpica/common/dmtbinfo.c b/sys/contrib/dev/acpica/common/dmtbinfo.c
index a803c70..af67d43 100644
--- a/sys/contrib/dev/acpica/common/dmtbinfo.c
+++ b/sys/contrib/dev/acpica/common/dmtbinfo.c
@@ -113,7 +113,7 @@
#define ACPI_SPMI_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SPMI,f)
#define ACPI_SRAT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SRAT,f)
#define ACPI_STAO_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_STAO,f)
-#define ACPI_TCPA_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_TCPA,f)
+#define ACPI_TCPA_CLIENT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_TCPA_CLIENT,f)
#define ACPI_TPM2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_TPM2,f)
#define ACPI_UEFI_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_UEFI,f)
#define ACPI_WAET_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_WAET,f)
@@ -2611,15 +2611,15 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoStaoStr[] =
/*******************************************************************************
*
- * TCPA - Trusted Computing Platform Alliance table
+ * TCPA - Trusted Computing Platform Alliance table (Client)
*
******************************************************************************/
ACPI_DMTABLE_INFO AcpiDmTableInfoTcpa[] =
{
- {ACPI_DMT_UINT16, ACPI_TCPA_OFFSET (Reserved), "Reserved", 0},
- {ACPI_DMT_UINT32, ACPI_TCPA_OFFSET (MaxLogLength), "Max Event Log Length", 0},
- {ACPI_DMT_UINT64, ACPI_TCPA_OFFSET (LogAddress), "Event Log Address", 0},
+ {ACPI_DMT_UINT16, ACPI_TCPA_CLIENT_OFFSET (PlatformClass), "Platform Class", 0},
+ {ACPI_DMT_UINT32, ACPI_TCPA_CLIENT_OFFSET (MinimumLogLength), "Min Event Log Length", 0},
+ {ACPI_DMT_UINT64, ACPI_TCPA_CLIENT_OFFSET (LogAddress), "Event Log Address", 0},
ACPI_DMT_TERMINATOR
};
@@ -2632,7 +2632,8 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoTcpa[] =
ACPI_DMTABLE_INFO AcpiDmTableInfoTpm2[] =
{
- {ACPI_DMT_UINT32, ACPI_TPM2_OFFSET (Flags), "Flags", 0},
+ {ACPI_DMT_UINT16, ACPI_TPM2_OFFSET (PlatformClass), "Platform Class", 0},
+ {ACPI_DMT_UINT16, ACPI_TPM2_OFFSET (Reserved), "Reserved", 0},
{ACPI_DMT_UINT64, ACPI_TPM2_OFFSET (ControlAddress), "Control Address", 0},
{ACPI_DMT_UINT32, ACPI_TPM2_OFFSET (StartMethod), "Start Method", 0},
ACPI_DMT_TERMINATOR
diff --git a/sys/contrib/dev/acpica/common/getopt.c b/sys/contrib/dev/acpica/common/getopt.c
index b93156c..4a199c0 100644
--- a/sys/contrib/dev/acpica/common/getopt.c
+++ b/sys/contrib/dev/acpica/common/getopt.c
@@ -145,7 +145,7 @@ AcpiGetopt(
{
return (ACPI_OPT_END);
}
- else if (ACPI_STRCMP (argv[AcpiGbl_Optind], "--") == 0)
+ else if (strcmp (argv[AcpiGbl_Optind], "--") == 0)
{
AcpiGbl_Optind++;
return (ACPI_OPT_END);
@@ -159,7 +159,7 @@ AcpiGetopt(
/* Make sure that the option is legal */
if (CurrentChar == ':' ||
- (OptsPtr = ACPI_STRCHR (opts, CurrentChar)) == NULL)
+ (OptsPtr = strchr (opts, CurrentChar)) == NULL)
{
ACPI_OPTION_ERROR ("Illegal option: -", CurrentChar);
diff --git a/sys/contrib/dev/acpica/compiler/aslanalyze.c b/sys/contrib/dev/acpica/compiler/aslanalyze.c
index 3c3eee8..e9b6fb2 100644
--- a/sys/contrib/dev/acpica/compiler/aslanalyze.c
+++ b/sys/contrib/dev/acpica/compiler/aslanalyze.c
@@ -67,8 +67,8 @@ AnIsInternalMethod (
ACPI_PARSE_OBJECT *Op)
{
- if ((!ACPI_STRCMP (Op->Asl.ExternalName, "\\_OSI")) ||
- (!ACPI_STRCMP (Op->Asl.ExternalName, "_OSI")))
+ if ((!strcmp (Op->Asl.ExternalName, "\\_OSI")) ||
+ (!strcmp (Op->Asl.ExternalName, "_OSI")))
{
return (TRUE);
}
@@ -94,8 +94,8 @@ AnGetInternalMethodReturnType (
ACPI_PARSE_OBJECT *Op)
{
- if ((!ACPI_STRCMP (Op->Asl.ExternalName, "\\_OSI")) ||
- (!ACPI_STRCMP (Op->Asl.ExternalName, "_OSI")))
+ if ((!strcmp (Op->Asl.ExternalName, "\\_OSI")) ||
+ (!strcmp (Op->Asl.ExternalName, "_OSI")))
{
return (ACPI_BTYPE_STRING);
}
@@ -462,7 +462,7 @@ ApCheckForGpeNameConflict (
/* Verify 3rd/4th chars are a valid hex value */
- GpeNumber = ACPI_STRTOUL (&Name[2], NULL, 16);
+ GpeNumber = strtoul (&Name[2], NULL, 16);
if (GpeNumber == ACPI_UINT32_MAX)
{
return;
diff --git a/sys/contrib/dev/acpica/compiler/aslascii.c b/sys/contrib/dev/acpica/compiler/aslascii.c
index 08e4630..1583dc3 100644
--- a/sys/contrib/dev/acpica/compiler/aslascii.c
+++ b/sys/contrib/dev/acpica/compiler/aslascii.c
@@ -226,7 +226,7 @@ FlCheckForAscii (
/* Ensure character is either printable or a "space" char */
- else if (!ACPI_IS_PRINT (Byte) && !ACPI_IS_SPACE (Byte))
+ else if (!isprint (Byte) && !isspace (Byte))
{
if ((BadBytes < 10) && (DisplayErrors))
{
diff --git a/sys/contrib/dev/acpica/compiler/aslcodegen.c b/sys/contrib/dev/acpica/compiler/aslcodegen.c
index 8dd30f3..a01afb7 100644
--- a/sys/contrib/dev/acpica/compiler/aslcodegen.c
+++ b/sys/contrib/dev/acpica/compiler/aslcodegen.c
@@ -110,7 +110,7 @@ CgGenerateAmlOutput (
DbgPrint (ASL_TREE_OUTPUT,
"%*s Value P_Op A_Op OpLen PByts Len SubLen PSubLen OpPtr"
- " Parent Child Next Flags AcTyp Final Col L\n",
+ " Parent Child Next Flags AcTyp Final Col L# EL# LL# ELL#\n",
76, " ");
CgCloseTable ();
@@ -145,7 +145,7 @@ CgAmlWriteWalk (
"Final parse tree used for AML output:\n");
DbgPrint (ASL_TREE_OUTPUT,
"%*s Value P_Op A_Op OpLen PByts Len SubLen PSubLen OpPtr"
- " Parent Child Next Flags AcTyp Final Col L\n",
+ " Parent Child Next Flags AcTyp Final Col L# EL# LL# ELL#\n",
76, " ");
}
@@ -169,7 +169,7 @@ CgAmlWriteWalk (
DbgPrint (ASL_TREE_OUTPUT,
"%08X %04X %04X %01X %04X %04X %04X %04X "
- "%08X %08X %08X %08X %08X %08X %04X %02d %02d\n",
+ "%08X %08X %08X %08X %08X %08X %04X %02d %02d %02d %02d %02d\n",
/* 1 */ (UINT32) Op->Asl.Value.Integer,
/* 2 */ Op->Asl.ParseOpcode,
/* 3 */ Op->Asl.AmlOpcode,
@@ -186,7 +186,10 @@ CgAmlWriteWalk (
/* 14 */ Op->Asl.AcpiBtype,
/* 15 */ Op->Asl.FinalAmlLength,
/* 16 */ Op->Asl.Column,
- /* 17 */ Op->Asl.LineNumber);
+ /* 17 */ Op->Asl.LineNumber,
+ /* 18 */ Op->Asl.EndLine,
+ /* 19 */ Op->Asl.LogicalLineNumber,
+ /* 20 */ Op->Asl.EndLogicalLine);
/* Generate the AML for this node */
diff --git a/sys/contrib/dev/acpica/compiler/aslcompile.c b/sys/contrib/dev/acpica/compiler/aslcompile.c
index 0b0ca7a..9aaac3b 100644
--- a/sys/contrib/dev/acpica/compiler/aslcompile.c
+++ b/sys/contrib/dev/acpica/compiler/aslcompile.c
@@ -103,6 +103,9 @@ CmDoCompile (
/* Preprocessor */
PrDoPreprocess ();
+ Gbl_CurrentLineNumber = 1;
+ Gbl_LogicalLineNumber = 1;
+
if (Gbl_PreprocessOnly)
{
UtEndEvent (Event);
@@ -112,6 +115,7 @@ CmDoCompile (
}
UtEndEvent (Event);
+
/* Build the parse tree */
Event = UtBeginEvent ("Parse source code and build parse tree");
@@ -708,7 +712,7 @@ CmCleanupAndExit (
/* Close all open files */
/*
- * Take care with the preprocessor file (.i), it might be the same
+ * Take care with the preprocessor file (.pre), it might be the same
* as the "input" file, depending on where the compiler has terminated
* or aborted. Prevent attempt to close the same file twice in
* loop below.
@@ -733,10 +737,9 @@ CmCleanupAndExit (
FlDeleteFile (ASL_FILE_AML_OUTPUT);
}
- /* Delete the preprocessor output file (.i) unless -li flag is set */
+ /* Delete the preprocessor temp file unless full debug was specified */
- if (!Gbl_PreprocessorOutputFlag &&
- Gbl_PreprocessFlag)
+ if (Gbl_PreprocessFlag && !Gbl_KeepPreprocessorTempFile)
{
FlDeleteFile (ASL_FILE_PREPROCESSOR);
}
@@ -752,8 +755,6 @@ CmCleanupAndExit (
* Note: Handles are cleared by FlCloseFile above, so we look at the
* filename instead, to determine if the .SRC file was actually
* created.
- *
- * TBD: SourceOutput should be .TMP, then rename if we want to keep it?
*/
if (!Gbl_SourceOutputFlag)
{
diff --git a/sys/contrib/dev/acpica/compiler/aslcompiler.h b/sys/contrib/dev/acpica/compiler/aslcompiler.h
index 181b36c..f84f988 100644
--- a/sys/contrib/dev/acpica/compiler/aslcompiler.h
+++ b/sys/contrib/dev/acpica/compiler/aslcompiler.h
@@ -1003,7 +1003,7 @@ UtDoConstant (
char *String);
ACPI_STATUS
-UtStrtoul64 (
+stroul64 (
char *String,
UINT32 Base,
UINT64 *RetInteger);
diff --git a/sys/contrib/dev/acpica/compiler/aslcompiler.l b/sys/contrib/dev/acpica/compiler/aslcompiler.l
index 621f5ae..6a3541b 100644
--- a/sys/contrib/dev/acpica/compiler/aslcompiler.l
+++ b/sys/contrib/dev/acpica/compiler/aslcompiler.l
@@ -709,7 +709,7 @@ NamePathTail [.]{NameSeg}
return (PARSEOP_NAMESTRING); }
. { count (1);
- if (ACPI_IS_PRINT (*AslCompilertext))
+ if (isprint ((int) *AslCompilertext))
{
sprintf (MsgBuffer,
"Invalid character (%c), expecting ASL keyword or name",
diff --git a/sys/contrib/dev/acpica/compiler/asldefine.h b/sys/contrib/dev/acpica/compiler/asldefine.h
index 0697276..0b5f614 100644
--- a/sys/contrib/dev/acpica/compiler/asldefine.h
+++ b/sys/contrib/dev/acpica/compiler/asldefine.h
@@ -105,7 +105,8 @@
/* filename suffixes for output files */
-#define FILE_SUFFIX_PREPROCESSOR "i"
+#define FILE_SUFFIX_PREPROC_USER "i "
+#define FILE_SUFFIX_PREPROCESSOR "pre"
#define FILE_SUFFIX_AML_CODE "aml"
#define FILE_SUFFIX_MAP "map"
#define FILE_SUFFIX_LISTING "lst"
@@ -136,6 +137,8 @@
#define ASL_ABORT TRUE
#define ASL_NO_ABORT FALSE
#define ASL_EOF ACPI_UINT32_MAX
+#define ASL_WITHIN_COMMENT (ACPI_UINT32_MAX -1)
+#define ASL_BLANK_LINE (ACPI_UINT32_MAX -1)
/* Listings */
diff --git a/sys/contrib/dev/acpica/compiler/aslerror.c b/sys/contrib/dev/acpica/compiler/aslerror.c
index 9b8928c..870e30b 100644
--- a/sys/contrib/dev/acpica/compiler/aslerror.c
+++ b/sys/contrib/dev/acpica/compiler/aslerror.c
@@ -561,11 +561,11 @@ AslCommonError2 (
/* Keep a copy of the extra message */
- ACPI_STRCPY (MessageBuffer, ExtraMessage);
+ strcpy (MessageBuffer, ExtraMessage);
}
LineBuffer = UtLocalCalloc (strlen (SourceLine) + 1);
- ACPI_STRCPY (LineBuffer, SourceLine);
+ strcpy (LineBuffer, SourceLine);
/* Initialize the error node */
@@ -647,7 +647,7 @@ AslCommonError (
/* Keep a copy of the extra message */
- ACPI_STRCPY (MessageBuffer, ExtraMessage);
+ strcpy (MessageBuffer, ExtraMessage);
}
/* Initialize the error node */
diff --git a/sys/contrib/dev/acpica/compiler/aslfileio.c b/sys/contrib/dev/acpica/compiler/aslfileio.c
index cf726dd..3feb8ea 100644
--- a/sys/contrib/dev/acpica/compiler/aslfileio.c
+++ b/sys/contrib/dev/acpica/compiler/aslfileio.c
@@ -218,6 +218,19 @@ FlWriteFile (
FlFileError (FileId, ASL_MSG_WRITE);
AslAbort ();
}
+
+ if ((FileId == ASL_FILE_PREPROCESSOR) && Gbl_PreprocessorOutputFlag)
+ {
+ /* Duplicate the output to the user preprocessor (.i) file */
+
+ Actual = fwrite ((char *) Buffer, 1, Length,
+ Gbl_Files[ASL_FILE_PREPROCESSOR_USER].Handle);
+ if (Actual != Length)
+ {
+ FlFileError (FileId, ASL_MSG_WRITE);
+ AslAbort ();
+ }
+ }
}
@@ -247,7 +260,6 @@ FlPrintFile (
va_start (Args, Format);
-
Actual = vfprintf (Gbl_Files[FileId].Handle, Format, Args);
va_end (Args);
@@ -256,6 +268,30 @@ FlPrintFile (
FlFileError (FileId, ASL_MSG_WRITE);
AslAbort ();
}
+
+ if ((FileId == ASL_FILE_PREPROCESSOR) && Gbl_PreprocessorOutputFlag)
+ {
+ /*
+ * Duplicate the output to the user preprocessor (.i) file,
+ * except: no #line directives.
+ */
+ if (!strncmp (Format, "#line", 5))
+ {
+ return;
+ }
+
+ va_start (Args, Format);
+ Actual = vfprintf (Gbl_Files[ASL_FILE_PREPROCESSOR_USER].Handle,
+ Format, Args);
+ va_end (Args);
+
+ if (Actual == -1)
+ {
+ FlFileError (FileId, ASL_MSG_WRITE);
+ AslAbort ();
+ }
+ }
+
}
diff --git a/sys/contrib/dev/acpica/compiler/aslfiles.c b/sys/contrib/dev/acpica/compiler/aslfiles.c
index d8c9ed5..37043cb 100644
--- a/sys/contrib/dev/acpica/compiler/aslfiles.c
+++ b/sys/contrib/dev/acpica/compiler/aslfiles.c
@@ -43,6 +43,7 @@
#include <contrib/dev/acpica/compiler/aslcompiler.h>
#include <contrib/dev/acpica/include/acapps.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
#define _COMPONENT ACPI_COMPILER
ACPI_MODULE_NAME ("aslfiles")
@@ -84,7 +85,6 @@ FlSetLineNumber (
LineNumber, Gbl_LogicalLineNumber);
Gbl_CurrentLineNumber = LineNumber;
- Gbl_LogicalLineNumber = LineNumber;
}
@@ -303,6 +303,7 @@ FlOpenIncludeWithPrefix (
{
FILE *IncludeFile;
char *Pathname;
+ UINT32 OriginalLineNumber;
/* Build the full pathname to the file */
@@ -322,13 +323,20 @@ FlOpenIncludeWithPrefix (
return (NULL);
}
-#ifdef _MUST_HANDLE_COMMENTS
/*
- * Check entire include file for any # preprocessor directives.
+ * Check the entire include file for any # preprocessor directives.
* This is because there may be some confusion between the #include
- * preprocessor directive and the ASL Include statement.
+ * preprocessor directive and the ASL Include statement. A file included
+ * by the ASL include cannot contain preprocessor directives because
+ * the preprocessor has already run by the time the ASL include is
+ * recognized (by the compiler, not the preprocessor.)
+ *
+ * Note: DtGetNextLine strips/ignores comments.
+ * Save current line number since DtGetNextLine modifies it.
*/
- while (fgets (Gbl_CurrentLineBuffer, Gbl_LineBufferSize, IncludeFile))
+ Gbl_CurrentLineNumber--;
+ OriginalLineNumber = Gbl_CurrentLineNumber;
+ while (DtGetNextLine (IncludeFile, DT_ALLOW_MULTILINE_QUOTES) != ASL_EOF)
{
if (Gbl_CurrentLineBuffer[0] == '#')
{
@@ -336,7 +344,7 @@ FlOpenIncludeWithPrefix (
Op, "use #include instead");
}
}
-#endif
+ Gbl_CurrentLineNumber = OriginalLineNumber;
/* Must seek back to the start of the file */
@@ -579,8 +587,6 @@ FlOpenMiscOutputFiles (
/* Open the debug file as STDERR, text mode */
- /* TBD: hide this behind a FlReopenFile function */
-
Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Filename = Filename;
Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle =
freopen (Filename, "w+t", stderr);
@@ -588,13 +594,15 @@ FlOpenMiscOutputFiles (
if (!Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle)
{
/*
- * A problem with freopen is that on error,
- * we no longer have stderr.
+ * A problem with freopen is that on error, we no longer
+ * have stderr and cannot emit normal error messages.
+ * Emit error to stdout, close files, and exit.
*/
- Gbl_DebugFlag = FALSE;
- memcpy (stderr, stdout, sizeof (FILE));
- FlFileError (ASL_FILE_DEBUG_OUTPUT, ASL_MSG_DEBUG_FILENAME);
- AslAbort ();
+ fprintf (stdout,
+ "\nCould not open debug output file: %s\n\n", Filename);
+
+ CmCleanupAndExit ();
+ exit (1);
}
AslCompilerSignon (ASL_FILE_DEBUG_OUTPUT);
@@ -621,7 +629,7 @@ FlOpenMiscOutputFiles (
AslCompilerFileHeader (ASL_FILE_LISTING_OUTPUT);
}
- /* Create the preprocessor output file if preprocessor enabled */
+ /* Create the preprocessor output temp file if preprocessor enabled */
if (Gbl_PreprocessFlag)
{
@@ -636,6 +644,23 @@ FlOpenMiscOutputFiles (
FlOpenFile (ASL_FILE_PREPROCESSOR, Filename, "w+t");
}
+ /*
+ * Create the "user" preprocessor output file if -li flag set.
+ * Note, this file contains no embedded #line directives.
+ */
+ if (Gbl_PreprocessorOutputFlag)
+ {
+ Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_PREPROC_USER);
+ if (!Filename)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_PREPROCESSOR_FILENAME,
+ 0, 0, 0, 0, NULL, NULL);
+ return (AE_ERROR);
+ }
+
+ FlOpenFile (ASL_FILE_PREPROCESSOR_USER, Filename, "w+t");
+ }
+
/* All done for data table compiler */
if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA)
diff --git a/sys/contrib/dev/acpica/compiler/aslfold.c b/sys/contrib/dev/acpica/compiler/aslfold.c
index 26b786d..af7a019 100644
--- a/sys/contrib/dev/acpica/compiler/aslfold.c
+++ b/sys/contrib/dev/acpica/compiler/aslfold.c
@@ -236,6 +236,8 @@ OpcAmlCheckForConstant (
*/
if (WalkState->Opcode == AML_BUFFER_OP)
{
+ DbgPrint (ASL_PARSE_OUTPUT,
+ "\nBuffer+Buffer->Buffer constant reduction is not supported yet");
Status = AE_TYPE;
goto CleanupAndExit;
}
@@ -380,10 +382,12 @@ TrSimpleConstantReduction (
return (Status);
}
+ /* Disconnect any existing children, install new constant */
+
+ Op->Asl.Child = NULL;
TrInstallReducedConstant (Op, ObjDesc);
UtSetParseOpName (Op);
- Op->Asl.Child = NULL;
return (AE_OK);
}
@@ -494,6 +498,10 @@ TrTransformToStoreOp (
goto EvalError;
}
+ /* Truncate any subtree expressions, they have been evaluated */
+
+ Child1->Asl.Child = NULL;
+
/* Folded constant is in ObjDesc, store into Child1 */
TrInstallReducedConstant (Child1, ObjDesc);
@@ -505,11 +513,6 @@ TrTransformToStoreOp (
UtSetParseOpName (Op);
Op->Common.Parent = OriginalParent;
- /* Truncate any subtree expressions, they have been evaluated */
-
- Child1->Asl.Child = NULL;
- Child2->Asl.Child = NULL;
-
/* First child is the folded constant */
/* Second child will be the target */
@@ -547,7 +550,8 @@ TrInstallReducedConstant (
ACPI_PARSE_OBJECT *Op,
ACPI_OPERAND_OBJECT *ObjDesc)
{
- ACPI_PARSE_OBJECT *RootOp;
+ ACPI_PARSE_OBJECT *LengthOp;
+ ACPI_PARSE_OBJECT *DataOp;
TotalFolds++;
@@ -574,17 +578,22 @@ TrInstallReducedConstant (
Op->Asl.ParseOpcode = PARSEOP_STRING_LITERAL;
Op->Common.AmlOpcode = AML_STRING_OP;
- Op->Asl.AmlLength = ACPI_STRLEN (ObjDesc->String.Pointer) + 1;
+ Op->Asl.AmlLength = strlen (ObjDesc->String.Pointer) + 1;
Op->Common.Value.String = ObjDesc->String.Pointer;
DbgPrint (ASL_PARSE_OUTPUT,
"Constant expression reduced to (STRING) %s\n\n",
Op->Common.Value.String);
-
break;
case ACPI_TYPE_BUFFER:
-
+ /*
+ * Create a new parse subtree of the form:
+ *
+ * BUFFER (Buffer AML opcode)
+ * INTEGER (Buffer length in bytes)
+ * RAW_DATA (Buffer byte data)
+ */
Op->Asl.ParseOpcode = PARSEOP_BUFFER;
Op->Common.AmlOpcode = AML_BUFFER_OP;
Op->Asl.CompileFlags = NODE_AML_PACKAGE;
@@ -592,28 +601,24 @@ TrInstallReducedConstant (
/* Child node is the buffer length */
- RootOp = TrAllocateNode (PARSEOP_INTEGER);
+ LengthOp = TrAllocateNode (PARSEOP_INTEGER);
- RootOp->Asl.AmlOpcode = AML_DWORD_OP;
- RootOp->Asl.Value.Integer = ObjDesc->Buffer.Length;
- RootOp->Asl.Parent = Op;
+ LengthOp->Asl.AmlOpcode = AML_DWORD_OP;
+ LengthOp->Asl.Value.Integer = ObjDesc->Buffer.Length;
+ LengthOp->Asl.Parent = Op;
+ (void) OpcSetOptimalIntegerSize (LengthOp);
- (void) OpcSetOptimalIntegerSize (RootOp);
-
- Op->Asl.Child = RootOp;
- Op = RootOp;
- UtSetParseOpName (Op);
+ Op->Asl.Child = LengthOp;
- /* Peer to the child is the raw buffer data */
+ /* Next child is the raw buffer data */
- RootOp = TrAllocateNode (PARSEOP_RAW_DATA);
- RootOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER;
- RootOp->Asl.AmlLength = ObjDesc->Buffer.Length;
- RootOp->Asl.Value.String = (char *) ObjDesc->Buffer.Pointer;
- RootOp->Asl.Parent = Op->Asl.Parent;
+ DataOp = TrAllocateNode (PARSEOP_RAW_DATA);
+ DataOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER;
+ DataOp->Asl.AmlLength = ObjDesc->Buffer.Length;
+ DataOp->Asl.Value.String = (char *) ObjDesc->Buffer.Pointer;
+ DataOp->Asl.Parent = Op;
- Op->Asl.Next = RootOp;
- Op = RootOp;
+ LengthOp->Asl.Next = DataOp;
DbgPrint (ASL_PARSE_OUTPUT,
"Constant expression reduced to (BUFFER) length %X\n\n",
diff --git a/sys/contrib/dev/acpica/compiler/aslglobal.h b/sys/contrib/dev/acpica/compiler/aslglobal.h
index c61b8ff..0696b67 100644
--- a/sys/contrib/dev/acpica/compiler/aslglobal.h
+++ b/sys/contrib/dev/acpica/compiler/aslglobal.h
@@ -73,6 +73,7 @@ ASL_FILE_INFO Gbl_Files [ASL_NUM_FILES] =
{NULL, NULL, "Binary Output:", "AML Output"},
{NULL, NULL, "Source Output:", "Source Output"},
{NULL, NULL, "Preprocessor: ", "Preprocessor Output"},
+ {NULL, NULL, "Preprocessor: ", "Preprocessor Temp File"},
{NULL, NULL, "Listing File: ", "Listing Output"},
{NULL, NULL, "Hex Dump: ", "Hex Table Output"},
{NULL, NULL, "Namespace: ", "Namespace Output"},
@@ -123,10 +124,10 @@ ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_CurrentLineBuffer, NUL
ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_LineBufPtr, NULL);
ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_LineBufferSize, ASL_DEFAULT_LINE_BUFFER_SIZE);
ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_CurrentColumn, 0);
-ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_PreviousLineNumber, 0);
ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_CurrentLineNumber, 1);
ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_LogicalLineNumber, 1);
ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_CurrentLineOffset, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_OriginalInputFileSize, 0);
ASL_EXTERN UINT8 ASL_INIT_GLOBAL (Gbl_SyntaxError, 0);
/* Exception reporting */
@@ -146,6 +147,7 @@ ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_UseDefaultAmlFilename,
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_MapfileFlag, FALSE);
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_NsOutputFlag, FALSE);
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_PreprocessorOutputFlag, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_KeepPreprocessorTempFile, FALSE);
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DebugFlag, FALSE);
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_AsmOutputFlag, FALSE);
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_C_OutputFlag, FALSE);
diff --git a/sys/contrib/dev/acpica/compiler/aslmain.c b/sys/contrib/dev/acpica/compiler/aslmain.c
index 99745ad..611183a 100644
--- a/sys/contrib/dev/acpica/compiler/aslmain.c
+++ b/sys/contrib/dev/acpica/compiler/aslmain.c
@@ -261,7 +261,7 @@ AslSignalHandler (
/* Close all open files */
- Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; /* the .i file is same as source file */
+ Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; /* the .pre file is same as source file */
for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++)
{
diff --git a/sys/contrib/dev/acpica/compiler/aslmapenter.c b/sys/contrib/dev/acpica/compiler/aslmapenter.c
index 87ad28a..2d2b863 100644
--- a/sys/contrib/dev/acpica/compiler/aslmapenter.c
+++ b/sys/contrib/dev/acpica/compiler/aslmapenter.c
@@ -239,7 +239,7 @@ MpCreateGpioInfo (
/* Sort on source DeviceName first */
while (NextGpio &&
- (ACPI_STRCMP (DeviceName, NextGpio->DeviceName) > 0))
+ (strcmp (DeviceName, NextGpio->DeviceName) > 0))
{
PrevGpio = NextGpio;
NextGpio = NextGpio->Next;
@@ -249,7 +249,7 @@ MpCreateGpioInfo (
while (NextGpio &&
(NextGpio->PinNumber < PinNumber) &&
- !ACPI_STRCMP (DeviceName, NextGpio->DeviceName))
+ !strcmp (DeviceName, NextGpio->DeviceName))
{
PrevGpio = NextGpio;
NextGpio = NextGpio->Next;
@@ -316,7 +316,7 @@ MpCreateSerialInfo (
/* Sort on source DeviceName */
while (NextSerial &&
- (ACPI_STRCMP (DeviceName, NextSerial->DeviceName) > 0))
+ (strcmp (DeviceName, NextSerial->DeviceName) > 0))
{
PrevSerial = NextSerial;
NextSerial = NextSerial->Next;
@@ -326,7 +326,7 @@ MpCreateSerialInfo (
while (NextSerial &&
(NextSerial->Address < Address) &&
- !ACPI_STRCMP (DeviceName, NextSerial->DeviceName))
+ !strcmp (DeviceName, NextSerial->DeviceName))
{
PrevSerial = NextSerial;
NextSerial = NextSerial->Next;
diff --git a/sys/contrib/dev/acpica/compiler/aslmapoutput.c b/sys/contrib/dev/acpica/compiler/aslmapoutput.c
index 622b1bd..1cf1e53 100644
--- a/sys/contrib/dev/acpica/compiler/aslmapoutput.c
+++ b/sys/contrib/dev/acpica/compiler/aslmapoutput.c
@@ -207,7 +207,7 @@ MpEmitGpioInfo (
/* Print header info for the controller itself */
if (!PrevDeviceName ||
- ACPI_STRCMP (PrevDeviceName, Info->DeviceName))
+ strcmp (PrevDeviceName, Info->DeviceName))
{
FlPrintFile (ASL_FILE_MAP_OUTPUT,
"\n\nGPIO Controller: %-8s %-28s",
@@ -360,7 +360,7 @@ MpEmitSerialInfo (
/* Print header info for the controller itself */
if (!PrevDeviceName ||
- ACPI_STRCMP (PrevDeviceName, Info->DeviceName))
+ strcmp (PrevDeviceName, Info->DeviceName))
{
FlPrintFile (ASL_FILE_MAP_OUTPUT, "\n\n%s Controller: ",
Type);
diff --git a/sys/contrib/dev/acpica/compiler/aslmethod.c b/sys/contrib/dev/acpica/compiler/aslmethod.c
index fa9216e..bee488f 100644
--- a/sys/contrib/dev/acpica/compiler/aslmethod.c
+++ b/sys/contrib/dev/acpica/compiler/aslmethod.c
@@ -430,7 +430,7 @@ MtMethodAnalysisWalkBegin (
/* Special typechecking for _HID */
- if (!ACPI_STRCMP (METHOD_NAME__HID, Op->Asl.NameSeg))
+ if (!strcmp (METHOD_NAME__HID, Op->Asl.NameSeg))
{
Next = Op->Asl.Child->Asl.Next;
AnCheckId (Next, ASL_TYPE_HID);
@@ -438,7 +438,7 @@ MtMethodAnalysisWalkBegin (
/* Special typechecking for _CID */
- else if (!ACPI_STRCMP (METHOD_NAME__CID, Op->Asl.NameSeg))
+ else if (!strcmp (METHOD_NAME__CID, Op->Asl.NameSeg))
{
Next = Op->Asl.Child->Asl.Next;
diff --git a/sys/contrib/dev/acpica/compiler/aslopcodes.c b/sys/contrib/dev/acpica/compiler/aslopcodes.c
index d4dbbe3..43628f9 100644
--- a/sys/contrib/dev/acpica/compiler/aslopcodes.c
+++ b/sys/contrib/dev/acpica/compiler/aslopcodes.c
@@ -636,7 +636,7 @@ OpcDoEisaId (
* The EISAID string must be exactly 7 characters and of the form
* "UUUXXXX" -- 3 uppercase letters and 4 hex digits (e.g., "PNP0001")
*/
- if (ACPI_STRLEN (InString) != 7)
+ if (strlen (InString) != 7)
{
Status = AE_BAD_PARAMETER;
}
@@ -855,7 +855,7 @@ OpcFindName (
for (i = 0, Str = List[0]; Str; i++, Str = List[i])
{
- if (!(ACPI_STRNCMP (Str, Name, ACPI_STRLEN (Name))))
+ if (!(strncmp (Str, Name, strlen (Name))))
{
*Index = i;
return (TRUE);
@@ -907,7 +907,7 @@ OpcDoPld (
return;
}
- ACPI_MEMSET (&PldInfo, 0, sizeof (ACPI_PLD_INFO));
+ memset (&PldInfo, 0, sizeof (ACPI_PLD_INFO));
Node = Op->Asl.Child;
while (Node)
diff --git a/sys/contrib/dev/acpica/compiler/asloperands.c b/sys/contrib/dev/acpica/compiler/asloperands.c
index b2972d4..df63357 100644
--- a/sys/contrib/dev/acpica/compiler/asloperands.c
+++ b/sys/contrib/dev/acpica/compiler/asloperands.c
@@ -932,7 +932,7 @@ OpnDoDefinitionBlock (
if (Child->Asl.Value.String)
{
Gbl_TableSignature = Child->Asl.Value.String;
- if (ACPI_STRLEN (Gbl_TableSignature) != 4)
+ if (strlen (Gbl_TableSignature) != 4)
{
AslError (ASL_ERROR, ASL_MSG_TABLE_SIGNATURE, Child,
"Length not exactly 4");
@@ -967,9 +967,9 @@ OpnDoDefinitionBlock (
Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
if (Child->Asl.Value.String)
{
- Length = ACPI_STRLEN (Child->Asl.Value.String);
+ Length = strlen (Child->Asl.Value.String);
Gbl_TableId = UtStringCacheCalloc (Length + 1);
- ACPI_STRCPY (Gbl_TableId, Child->Asl.Value.String);
+ strcpy (Gbl_TableId, Child->Asl.Value.String);
/*
* Convert anything non-alphanumeric to an underscore. This
diff --git a/sys/contrib/dev/acpica/compiler/aslopt.c b/sys/contrib/dev/acpica/compiler/aslopt.c
index 1079f9c..a65a25e 100644
--- a/sys/contrib/dev/acpica/compiler/aslopt.c
+++ b/sys/contrib/dev/acpica/compiler/aslopt.c
@@ -168,9 +168,9 @@ OptSearchToRoot (
/* We must allocate a new string for the name (TargetPath gets deleted) */
*NewPath = UtStringCacheCalloc (ACPI_NAME_SIZE + 1);
- ACPI_STRCPY (*NewPath, Path);
+ strcpy (*NewPath, Path);
- if (ACPI_STRNCMP (*NewPath, "_T_", 3))
+ if (strncmp (*NewPath, "_T_", 3))
{
AslError (ASL_OPTIMIZATION, ASL_MSG_SINGLE_NAME_OPTIMIZATION, Op,
*NewPath);
@@ -341,7 +341,7 @@ OptBuildShortestPath (
Index = TargetPath->Length;
}
- ACPI_STRCPY (&NewPathExternal[i], &((char *) TargetPath->Pointer)[Index]);
+ strcpy (&NewPathExternal[i], &((char *) TargetPath->Pointer)[Index]);
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " %-24s", NewPathExternal));
/*
@@ -358,11 +358,11 @@ OptBuildShortestPath (
return (Status);
}
- if (ACPI_STRLEN (NewPath) >= AmlNameStringLength)
+ if (strlen (NewPath) >= AmlNameStringLength)
{
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
" NOT SHORTER (New %u old %u)",
- (UINT32) ACPI_STRLEN (NewPath), (UINT32) AmlNameStringLength));
+ (UINT32) strlen (NewPath), (UINT32) AmlNameStringLength));
ACPI_FREE (NewPathExternal);
return (AE_NOT_FOUND);
}
@@ -597,7 +597,7 @@ OptOptimizeNamePath (
* The original path must be longer than one NameSeg (4 chars) for there
* to be any possibility that it can be optimized to a shorter string
*/
- AmlNameStringLength = ACPI_STRLEN (AmlNameString);
+ AmlNameStringLength = strlen (AmlNameString);
if (AmlNameStringLength <= ACPI_NAME_SIZE)
{
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
@@ -745,7 +745,7 @@ OptOptimizeNamePath (
*/
if (ACPI_SUCCESS (Status))
{
- HowMuchShorter = (AmlNameStringLength - ACPI_STRLEN (NewPath));
+ HowMuchShorter = (AmlNameStringLength - strlen (NewPath));
OptTotal += HowMuchShorter;
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
@@ -761,12 +761,12 @@ OptOptimizeNamePath (
* (alias name) is the second operand
*/
Op->Asl.Child->Asl.Next->Asl.Value.String = NewPath;
- Op->Asl.Child->Asl.Next->Asl.AmlLength = ACPI_STRLEN (NewPath);
+ Op->Asl.Child->Asl.Next->Asl.AmlLength = strlen (NewPath);
}
else
{
Op->Asl.Child->Asl.Value.String = NewPath;
- Op->Asl.Child->Asl.AmlLength = ACPI_STRLEN (NewPath);
+ Op->Asl.Child->Asl.AmlLength = strlen (NewPath);
}
}
else if (Flags & AML_CREATE)
@@ -781,14 +781,14 @@ OptOptimizeNamePath (
/* Update the parse node with the new NamePath */
NextOp->Asl.Value.String = NewPath;
- NextOp->Asl.AmlLength = ACPI_STRLEN (NewPath);
+ NextOp->Asl.AmlLength = strlen (NewPath);
}
else
{
/* Update the parse node with the new NamePath */
Op->Asl.Value.String = NewPath;
- Op->Asl.AmlLength = ACPI_STRLEN (NewPath);
+ Op->Asl.AmlLength = strlen (NewPath);
}
}
else
diff --git a/sys/contrib/dev/acpica/compiler/asloptions.c b/sys/contrib/dev/acpica/compiler/asloptions.c
index cc20bcd..4cff853 100644
--- a/sys/contrib/dev/acpica/compiler/asloptions.c
+++ b/sys/contrib/dev/acpica/compiler/asloptions.c
@@ -194,6 +194,7 @@ AslDoOptions (
DtParserdebug = 1;
PrParserdebug = 1;
Gbl_DebugFlag = TRUE;
+ Gbl_KeepPreprocessorTempFile = TRUE;
break;
case 'p': /* Prune ASL parse tree */
diff --git a/sys/contrib/dev/acpica/compiler/aslprintf.c b/sys/contrib/dev/acpica/compiler/aslprintf.c
index c8647ea..1d8d4d7 100644
--- a/sys/contrib/dev/acpica/compiler/aslprintf.c
+++ b/sys/contrib/dev/acpica/compiler/aslprintf.c
@@ -186,7 +186,7 @@ OpcParsePrintf (
if (StringToProcess)
{
NewString = UtStringCacheCalloc (StringLength + 1);
- ACPI_STRNCPY (NewString, StartPosition, StringLength);
+ strncpy (NewString, StartPosition, StringLength);
NewOp = TrAllocateNode (PARSEOP_STRING_LITERAL);
NewOp->Asl.Value.String = NewString;
@@ -275,7 +275,7 @@ OpcParsePrintf (
if (StringToProcess)
{
NewString = UtStringCacheCalloc (StringLength + 1);
- ACPI_STRNCPY (NewString, StartPosition, StringLength);
+ strncpy (NewString, StartPosition, StringLength);
NewOp = TrAllocateNode (PARSEOP_STRING_LITERAL);
NewOp->Asl.Value.String = NewString;
diff --git a/sys/contrib/dev/acpica/compiler/aslstartup.c b/sys/contrib/dev/acpica/compiler/aslstartup.c
index 85e2f88..211658b 100644
--- a/sys/contrib/dev/acpica/compiler/aslstartup.c
+++ b/sys/contrib/dev/acpica/compiler/aslstartup.c
@@ -359,6 +359,8 @@ AslDoOneFile (
return (AE_ERROR);
}
+ Gbl_OriginalInputFileSize = FlGetFileSize (ASL_FILE_INPUT);
+
/* Determine input file type */
Gbl_FileType = AslDetectSourceFileType (&Gbl_Files[ASL_FILE_INPUT]);
diff --git a/sys/contrib/dev/acpica/compiler/aslsupport.l b/sys/contrib/dev/acpica/compiler/aslsupport.l
index b3149cf..0016626 100644
--- a/sys/contrib/dev/acpica/compiler/aslsupport.l
+++ b/sys/contrib/dev/acpica/compiler/aslsupport.l
@@ -113,6 +113,7 @@ AslDoLineDirective (
char *Filename;
UINT32 i;
+ Gbl_HasIncludeFiles = TRUE;
/* Eat the entire line that contains the #line directive */
@@ -713,7 +714,7 @@ DoCharacter:
* string and resume processing of the next character
*/
ConvertBuffer[i] = 0;
- Digit = (UINT8) ACPI_STRTOUL (ConvertBuffer, NULL, 8);
+ Digit = (UINT8) strtoul (ConvertBuffer, NULL, 8);
/* Check for NULL or non-ascii character (ignore if so) */
@@ -749,7 +750,7 @@ DoCharacter:
/* Up to two hex digits allowed */
- if (!ACPI_IS_XDIGIT (StringChar) ||
+ if (!isxdigit (StringChar) ||
(i > 1))
{
/*
@@ -757,7 +758,7 @@ DoCharacter:
* string and resume processing of the next character
*/
ConvertBuffer[i] = 0;
- Digit = (UINT8) ACPI_STRTOUL (ConvertBuffer, NULL, 16);
+ Digit = (UINT8) strtoul (ConvertBuffer, NULL, 16);
/* Check for NULL or non-ascii character (ignore if so) */
@@ -830,7 +831,7 @@ CompletedString:
return (FALSE);
}
- ACPI_STRCPY (CleanString, MsgBuffer);
+ strcpy (CleanString, MsgBuffer);
AslCompilerlval.s = CleanString;
return (TRUE);
diff --git a/sys/contrib/dev/acpica/compiler/asltypes.h b/sys/contrib/dev/acpica/compiler/asltypes.h
index 4bd24da..343c364 100644
--- a/sys/contrib/dev/acpica/compiler/asltypes.h
+++ b/sys/contrib/dev/acpica/compiler/asltypes.h
@@ -148,32 +148,56 @@ typedef struct asl_file_status
/*
* File types. Note: Any changes to this table must also be reflected
* in the Gbl_Files array.
+ *
+ * Corresponding filename suffixes are in comments
+ *
+ * NOTE: Don't move the first 4 file types
*/
typedef enum
{
ASL_FILE_STDOUT = 0,
ASL_FILE_STDERR,
- ASL_FILE_INPUT,
- ASL_FILE_AML_OUTPUT, /* Don't move these first 4 file types */
- ASL_FILE_SOURCE_OUTPUT,
- ASL_FILE_PREPROCESSOR,
- ASL_FILE_LISTING_OUTPUT,
- ASL_FILE_HEX_OUTPUT,
- ASL_FILE_NAMESPACE_OUTPUT,
- ASL_FILE_DEBUG_OUTPUT,
- ASL_FILE_ASM_SOURCE_OUTPUT,
- ASL_FILE_C_SOURCE_OUTPUT,
- ASL_FILE_ASM_INCLUDE_OUTPUT,
- ASL_FILE_C_INCLUDE_OUTPUT,
- ASL_FILE_C_OFFSET_OUTPUT,
- ASL_FILE_MAP_OUTPUT
+ ASL_FILE_INPUT, /* .asl */
+ ASL_FILE_AML_OUTPUT, /* .aml */
+ ASL_FILE_SOURCE_OUTPUT, /* .src */
+ ASL_FILE_PREPROCESSOR, /* .pre */
+ ASL_FILE_PREPROCESSOR_USER, /* .i */
+ ASL_FILE_LISTING_OUTPUT, /* .lst */
+ ASL_FILE_HEX_OUTPUT, /* .hex */
+ ASL_FILE_NAMESPACE_OUTPUT, /* .nsp */
+ ASL_FILE_DEBUG_OUTPUT, /* .txt */
+ ASL_FILE_ASM_SOURCE_OUTPUT, /* .asm */
+ ASL_FILE_C_SOURCE_OUTPUT, /* .c */
+ ASL_FILE_ASM_INCLUDE_OUTPUT,/* .inc */
+ ASL_FILE_C_INCLUDE_OUTPUT, /* .h */
+ ASL_FILE_C_OFFSET_OUTPUT, /* offset.h */
+ ASL_FILE_MAP_OUTPUT /* .map */
} ASL_FILE_TYPES;
-#define ASL_MAX_FILE_TYPE 15
+#define ASL_MAX_FILE_TYPE 16
#define ASL_NUM_FILES (ASL_MAX_FILE_TYPE + 1)
+/* filename suffixes for output files */
+
+#define FILE_SUFFIX_PREPROC_USER "i "
+#define FILE_SUFFIX_PREPROCESSOR "pre"
+#define FILE_SUFFIX_AML_CODE "aml"
+#define FILE_SUFFIX_MAP "map"
+#define FILE_SUFFIX_LISTING "lst"
+#define FILE_SUFFIX_HEX_DUMP "hex"
+#define FILE_SUFFIX_DEBUG "txt"
+#define FILE_SUFFIX_SOURCE "src"
+#define FILE_SUFFIX_NAMESPACE "nsp"
+#define FILE_SUFFIX_ASM_SOURCE "asm"
+#define FILE_SUFFIX_C_SOURCE "c"
+#define FILE_SUFFIX_DISASSEMBLY "dsl"
+#define FILE_SUFFIX_ASM_INCLUDE "inc"
+#define FILE_SUFFIX_C_INCLUDE "h"
+#define FILE_SUFFIX_ASL_CODE "asl"
+#define FILE_SUFFIX_C_OFFSET "offset.h"
+
/* Cache block structure for ParseOps and Strings */
diff --git a/sys/contrib/dev/acpica/compiler/aslutils.c b/sys/contrib/dev/acpica/compiler/aslutils.c
index dadd6b1..e0511a4 100644
--- a/sys/contrib/dev/acpica/compiler/aslutils.c
+++ b/sys/contrib/dev/acpica/compiler/aslutils.c
@@ -441,17 +441,20 @@ UtDisplaySummary (
"%-14s %s - %u lines, %u bytes, %u keywords\n",
"ASL Input:",
Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber,
- Gbl_InputByteCount, TotalKeywords);
+ Gbl_OriginalInputFileSize, TotalKeywords);
/* AML summary */
if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors))
{
- FlPrintFile (FileId,
- "%-14s %s - %u bytes, %u named objects, %u executable opcodes\n",
- "AML Output:",
- Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength,
- TotalNamedObjects, TotalExecutableOpcodes);
+ if (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
+ {
+ FlPrintFile (FileId,
+ "%-14s %s - %u bytes, %u named objects, %u executable opcodes\n",
+ "AML Output:",
+ Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength,
+ TotalNamedObjects, TotalExecutableOpcodes);
+ }
}
}
@@ -471,9 +474,9 @@ UtDisplaySummary (
continue;
}
- /* .I is a temp file unless specifically requested */
+ /* .PRE is the preprocessor intermediate file */
- if ((i == ASL_FILE_PREPROCESSOR) && (!Gbl_PreprocessorOutputFlag))
+ if ((i == ASL_FILE_PREPROCESSOR) && (!Gbl_KeepPreprocessorTempFile))
{
continue;
}
@@ -932,7 +935,7 @@ UtDoConstant (
char ErrBuf[64];
- Status = UtStrtoul64 (String, 0, &Converted);
+ Status = stroul64 (String, 0, &Converted);
if (ACPI_FAILURE (Status))
{
sprintf (ErrBuf, "%s %s\n", "Conversion error:",
@@ -948,7 +951,7 @@ UtDoConstant (
/*******************************************************************************
*
- * FUNCTION: UtStrtoul64
+ * FUNCTION: stroul64
*
* PARAMETERS: String - Null terminated string
* Terminater - Where a pointer to the terminating byte
@@ -962,7 +965,7 @@ UtDoConstant (
******************************************************************************/
ACPI_STATUS
-UtStrtoul64 (
+stroul64 (
char *String,
UINT32 Base,
UINT64 *RetInteger)
diff --git a/sys/contrib/dev/acpica/compiler/asluuid.c b/sys/contrib/dev/acpica/compiler/asluuid.c
index 4e345e9..850ac6a 100644
--- a/sys/contrib/dev/acpica/compiler/asluuid.c
+++ b/sys/contrib/dev/acpica/compiler/asluuid.c
@@ -69,7 +69,7 @@ AuValidateUuid (
UINT32 i;
- if (!InString || (ACPI_STRLEN (InString) != UUID_STRING_LENGTH))
+ if (!InString || (strlen (InString) != UUID_STRING_LENGTH))
{
return (AE_BAD_PARAMETER);
}
diff --git a/sys/contrib/dev/acpica/compiler/dtcompile.c b/sys/contrib/dev/acpica/compiler/dtcompile.c
index 20da143..506c4cd 100644
--- a/sys/contrib/dev/acpica/compiler/dtcompile.c
+++ b/sys/contrib/dev/acpica/compiler/dtcompile.c
@@ -302,7 +302,7 @@ DtCompileDataTable (
return (AE_ERROR);
}
- Gbl_Signature = UtStringCacheCalloc (ACPI_STRLEN (Signature) + 1);
+ Gbl_Signature = UtStringCacheCalloc (strlen (Signature) + 1);
strcpy (Gbl_Signature, Signature);
/*
@@ -358,6 +358,8 @@ DtCompileDataTable (
TableData = AcpiDmGetTableData (Signature);
if (!TableData || Gbl_CompileGeneric)
{
+ /* Unknown table signature and/or force generic compile */
+
DtCompileGeneric ((void **) FieldList, NULL, NULL);
goto FinishHeader;
}
@@ -454,7 +456,7 @@ DtCompileTable (
/* Ignore optional subtable if name does not match */
if ((Info->Flags & DT_OPTIONAL) &&
- ACPI_STRCMP ((*Field)->Name, Info->Name))
+ strcmp ((*Field)->Name, Info->Name))
{
*RetSubtable = NULL;
return (AE_OK);
@@ -591,7 +593,7 @@ DtCompileTable (
DtSetSubtableLength (InlineSubtable);
- ACPI_MEMCPY (Buffer, InlineSubtable->Buffer, FieldLength);
+ memcpy (Buffer, InlineSubtable->Buffer, FieldLength);
LocalField = *Field;
break;
diff --git a/sys/contrib/dev/acpica/compiler/dtcompiler.h b/sys/contrib/dev/acpica/compiler/dtcompiler.h
index 201b2db..daff7aa 100644
--- a/sys/contrib/dev/acpica/compiler/dtcompiler.h
+++ b/sys/contrib/dev/acpica/compiler/dtcompiler.h
@@ -181,7 +181,13 @@ DtCompilePadding (
UINT32
DtGetNextLine (
- FILE *Handle);
+ FILE *Handle,
+ UINT32 Flags);
+
+/* Flags for DtGetNextLine */
+
+#define DT_ALLOW_MULTILINE_QUOTES 0x01
+
DT_FIELD *
DtScanFile (
diff --git a/sys/contrib/dev/acpica/compiler/dtexpress.c b/sys/contrib/dev/acpica/compiler/dtexpress.c
index 90054c9..4316b79 100644
--- a/sys/contrib/dev/acpica/compiler/dtexpress.c
+++ b/sys/contrib/dev/acpica/compiler/dtexpress.c
@@ -413,7 +413,7 @@ DtLookupLabel (
LabelField = Gbl_LabelList;
while (LabelField)
{
- if (!ACPI_STRCMP (Name, LabelField->Value))
+ if (!strcmp (Name, LabelField->Value))
{
return (LabelField);
}
diff --git a/sys/contrib/dev/acpica/compiler/dtfield.c b/sys/contrib/dev/acpica/compiler/dtfield.c
index 3b191ab..621636c 100644
--- a/sys/contrib/dev/acpica/compiler/dtfield.c
+++ b/sys/contrib/dev/acpica/compiler/dtfield.c
@@ -166,7 +166,7 @@ DtCompileString (
UINT32 Length;
- Length = ACPI_STRLEN (Field->Value);
+ Length = strlen (Field->Value);
/* Check if the string is too long for the field */
@@ -177,7 +177,7 @@ DtCompileString (
Length = ByteLength;
}
- ACPI_MEMCPY (Buffer, Field->Value, Length);
+ memcpy (Buffer, Field->Value, Length);
}
@@ -212,7 +212,7 @@ DtCompileUnicode (
AsciiString = Field->Value;
UnicodeString = (UINT16 *) Buffer;
- Count = ACPI_STRLEN (AsciiString) + 1;
+ Count = strlen (AsciiString) + 1;
/* Convert to Unicode string (including null terminator) */
@@ -318,7 +318,7 @@ DtCompileInteger (
/* TBD: Should use a flag rather than compare "Reserved" */
- if (!ACPI_STRCMP (Field->Name, "Reserved"))
+ if (!strcmp (Field->Name, "Reserved"))
{
if (Flags & DT_NON_ZERO)
{
@@ -359,7 +359,7 @@ DtCompileInteger (
DtError (ASL_ERROR, ASL_MSG_INTEGER_SIZE, Field, MsgBuffer);
}
- ACPI_MEMCPY (Buffer, &Value, ByteLength);
+ memcpy (Buffer, &Value, ByteLength);
return;
}
@@ -391,7 +391,7 @@ DtNormalizeBuffer (
char c;
- NewBuffer = UtLocalCalloc (ACPI_STRLEN (Buffer) + 1);
+ NewBuffer = UtLocalCalloc (strlen (Buffer) + 1);
TmpBuffer = NewBuffer;
while ((c = *Buffer++))
diff --git a/sys/contrib/dev/acpica/compiler/dtio.c b/sys/contrib/dev/acpica/compiler/dtio.c
index 4b05bd0..fed9925 100644
--- a/sys/contrib/dev/acpica/compiler/dtio.c
+++ b/sys/contrib/dev/acpica/compiler/dtio.c
@@ -129,7 +129,7 @@ DtTrim (
/* Skip lines that start with a space */
- if (!ACPI_STRCMP (String, " "))
+ if (!strcmp (String, " "))
{
ReturnString = UtStringCacheCalloc (1);
return (ReturnString);
@@ -138,7 +138,7 @@ DtTrim (
/* Setup pointers to start and end of input string */
Start = String;
- End = String + ACPI_STRLEN (String) - 1;
+ End = String + strlen (String) - 1;
/* Find first non-whitespace character */
@@ -180,9 +180,9 @@ DtTrim (
Length = ACPI_PTR_DIFF (End, Start) + 1;
ReturnString = UtStringCacheCalloc (Length + 1);
- if (ACPI_STRLEN (Start))
+ if (strlen (Start))
{
- ACPI_STRNCPY (ReturnString, Start, Length);
+ strncpy (ReturnString, Start, Length);
}
ReturnString[Length] = 0;
@@ -313,7 +313,7 @@ DtParseLine (
Length = ACPI_PTR_DIFF (End, Start);
TmpName = UtLocalCalloc (Length + 1);
- ACPI_STRNCPY (TmpName, Start, Length);
+ strncpy (TmpName, Start, Length);
Name = DtTrim (TmpName);
ACPI_FREE (TmpName);
@@ -360,7 +360,7 @@ DtParseLine (
Length = ACPI_PTR_DIFF (End, Start);
TmpValue = UtLocalCalloc (Length + 1);
- ACPI_STRNCPY (TmpValue, Start, Length);
+ strncpy (TmpValue, Start, Length);
Value = DtTrim (TmpValue);
ACPI_FREE (TmpValue);
@@ -406,7 +406,8 @@ DtParseLine (
UINT32
DtGetNextLine (
- FILE *Handle)
+ FILE *Handle,
+ UINT32 Flags)
{
BOOLEAN LineNotAllBlanks = FALSE;
UINT32 State = DT_NORMAL_TEXT;
@@ -415,7 +416,7 @@ DtGetNextLine (
int c;
- ACPI_MEMSET (Gbl_CurrentLineBuffer, 0, Gbl_LineBufferSize);
+ memset (Gbl_CurrentLineBuffer, 0, Gbl_LineBufferSize);
for (i = 0; ;)
{
/*
@@ -550,9 +551,12 @@ DtGetNextLine (
case '\n':
- AcpiOsPrintf ("ERROR at line %u: Unterminated quoted string\n",
- Gbl_CurrentLineNumber++);
- State = DT_NORMAL_TEXT;
+ if (!(Flags & DT_ALLOW_MULTILINE_QUOTES))
+ {
+ AcpiOsPrintf ("ERROR at line %u: Unterminated quoted string\n",
+ Gbl_CurrentLineNumber++);
+ State = DT_NORMAL_TEXT;
+ }
break;
default: /* Get next character */
@@ -746,7 +750,7 @@ DtScanFile (
/* Scan line-by-line */
- while ((Offset = DtGetNextLine (Handle)) != ASL_EOF)
+ while ((Offset = DtGetNextLine (Handle, 0)) != ASL_EOF)
{
ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Line %2.2u/%4.4X - %s",
Gbl_CurrentLineNumber, Offset, Gbl_CurrentLineBuffer));
@@ -897,7 +901,7 @@ DtDumpBuffer (
}
BufChar = Buffer[(ACPI_SIZE) i + j];
- if (ACPI_IS_PRINT (BufChar))
+ if (isprint (BufChar))
{
FlPrintFile (FileId, "%c", BufChar);
}
diff --git a/sys/contrib/dev/acpica/compiler/dtparser.y b/sys/contrib/dev/acpica/compiler/dtparser.y
index 0271d78..9d6f1e2 100644
--- a/sys/contrib/dev/acpica/compiler/dtparser.y
+++ b/sys/contrib/dev/acpica/compiler/dtparser.y
@@ -48,6 +48,13 @@
#define _COMPONENT DT_COMPILER
ACPI_MODULE_NAME ("dtparser")
+void * AslLocalAllocate (unsigned int Size);
+
+/* Bison/yacc configuration */
+
+#undef alloca
+#define alloca AslLocalAllocate
+
int DtParserlex (void);
int DtParserparse (void);
void DtParsererror (char const *msg);
@@ -162,15 +169,15 @@ Expression
/* Default base for a non-prefixed integer is 16 */
- | EXPOP_NUMBER { UtStrtoul64 (DtParsertext, 16, &$$);}
+ | EXPOP_NUMBER { stroul64 (DtParsertext, 16, &$$);}
/* Standard hex number (0x1234) */
- | EXPOP_HEX_NUMBER { UtStrtoul64 (DtParsertext, 16, &$$);}
+ | EXPOP_HEX_NUMBER { stroul64 (DtParsertext, 16, &$$);}
- /* TBD: Decimal number with prefix (0d1234) - Not supported by UtStrtoul64 at this time */
+ /* TBD: Decimal number with prefix (0d1234) - Not supported by stroul64 at this time */
- | EXPOP_DECIMAL_NUMBER { UtStrtoul64 (DtParsertext, 10, &$$);}
+ | EXPOP_DECIMAL_NUMBER { stroul64 (DtParsertext, 10, &$$);}
;
%%
diff --git a/sys/contrib/dev/acpica/compiler/dtsubtable.c b/sys/contrib/dev/acpica/compiler/dtsubtable.c
index 1152656..8cb5253 100644
--- a/sys/contrib/dev/acpica/compiler/dtsubtable.c
+++ b/sys/contrib/dev/acpica/compiler/dtsubtable.c
@@ -80,7 +80,7 @@ DtCreateSubtable (
String = UtStringCacheCalloc (Length);
Subtable->Buffer = ACPI_CAST_PTR (UINT8, String);
- ACPI_MEMCPY (Subtable->Buffer, Buffer, Length);
+ memcpy (Subtable->Buffer, Buffer, Length);
Subtable->Length = Length;
Subtable->TotalLength = Length;
@@ -379,6 +379,6 @@ DtSetSubtableLength (
return;
}
- ACPI_MEMCPY (Subtable->LengthField, &Subtable->TotalLength,
+ memcpy (Subtable->LengthField, &Subtable->TotalLength,
Subtable->SizeOfLengthField);
}
diff --git a/sys/contrib/dev/acpica/compiler/dttable.c b/sys/contrib/dev/acpica/compiler/dttable.c
index bae80ad..1c32fe0 100644
--- a/sys/contrib/dev/acpica/compiler/dttable.c
+++ b/sys/contrib/dev/acpica/compiler/dttable.c
@@ -1824,7 +1824,7 @@ DtCompileIvrs (
if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
{
while (*PFieldList &&
- !ACPI_STRCMP ((*PFieldList)->Name, "Entry Type"))
+ !strcmp ((*PFieldList)->Name, "Entry Type"))
{
SubtableStart = *PFieldList;
DtCompileInteger (&EntryType, *PFieldList, 1, 0);
@@ -3403,13 +3403,13 @@ DtCompileGeneric (
/* Now we can actually compile the parse tree */
- if (*Length)
+ if (Length && *Length)
{
*Length = 0;
}
while (*PFieldList)
{
- if (Name && !ACPI_STRCMP ((*PFieldList)->Name, Name))
+ if (Name && !strcmp ((*PFieldList)->Name, Name))
{
break;
}
diff --git a/sys/contrib/dev/acpica/compiler/dttemplate.c b/sys/contrib/dev/acpica/compiler/dttemplate.c
index 90b6b17..07e930f 100644
--- a/sys/contrib/dev/acpica/compiler/dttemplate.c
+++ b/sys/contrib/dev/acpica/compiler/dttemplate.c
@@ -85,6 +85,7 @@ AcpiUtIsSpecialTable (
{
if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT) ||
+ ACPI_COMPARE_NAME (Signature, ACPI_SIG_OSDT) ||
ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT) ||
ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS) ||
ACPI_COMPARE_NAME (Signature, ACPI_RSDP_NAME))
@@ -127,8 +128,8 @@ DtCreateTemplates (
}
AcpiUtStrupr (Signature);
- if (!ACPI_STRCMP (Signature, "ALL") ||
- !ACPI_STRCMP (Signature, "*"))
+ if (!strcmp (Signature, "ALL") ||
+ !strcmp (Signature, "*"))
{
/* Create all available/known templates */
@@ -327,7 +328,7 @@ DtCreateOneTemplate (
AcpiOsPrintf ("/*\n");
AcpiOsPrintf (ACPI_COMMON_HEADER ("iASL Compiler/Disassembler", " * "));
- AcpiOsPrintf (" * Template for [%4.4s] ACPI Table\n",
+ AcpiOsPrintf (" * Template for [%4.4s] ACPI Table",
Signature);
/* Dump the actual ACPI table */
@@ -336,6 +337,8 @@ DtCreateOneTemplate (
{
/* Normal case, tables that appear in AcpiDmTableData */
+ AcpiOsPrintf (" (static data table)\n");
+
if (Gbl_VerboseTemplates)
{
AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength]"
@@ -344,7 +347,7 @@ DtCreateOneTemplate (
else
{
AcpiOsPrintf (" * Format: [ByteLength]"
- " FieldName : HexFieldValue\n */\n\n");
+ " FieldName : HexFieldValue\n */\n");
}
AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
@@ -352,9 +355,11 @@ DtCreateOneTemplate (
}
else
{
- /* Special ACPI tables - DSDT, SSDT, FADT, RSDP */
+ /* Special ACPI tables - DSDT, SSDT, OSDT, FADT, RSDP */
+
+ AcpiOsPrintf (" (AML byte code table)\n");
- AcpiOsPrintf (" */\n\n");
+ AcpiOsPrintf (" */\n");
if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT))
{
Actual = fwrite (TemplateDsdt, 1, sizeof (TemplateDsdt) -1, File);
@@ -377,6 +382,17 @@ DtCreateOneTemplate (
goto Cleanup;
}
}
+ else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_OSDT))
+ {
+ Actual = fwrite (TemplateOsdt, 1, sizeof (TemplateOsdt) -1, File);
+ if (Actual != sizeof (TemplateOsdt) -1)
+ {
+ fprintf (stderr,
+ "Could not write to output file %s\n", DisasmFilename);
+ Status = AE_ERROR;
+ goto Cleanup;
+ }
+ }
else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS)) /* FADT */
{
AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
diff --git a/sys/contrib/dev/acpica/compiler/dttemplate.h b/sys/contrib/dev/acpica/compiler/dttemplate.h
index 1b27b4e..6d76f4d 100644
--- a/sys/contrib/dev/acpica/compiler/dttemplate.h
+++ b/sys/contrib/dev/acpica/compiler/dttemplate.h
@@ -45,7 +45,7 @@
#define __DTTEMPLATE_H
-/* Special templates for DSDT and SSDT (AML byte-code tables) */
+/* Special templates for the ASL/AML tables: DSDT, SSDT, and OSDT */
const char TemplateDsdt[] =
"DefinitionBlock (\"dsdt.aml\", \"DSDT\", 2, \"Intel\", \"Template\", 0x00000001)\n"
@@ -65,6 +65,15 @@ const char TemplateSsdt[] =
" }\n"
"}\n\n";
+const char TemplateOsdt[] =
+ "DefinitionBlock (\"osdt.aml\", \"OSDT\", 2, \"Intel\", \"Template\", 0x00000001)\n"
+ "{\n"
+ " Method (MAIN, 0, NotSerialized)\n"
+ " {\n"
+ " Return (Zero)\n"
+ " }\n"
+ "}\n\n";
+
/* Templates for ACPI data tables */
diff --git a/sys/contrib/dev/acpica/compiler/dtutils.c b/sys/contrib/dev/acpica/compiler/dtutils.c
index 2d5b762..ce996c4 100644
--- a/sys/contrib/dev/acpica/compiler/dtutils.c
+++ b/sys/contrib/dev/acpica/compiler/dtutils.c
@@ -241,7 +241,7 @@ DtStrtoul64 (
while (*ThisChar)
{
- if (ACPI_IS_DIGIT (*ThisChar))
+ if (isdigit ((int) *ThisChar))
{
/* Convert ASCII 0-9 to Decimal value */
@@ -249,8 +249,8 @@ DtStrtoul64 (
}
else /* Letter */
{
- ThisDigit = (UINT32) ACPI_TOUPPER (*ThisChar);
- if (!ACPI_IS_XDIGIT ((char) ThisDigit))
+ ThisDigit = (UINT32) toupper ((int) *ThisChar);
+ if (!isxdigit ((int) ThisDigit))
{
/* Not A-F */
@@ -568,7 +568,7 @@ DtGetFieldLength (
Value = DtGetFieldValue (Field);
if (Value)
{
- ByteLength = ACPI_STRLEN (Value) + 1;
+ ByteLength = strlen (Value) + 1;
}
else
{ /* At this point, this is a fatal error */
@@ -633,7 +633,7 @@ DtGetFieldLength (
/* TBD: error if Value is NULL? (as below?) */
- ByteLength = (ACPI_STRLEN (Value) + 1) * sizeof(UINT16);
+ ByteLength = (strlen (Value) + 1) * sizeof(UINT16);
break;
default:
diff --git a/sys/contrib/dev/acpica/compiler/prparser.y b/sys/contrib/dev/acpica/compiler/prparser.y
index 20d6e6a..f0c5f9b 100644
--- a/sys/contrib/dev/acpica/compiler/prparser.y
+++ b/sys/contrib/dev/acpica/compiler/prparser.y
@@ -48,6 +48,13 @@
#define _COMPONENT ASL_PREPROCESSOR
ACPI_MODULE_NAME ("prparser")
+void * AslLocalAllocate (unsigned int Size);
+
+/* Bison/yacc configuration */
+
+#undef alloca
+#define alloca AslLocalAllocate
+
int PrParserlex (void);
int PrParserparse (void);
void PrParsererror (char const *msg);
@@ -175,11 +182,11 @@ Expression
/* Default base for a non-prefixed integer is 10 */
- | EXPOP_NUMBER { UtStrtoul64 (PrParsertext, 10, &$$);}
+ | EXPOP_NUMBER { stroul64 (PrParsertext, 10, &$$);}
/* Standard hex number (0x1234) */
- | EXPOP_HEX_NUMBER { UtStrtoul64 (PrParsertext, 16, &$$);}
+ | EXPOP_HEX_NUMBER { stroul64 (PrParsertext, 16, &$$);}
;
%%
diff --git a/sys/contrib/dev/acpica/compiler/prscan.c b/sys/contrib/dev/acpica/compiler/prscan.c
index 12d303c..cbf82a9 100644
--- a/sys/contrib/dev/acpica/compiler/prscan.c
+++ b/sys/contrib/dev/acpica/compiler/prscan.c
@@ -67,6 +67,14 @@ PrDoDirective (
char *DirectiveToken,
char **Next);
+static void
+PrGetNextLineInit (
+ void);
+
+static UINT32
+PrGetNextLine (
+ FILE *Handle);
+
static int
PrMatchDirective (
char *Directive);
@@ -186,7 +194,7 @@ PrInitializeGlobals (
/* Init globals */
Gbl_InputFileList = NULL;
- Gbl_CurrentLineNumber = 0;
+ Gbl_CurrentLineNumber = 1;
Gbl_PreprocessorLineNumber = 1;
Gbl_PreprocessorError = FALSE;
@@ -271,7 +279,7 @@ PrDoPreprocess (
} while (MoreInputFiles);
- /* Point compiler input to the new preprocessor output file (.i) */
+ /* Point compiler input to the new preprocessor output file (.pre) */
FlCloseFile (ASL_FILE_INPUT);
Gbl_Files[ASL_FILE_INPUT].Handle = Gbl_Files[ASL_FILE_PREPROCESSOR].Handle;
@@ -280,7 +288,10 @@ PrDoPreprocess (
/* Reset globals to allow compiler to run */
FlSeekFile (ASL_FILE_INPUT, 0);
- Gbl_CurrentLineNumber = 1;
+ if (!Gbl_PreprocessOnly)
+ {
+ Gbl_CurrentLineNumber = 0;
+ }
DbgPrint (ASL_DEBUG_OUTPUT, "Preprocessing phase complete \n\n");
}
@@ -297,7 +308,8 @@ PrDoPreprocess (
* DESCRIPTION: Preprocess one entire file, line-by-line.
*
* Input: Raw user ASL from ASL_FILE_INPUT
- * Output: Preprocessed file written to ASL_FILE_PREPROCESSOR
+ * Output: Preprocessed file written to ASL_FILE_PREPROCESSOR and
+ * (optionally) ASL_FILE_PREPROCESSOR_USER
*
******************************************************************************/
@@ -305,7 +317,7 @@ static void
PrPreprocessInputFile (
void)
{
- UINT32 Offset;
+ UINT32 Status;
char *Token;
char *ReplaceString;
PR_DEFINE_INFO *DefineInfo;
@@ -314,10 +326,21 @@ PrPreprocessInputFile (
int OffsetAdjust;
+ PrGetNextLineInit ();
+
/* Scan line-by-line. Comments and blank lines are skipped by this function */
- while ((Offset = DtGetNextLine (Gbl_Files[ASL_FILE_INPUT].Handle)) != ASL_EOF)
+ while ((Status = PrGetNextLine (Gbl_Files[ASL_FILE_INPUT].Handle)) != ASL_EOF)
{
+ Gbl_CurrentLineNumber++;
+ Gbl_LogicalLineNumber++;
+
+ if ((Status == ASL_WITHIN_COMMENT) ||
+ (Status == ASL_BLANK_LINE))
+ {
+ goto WriteEntireLine;
+ }
+
/* Need a copy of the input line for strok() */
strcpy (Gbl_MainTokenBuffer, Gbl_CurrentLineBuffer);
@@ -397,24 +420,13 @@ PrPreprocessInputFile (
Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next);
}
- /*
- * Emit a #line directive if necessary, to keep the line numbers in
- * the (.i) file synchronized with the original source code file, so
- * that the correct line number appears in any error messages
- * generated by the actual compiler.
- */
- if (Gbl_CurrentLineNumber > (Gbl_PreviousLineNumber + 1))
- {
- FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u\n",
- Gbl_CurrentLineNumber);
- }
-
- Gbl_PreviousLineNumber = Gbl_CurrentLineNumber;
Gbl_PreprocessorLineNumber++;
+
+WriteEntireLine:
/*
* Now we can write the possibly modified source line to the
- * preprocessor (.i) file
+ * preprocessor file(s).
*/
FlWriteFile (ASL_FILE_PREPROCESSOR, Gbl_CurrentLineBuffer,
strlen (Gbl_CurrentLineBuffer));
@@ -654,7 +666,7 @@ PrDoDirective (
{
#ifndef MACROS_SUPPORTED
AcpiOsPrintf ("%s ERROR - line %u: #define macros are not supported yet\n",
- Gbl_CurrentLineBuffer, Gbl_CurrentLineNumber);
+ Gbl_CurrentLineBuffer, Gbl_LogicalLineNumber);
exit(1);
#else
PrAddMacro (Token, Next);
@@ -691,7 +703,7 @@ PrDoDirective (
#endif
DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
"New #define: %s->%s\n",
- Gbl_CurrentLineNumber, Token, Token2);
+ Gbl_LogicalLineNumber, Token, Token2);
PrAddDefine (Token, Token2, FALSE);
}
@@ -760,10 +772,7 @@ PrDoDirective (
"User #line invocation %s\n", Gbl_CurrentLineNumber,
Token);
- /* Update local line numbers */
-
Gbl_CurrentLineNumber = (UINT32) Value;
- Gbl_PreviousLineNumber = 0;
/* Emit #line into the preprocessor file */
@@ -839,6 +848,107 @@ SyntaxError:
/*******************************************************************************
*
+ * FUNCTION: PrGetNextLine, PrGetNextLineInit
+ *
+ * PARAMETERS: Handle - Open file handle for the source file
+ *
+ * RETURN: Status of the GetLine operation:
+ * AE_OK - Normal line, OK status
+ * ASL_WITHIN_COMMENT - Line is part of a multi-line comment
+ * ASL_EOF - End-of-file reached
+ *
+ * DESCRIPTION: Get the next text line from the input file. Does not strip
+ * comments.
+ *
+ ******************************************************************************/
+
+#define PR_NORMAL_TEXT 0
+#define PR_WITHIN_COMMENT 1
+
+static UINT8 AcpiGbl_LineScanState = PR_NORMAL_TEXT;
+
+static void
+PrGetNextLineInit (
+ void)
+{
+ AcpiGbl_LineScanState = 0;
+}
+
+static UINT32
+PrGetNextLine (
+ FILE *Handle)
+{
+ UINT32 i;
+ int c = 0;
+ int PreviousChar;
+
+
+ /* Always clear the global line buffer */
+
+ memset (Gbl_CurrentLineBuffer, 0, Gbl_LineBufferSize);
+ for (i = 0; ;)
+ {
+ /*
+ * If line is too long, expand the line buffers. Also increases
+ * Gbl_LineBufferSize.
+ */
+ if (i >= Gbl_LineBufferSize)
+ {
+ UtExpandLineBuffers ();
+ }
+
+ PreviousChar = c;
+ c = getc (Handle);
+ if (c == EOF)
+ {
+ return (ASL_EOF);
+ }
+
+ /* We need to worry about multi-line slash-asterisk comments */
+
+ /* Check for comment open */
+
+ if ((AcpiGbl_LineScanState == PR_NORMAL_TEXT) &&
+ (PreviousChar == '/') && (c == '*'))
+ {
+ AcpiGbl_LineScanState = PR_WITHIN_COMMENT;
+ }
+
+ /* Check for comment close */
+
+ if ((AcpiGbl_LineScanState == PR_WITHIN_COMMENT) &&
+ (PreviousChar == '*') && (c == '/'))
+ {
+ AcpiGbl_LineScanState = PR_NORMAL_TEXT;
+ }
+
+ /* Always copy the character into line buffer */
+
+ Gbl_CurrentLineBuffer[i] = (char) c;
+ i++;
+
+ /* Always exit on end-of-line */
+
+ if (c == '\n')
+ {
+ /* Handle multi-line comments */
+
+ if (AcpiGbl_LineScanState == PR_WITHIN_COMMENT)
+ {
+ return (ASL_WITHIN_COMMENT);
+ }
+ if (i == 1)
+ {
+ return (ASL_BLANK_LINE);
+ }
+ return (AE_OK);
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: PrMatchDirective
*
* PARAMETERS: Directive - Pointer to directive name token
diff --git a/sys/contrib/dev/acpica/compiler/prutils.c b/sys/contrib/dev/acpica/compiler/prutils.c
index 7e880b1..751d1a0 100644
--- a/sys/contrib/dev/acpica/compiler/prutils.c
+++ b/sys/contrib/dev/acpica/compiler/prutils.c
@@ -382,6 +382,8 @@ PrPushInputFileStack (
PR_FILE_NODE *Fnode;
+ Gbl_HasIncludeFiles = TRUE;
+
/* Save the current state in an Fnode */
Fnode = UtLocalCalloc (sizeof (PR_FILE_NODE));
@@ -406,11 +408,11 @@ PrPushInputFileStack (
strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename);
Gbl_Files[ASL_FILE_INPUT].Handle = InputFile;
- Gbl_PreviousLineNumber = 0;
- Gbl_CurrentLineNumber = 0;
+ Gbl_CurrentLineNumber = 1;
/* Emit a new #line directive for the include file */
+ Gbl_CurrentLineNumber = 1;
FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\"\n", 1, Filename);
}
@@ -460,12 +462,11 @@ PrPopInputFileStack (
Gbl_Files[ASL_FILE_INPUT].Filename = Fnode->Filename;
Gbl_Files[ASL_FILE_INPUT].Handle = Fnode->File;
Gbl_CurrentLineNumber = Fnode->CurrentLineNumber;
- Gbl_PreviousLineNumber = 0;
/* Emit a new #line directive after the include file */
FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\"\n",
- Gbl_CurrentLineNumber + 1, Fnode->Filename);
+ Gbl_CurrentLineNumber, Fnode->Filename);
/* All done with this node */
diff --git a/sys/contrib/dev/acpica/components/debugger/dbcmds.c b/sys/contrib/dev/acpica/components/debugger/dbcmds.c
index c11451d..0f236d2 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbcmds.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbcmds.c
@@ -111,7 +111,7 @@ AcpiDbConvertToNode (
{
/* Numeric argument, convert */
- Address = ACPI_STRTOUL (InString, NULL, 16);
+ Address = strtoul (InString, NULL, 16);
Node = ACPI_TO_POINTER (Address);
if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE)))
{
@@ -189,7 +189,7 @@ AcpiDbSleep (
/* Convert argument to binary and invoke the sleep state */
- SleepState = (UINT8) ACPI_STRTOUL (ObjectArg, NULL, 0);
+ SleepState = (UINT8) strtoul (ObjectArg, NULL, 0);
AcpiDbDoOneSleepState (SleepState);
return_ACPI_STATUS (AE_OK);
}
@@ -561,7 +561,7 @@ AcpiDbDisplayInterfaces (
/* Install - install an interface */
- SubString = ACPI_STRSTR ("INSTALL", ActionArg);
+ SubString = strstr ("INSTALL", ActionArg);
if (SubString)
{
Status = AcpiInstallInterface (InterfaceNameArg);
@@ -575,7 +575,7 @@ AcpiDbDisplayInterfaces (
/* Remove - remove an interface */
- SubString = ACPI_STRSTR ("REMOVE", ActionArg);
+ SubString = strstr ("REMOVE", ActionArg);
if (SubString)
{
Status = AcpiRemoveInterface (InterfaceNameArg);
@@ -736,7 +736,7 @@ AcpiDmCompareAmlResources (
/* Check for descriptor byte match */
- else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length))
+ else if (memcmp (Aml1, Aml2, Aml1Length))
{
AcpiOsPrintf (
"**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n",
@@ -1138,7 +1138,7 @@ AcpiDbDisplayResources (
/* Asterisk means "display resources for all devices" */
- if (!ObjectArg || (!ACPI_STRCMP (ObjectArg, "*")))
+ if (!ObjectArg || (!strcmp (ObjectArg, "*")))
{
(void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, AcpiDbDeviceResources, NULL, NULL, NULL);
@@ -1191,7 +1191,7 @@ AcpiDbGenerateGpe (
ACPI_GPE_EVENT_INFO *GpeEventInfo;
- GpeNumber = ACPI_STRTOUL (GpeArg, NULL, 0);
+ GpeNumber = strtoul (GpeArg, NULL, 0);
/*
* If no block arg, or block arg == 0 or 1, use the FADT-defined
@@ -1199,7 +1199,7 @@ AcpiDbGenerateGpe (
*/
if (BlockArg)
{
- BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
+ BlockNumber = strtoul (BlockArg, NULL, 0);
if (BlockNumber == 1)
{
BlockNumber = 0;
diff --git a/sys/contrib/dev/acpica/components/debugger/dbconvert.c b/sys/contrib/dev/acpica/components/debugger/dbconvert.c
index f6c0286..08931e4 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbconvert.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbconvert.c
@@ -77,7 +77,7 @@ AcpiDbHexCharToValue (
/* Digit must be ascii [0-9a-fA-F] */
- if (!ACPI_IS_XDIGIT (HexChar))
+ if (!isxdigit (HexChar))
{
return (AE_BAD_HEX_CONSTANT);
}
@@ -88,7 +88,7 @@ AcpiDbHexCharToValue (
}
else
{
- Value = (UINT8) (ACPI_TOUPPER (HexChar) - 0x37);
+ Value = (UINT8) (toupper (HexChar) - 0x37);
}
*ReturnValue = Value;
@@ -306,7 +306,7 @@ AcpiDbConvertToObject (
Object->Type = ACPI_TYPE_STRING;
Object->String.Pointer = String;
- Object->String.Length = (UINT32) ACPI_STRLEN (String);
+ Object->String.Length = (UINT32) strlen (String);
break;
case ACPI_TYPE_BUFFER:
@@ -471,7 +471,7 @@ AcpiDbDumpPldBuffer (
/* The two bit-packed buffers should match */
- if (ACPI_MEMCMP (NewBuffer, BufferDesc->Buffer.Pointer,
+ if (memcmp (NewBuffer, BufferDesc->Buffer.Pointer,
BufferDesc->Buffer.Length))
{
AcpiOsPrintf ("Converted _PLD buffer does not compare. New:\n");
diff --git a/sys/contrib/dev/acpica/components/debugger/dbdisply.c b/sys/contrib/dev/acpica/components/debugger/dbdisply.c
index 507c2b0..d71d21d 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbdisply.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbdisply.c
@@ -141,7 +141,7 @@ AcpiDbGetPointer (
ACPI_SIZE Address;
- Address = ACPI_STRTOUL (Target, NULL, 16);
+ Address = strtoul (Target, NULL, 16);
ObjPtr = ACPI_TO_POINTER (Address);
return (ObjPtr);
}
diff --git a/sys/contrib/dev/acpica/components/debugger/dbexec.c b/sys/contrib/dev/acpica/components/debugger/dbexec.c
index 79c0ee9..c8a4112 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbexec.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbexec.c
@@ -433,15 +433,15 @@ AcpiDbExecute (
}
else
{
- NameString = ACPI_ALLOCATE (ACPI_STRLEN (Name) + 1);
+ NameString = ACPI_ALLOCATE (strlen (Name) + 1);
if (!NameString)
{
return;
}
- ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO));
+ memset (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO));
- ACPI_STRCPY (NameString, Name);
+ strcpy (NameString, Name);
AcpiUtStrupr (NameString);
AcpiGbl_DbMethodInfo.Name = NameString;
AcpiGbl_DbMethodInfo.Args = Args;
@@ -669,8 +669,8 @@ AcpiDbCreateExecutionThreads (
/* Get the arguments */
- NumThreads = ACPI_STRTOUL (NumThreadsArg, NULL, 0);
- NumLoops = ACPI_STRTOUL (NumLoopsArg, NULL, 0);
+ NumThreads = strtoul (NumThreadsArg, NULL, 0);
+ NumLoops = strtoul (NumLoopsArg, NULL, 0);
if (!NumThreads || !NumLoops)
{
@@ -714,7 +714,7 @@ AcpiDbCreateExecutionThreads (
return;
}
- ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO));
+ memset (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO));
/* Array to store IDs of threads */
@@ -729,7 +729,7 @@ AcpiDbCreateExecutionThreads (
(void) AcpiOsDeleteSemaphore (InfoGate);
return;
}
- ACPI_MEMSET (AcpiGbl_DbMethodInfo.Threads, 0, Size);
+ memset (AcpiGbl_DbMethodInfo.Threads, 0, Size);
/* Setup the context to be passed to each thread */
diff --git a/sys/contrib/dev/acpica/components/debugger/dbfileio.c b/sys/contrib/dev/acpica/components/debugger/dbfileio.c
index 59a9a52..f39fac1 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbfileio.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbfileio.c
@@ -112,7 +112,7 @@ AcpiDbOpenDebugFile (
}
AcpiOsPrintf ("Debug output file %s opened\n", Name);
- ACPI_STRNCPY (AcpiGbl_DbDebugFilename, Name,
+ strncpy (AcpiGbl_DbDebugFilename, Name,
sizeof (AcpiGbl_DbDebugFilename));
AcpiGbl_DbOutputToFile = TRUE;
diff --git a/sys/contrib/dev/acpica/components/debugger/dbhistry.c b/sys/contrib/dev/acpica/components/debugger/dbhistry.c
index e945779..6674fdb 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbhistry.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbhistry.c
@@ -92,7 +92,7 @@ AcpiDbAddToHistory (
/* Put command into the next available slot */
- CmdLen = (UINT16) ACPI_STRLEN (CommandLine);
+ CmdLen = (UINT16) strlen (CommandLine);
if (!CmdLen)
{
return;
@@ -100,7 +100,7 @@ AcpiDbAddToHistory (
if (AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command != NULL)
{
- BufferLen = (UINT16) ACPI_STRLEN (
+ BufferLen = (UINT16) strlen (
AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command);
if (CmdLen > BufferLen)
{
@@ -116,7 +116,7 @@ AcpiDbAddToHistory (
AcpiOsAllocate (CmdLen + 1);
}
- ACPI_STRCPY (AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command,
+ strcpy (AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command,
CommandLine);
AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].CmdNum =
@@ -217,7 +217,7 @@ AcpiDbGetFromHistory (
else
{
- CmdNum = ACPI_STRTOUL (CommandNumArg, NULL, 0);
+ CmdNum = strtoul (CommandNumArg, NULL, 0);
}
return (AcpiDbGetHistoryByIndex (CmdNum));
diff --git a/sys/contrib/dev/acpica/components/debugger/dbinput.c b/sys/contrib/dev/acpica/components/debugger/dbinput.c
index 623bc48..f7e59d8 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbinput.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbinput.c
@@ -361,7 +361,7 @@ AcpiDbMatchCommandHelp (
while ((*Command) && (*Invocation) && (*Invocation != ' '))
{
- if (ACPI_TOLOWER (*Command) != ACPI_TOLOWER (*Invocation))
+ if (tolower ((int) *Command) != tolower ((int) *Invocation))
{
return (FALSE);
}
@@ -702,7 +702,7 @@ AcpiDbMatchCommand (
for (i = CMD_FIRST_VALID; AcpiGbl_DbCommands[i].Name; i++)
{
- if (ACPI_STRSTR (AcpiGbl_DbCommands[i].Name, UserCommand) ==
+ if (strstr (AcpiGbl_DbCommands[i].Name, UserCommand) ==
AcpiGbl_DbCommands[i].Name)
{
return (i);
@@ -946,7 +946,7 @@ AcpiDbCommandDispatch (
else if (ParamCount == 2)
{
Temp = AcpiGbl_DbConsoleDebugLevel;
- AcpiGbl_DbConsoleDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1],
+ AcpiGbl_DbConsoleDebugLevel = strtoul (AcpiGbl_DbArgs[1],
NULL, 16);
AcpiOsPrintf (
"Debug Level for console output was %8.8lX, now %8.8lX\n",
@@ -955,7 +955,7 @@ AcpiDbCommandDispatch (
else
{
Temp = AcpiGbl_DbDebugLevel;
- AcpiGbl_DbDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1], NULL, 16);
+ AcpiGbl_DbDebugLevel = strtoul (AcpiGbl_DbArgs[1], NULL, 16);
AcpiOsPrintf (
"Debug Level for file output was %8.8lX, now %8.8lX\n",
Temp, AcpiGbl_DbDebugLevel);
@@ -994,7 +994,7 @@ AcpiDbCommandDispatch (
case CMD_NOTIFY:
- Temp = ACPI_STRTOUL (AcpiGbl_DbArgs[2], NULL, 0);
+ Temp = strtoul (AcpiGbl_DbArgs[2], NULL, 0);
AcpiDbSendNotify (AcpiGbl_DbArgs[1], Temp);
break;
diff --git a/sys/contrib/dev/acpica/components/debugger/dbmethod.c b/sys/contrib/dev/acpica/components/debugger/dbmethod.c
index 5224854..65266c1 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbmethod.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbmethod.c
@@ -89,7 +89,7 @@ AcpiDbSetMethodBreakpoint (
/* Get and verify the breakpoint address */
- Address = ACPI_STRTOUL (Location, NULL, 16);
+ Address = strtoul (Location, NULL, 16);
if (Address <= Op->Common.AmlOffset)
{
AcpiOsPrintf ("Breakpoint %X is beyond current address %X\n",
@@ -174,7 +174,7 @@ AcpiDbSetMethodData (
return;
}
- Value = ACPI_STRTOUL (ValueArg, NULL, 16);
+ Value = strtoul (ValueArg, NULL, 16);
if (Type == 'N')
{
@@ -196,7 +196,7 @@ AcpiDbSetMethodData (
/* Get the index and value */
- Index = ACPI_STRTOUL (IndexArg, NULL, 16);
+ Index = strtoul (IndexArg, NULL, 16);
WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
if (!WalkState)
@@ -304,7 +304,7 @@ AcpiDbDisassembleAml (
if (Statements)
{
- NumStatements = ACPI_STRTOUL (Statements, NULL, 0);
+ NumStatements = strtoul (Statements, NULL, 0);
}
#ifdef ACPI_DISASSEMBLER
diff --git a/sys/contrib/dev/acpica/components/debugger/dbnames.c b/sys/contrib/dev/acpica/components/debugger/dbnames.c
index d749b1d..67cf517 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbnames.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbnames.c
@@ -248,7 +248,7 @@ AcpiDbDumpNamespace (
if (DepthArg)
{
- MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
+ MaxDepth = strtoul (DepthArg, NULL, 0);
}
}
@@ -319,13 +319,13 @@ AcpiDbDumpNamespaceByOwner (
ACPI_OWNER_ID OwnerId;
- OwnerId = (ACPI_OWNER_ID) ACPI_STRTOUL (OwnerArg, NULL, 0);
+ OwnerId = (ACPI_OWNER_ID) strtoul (OwnerArg, NULL, 0);
/* Now we can check for the depth argument */
if (DepthArg)
{
- MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
+ MaxDepth = strtoul (DepthArg, NULL, 0);
}
AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
@@ -426,7 +426,7 @@ AcpiDbFindNameInNamespace (
char *AcpiNamePtr = AcpiName;
- if (ACPI_STRLEN (NameArg) > 4)
+ if (strlen (NameArg) > 4)
{
AcpiOsPrintf ("Name must be no longer than 4 characters\n");
return (AE_OK);
@@ -830,7 +830,7 @@ AcpiDbFindReferences (
/* Convert string to object pointer */
- Address = ACPI_STRTOUL (ObjectArg, NULL, 16);
+ Address = strtoul (ObjectArg, NULL, 16);
ObjDesc = ACPI_TO_POINTER (Address);
/* Search all nodes in namespace */
diff --git a/sys/contrib/dev/acpica/components/debugger/dbtest.c b/sys/contrib/dev/acpica/components/debugger/dbtest.c
index ab14984..ce3347c 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbtest.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbtest.c
@@ -646,7 +646,7 @@ AcpiDbTestBufferType (
* count is not an integral number of bytes. Zero out the
* unused bits.
*/
- ACPI_MEMSET (Buffer, BUFFER_FILL_VALUE, ByteLength);
+ memset (Buffer, BUFFER_FILL_VALUE, ByteLength);
ExtraBits = BitLength % 8;
if (ExtraBits)
{
@@ -671,7 +671,7 @@ AcpiDbTestBufferType (
goto Exit;
}
- if (ACPI_MEMCMP (Temp2->Buffer.Pointer, Buffer, ByteLength))
+ if (memcmp (Temp2->Buffer.Pointer, Buffer, ByteLength))
{
AcpiOsPrintf (" MISMATCH 2: New buffer value");
}
@@ -695,7 +695,7 @@ AcpiDbTestBufferType (
goto Exit;
}
- if (ACPI_MEMCMP (Temp1->Buffer.Pointer, Temp3->Buffer.Pointer, ByteLength))
+ if (memcmp (Temp1->Buffer.Pointer, Temp3->Buffer.Pointer, ByteLength))
{
AcpiOsPrintf (" MISMATCH 3: While restoring original buffer");
}
@@ -751,7 +751,7 @@ AcpiDbTestStringType (
/* Write a new value */
WriteValue.Type = ACPI_TYPE_STRING;
- WriteValue.String.Length = ACPI_STRLEN (ValueToWrite);
+ WriteValue.String.Length = strlen (ValueToWrite);
WriteValue.String.Pointer = ValueToWrite;
Status = AcpiDbWriteToObject (Node, &WriteValue);
@@ -768,7 +768,7 @@ AcpiDbTestStringType (
goto Exit;
}
- if (ACPI_STRCMP (Temp2->String.Pointer, ValueToWrite))
+ if (strcmp (Temp2->String.Pointer, ValueToWrite))
{
AcpiOsPrintf (" MISMATCH 2: %s, expecting %s",
Temp2->String.Pointer, ValueToWrite);
@@ -776,7 +776,7 @@ AcpiDbTestStringType (
/* Write back the original value */
- WriteValue.String.Length = ACPI_STRLEN (Temp1->String.Pointer);
+ WriteValue.String.Length = strlen (Temp1->String.Pointer);
WriteValue.String.Pointer = Temp1->String.Pointer;
Status = AcpiDbWriteToObject (Node, &WriteValue);
@@ -793,7 +793,7 @@ AcpiDbTestStringType (
goto Exit;
}
- if (ACPI_STRCMP (Temp1->String.Pointer, Temp3->String.Pointer))
+ if (strcmp (Temp1->String.Pointer, Temp3->String.Pointer))
{
AcpiOsPrintf (" MISMATCH 3: %s, expecting %s",
Temp3->String.Pointer, Temp1->String.Pointer);
@@ -926,7 +926,7 @@ AcpiDbWriteToObject (
/* Copy the incoming user parameter */
- ACPI_MEMCPY (&Params[1], Value, sizeof (ACPI_OBJECT));
+ memcpy (&Params[1], Value, sizeof (ACPI_OBJECT));
ParamObjects.Count = 2;
ParamObjects.Pointer = Params;
@@ -970,7 +970,7 @@ AcpiDbEvaluateAllPredefinedNames (
if (CountArg)
{
- Info.MaxCount = ACPI_STRTOUL (CountArg, NULL, 0);
+ Info.MaxCount = strtoul (CountArg, NULL, 0);
}
/* Search all nodes in namespace */
@@ -1077,7 +1077,7 @@ AcpiDbEvaluateOnePredefinedName (
case ACPI_TYPE_STRING:
ThisParam->String.Pointer = "This is the default argument string";
- ThisParam->String.Length = ACPI_STRLEN (ThisParam->String.Pointer);
+ ThisParam->String.Length = strlen (ThisParam->String.Pointer);
break;
case ACPI_TYPE_BUFFER:
diff --git a/sys/contrib/dev/acpica/components/debugger/dbutils.c b/sys/contrib/dev/acpica/components/debugger/dbutils.c
index 5db98e1..eeb5f82 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbutils.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbutils.c
@@ -96,7 +96,7 @@ AcpiDbMatchArgument (
for (i = 0; Arguments[i].Name; i++)
{
- if (ACPI_STRSTR (Arguments[i].Name, UserArgument) == Arguments[i].Name)
+ if (strstr (Arguments[i].Name, UserArgument) == Arguments[i].Name)
{
return (i);
}
@@ -375,7 +375,7 @@ AcpiDbUint32ToHexString (
if (Value == 0)
{
- ACPI_STRCPY (Buffer, "0");
+ strcpy (Buffer, "0");
return;
}
diff --git a/sys/contrib/dev/acpica/components/debugger/dbxface.c b/sys/contrib/dev/acpica/components/debugger/dbxface.c
index d72ee5e..6609962 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbxface.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbxface.c
@@ -435,7 +435,7 @@ AcpiDbInitialize (
{
return_ACPI_STATUS (AE_NO_MEMORY);
}
- ACPI_MEMSET (AcpiGbl_DbBuffer, 0, ACPI_DEBUG_BUFFER_SIZE);
+ memset (AcpiGbl_DbBuffer, 0, ACPI_DEBUG_BUFFER_SIZE);
/* Initial scope is the root */
diff --git a/sys/contrib/dev/acpica/components/disassembler/dmbuffer.c b/sys/contrib/dev/acpica/components/disassembler/dmbuffer.c
index 15b7e87..fbd8f0b 100644
--- a/sys/contrib/dev/acpica/components/disassembler/dmbuffer.c
+++ b/sys/contrib/dev/acpica/components/disassembler/dmbuffer.c
@@ -205,7 +205,7 @@ AcpiDmDisasmByteList (
}
BufChar = ByteData[CurrentIndex];
- if (ACPI_IS_PRINT (BufChar))
+ if (isprint (BufChar))
{
AcpiOsPrintf ("%c", BufChar);
}
@@ -554,7 +554,7 @@ AcpiDmIsStringBuffer (
* they will be handled in the string output routine
*/
- if (!ACPI_IS_PRINT (ByteData[i]))
+ if (!isprint (ByteData[i]))
{
return (FALSE);
}
@@ -836,7 +836,7 @@ AcpiDmUnicode (
{
AcpiOsPrintf ("\\%c", OutputValue);
}
- else if (!ACPI_IS_PRINT (OutputValue))
+ else if (!isprint (OutputValue))
{
AcpiOsPrintf ("\\x%2.2X", OutputValue);
}
@@ -902,7 +902,7 @@ AcpiDmGetHardwareIdType (
for (i = 0; i < 3; i++)
{
if (!ACPI_IS_ASCII (Prefix[i]) ||
- !ACPI_IS_ALPHA (Prefix[i]))
+ !isalpha (Prefix[i]))
{
return;
}
diff --git a/sys/contrib/dev/acpica/components/disassembler/dmcstyle.c b/sys/contrib/dev/acpica/components/disassembler/dmcstyle.c
index b66dbed..11814a4 100644
--- a/sys/contrib/dev/acpica/components/disassembler/dmcstyle.c
+++ b/sys/contrib/dev/acpica/components/disassembler/dmcstyle.c
@@ -337,23 +337,70 @@ AcpiDmCheckForSymbolicOpcode (
*/
AcpiDmPromoteTarget (Op, Target);
- /*
- * Check for possible conversion to a "Compound Assignment".
- *
- * Determine if either operand is the same as the target
- * and display compound assignment operator and other operand.
- */
- if ((AcpiDmIsTargetAnOperand (Target, Child1, TRUE)) ||
- (AcpiDmIsTargetAnOperand (Target, Child2, TRUE)))
+ /* Check operands for conversion to a "Compound Assignment" */
+
+ switch (Op->Common.AmlOpcode)
{
- Target->Common.OperatorSymbol =
- AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode);
+ /* Commutative operators */
+
+ case AML_ADD_OP:
+ case AML_MULTIPLY_OP:
+ case AML_BIT_AND_OP:
+ case AML_BIT_OR_OP:
+ case AML_BIT_XOR_OP:
+ /*
+ * For the commutative operators, we can convert to a
+ * compound statement only if at least one (either) operand
+ * is the same as the target.
+ *
+ * Add (A, B, A) --> A += B
+ * Add (B, A, A) --> A += B
+ * Add (B, C, A) --> A = (B + C)
+ */
+ if ((AcpiDmIsTargetAnOperand (Target, Child1, TRUE)) ||
+ (AcpiDmIsTargetAnOperand (Target, Child2, TRUE)))
+ {
+ Target->Common.OperatorSymbol =
+ AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode);
- /* Convert operator to compound assignment */
+ /* Convert operator to compound assignment */
- Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND;
- Child1->Common.OperatorSymbol = NULL;
- return (TRUE);
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND;
+ Child1->Common.OperatorSymbol = NULL;
+ return (TRUE);
+ }
+ break;
+
+ /* Non-commutative operators */
+
+ case AML_SUBTRACT_OP:
+ case AML_DIVIDE_OP:
+ case AML_MOD_OP:
+ case AML_SHIFT_LEFT_OP:
+ case AML_SHIFT_RIGHT_OP:
+ /*
+ * For the non-commutative operators, we can convert to a
+ * compound statement only if the target is the same as the
+ * first operand.
+ *
+ * Subtract (A, B, A) --> A -= B
+ * Subtract (B, A, A) --> A = (B - A)
+ */
+ if ((AcpiDmIsTargetAnOperand (Target, Child1, TRUE)))
+ {
+ Target->Common.OperatorSymbol =
+ AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode);
+
+ /* Convert operator to compound assignment */
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND;
+ Child1->Common.OperatorSymbol = NULL;
+ return (TRUE);
+ }
+ break;
+
+ default:
+ break;
}
/*
@@ -423,8 +470,12 @@ AcpiDmCheckForSymbolicOpcode (
* source so that the target is processed first.
*/
Target = Child1->Common.Next;
- AcpiDmPromoteTarget (Op, Target);
+ if (!Target)
+ {
+ return (FALSE);
+ }
+ AcpiDmPromoteTarget (Op, Target);
if (!Target->Common.OperatorSymbol)
{
Target->Common.OperatorSymbol = " = ";
@@ -674,7 +725,8 @@ AcpiDmPromoteTarget (
*
* DESCRIPTION: Determine if a Target Op is a placeholder Op or a real Target.
* In other words, determine if the optional target is used or
- * not.
+ * not. Note: If Target is NULL, something is seriously wrong,
+ * probably with the parse tree.
*
******************************************************************************/
@@ -683,6 +735,11 @@ AcpiDmIsValidTarget (
ACPI_PARSE_OBJECT *Target)
{
+ if (!Target)
+ {
+ return (FALSE);
+ }
+
if ((Target->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
(Target->Common.Value.Arg == NULL))
{
diff --git a/sys/contrib/dev/acpica/components/disassembler/dmopcode.c b/sys/contrib/dev/acpica/components/disassembler/dmopcode.c
index b10d433..6b7c1f5 100644
--- a/sys/contrib/dev/acpica/components/disassembler/dmopcode.c
+++ b/sys/contrib/dev/acpica/components/disassembler/dmopcode.c
@@ -269,10 +269,10 @@ AcpiDmPredefinedDescription (
* Note: NameString is guaranteed to be upper case here.
*/
LastCharIsDigit =
- (ACPI_IS_DIGIT (NameString[3])); /* d */
+ (isdigit ((int) NameString[3])); /* d */
LastCharsAreHex =
- (ACPI_IS_XDIGIT (NameString[2]) && /* xx */
- ACPI_IS_XDIGIT (NameString[3]));
+ (isxdigit ((int) NameString[2]) && /* xx */
+ isxdigit ((int) NameString[3]));
switch (NameString[1])
{
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsfield.c b/sys/contrib/dev/acpica/components/dispatcher/dsfield.c
index d376bb1..81cf410 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dsfield.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dsfield.c
@@ -530,7 +530,7 @@ AcpiDsCreateField (
}
}
- ACPI_MEMSET (&Info, 0, sizeof (ACPI_CREATE_FIELD_INFO));
+ memset (&Info, 0, sizeof (ACPI_CREATE_FIELD_INFO));
/* Second arg is the field flags */
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsinit.c b/sys/contrib/dev/acpica/components/dispatcher/dsinit.c
index 62f9bde..921f556 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dsinit.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dsinit.c
@@ -224,7 +224,7 @@ AcpiDsInitializeObjects (
/* Set all init info to zero */
- ACPI_MEMSET (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));
+ memset (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));
Info.OwnerId = OwnerId;
Info.TableIndex = TableIndex;
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsobject.c b/sys/contrib/dev/acpica/components/dispatcher/dsobject.c
index 106c6ab..33d0392 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dsobject.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dsobject.c
@@ -348,7 +348,7 @@ AcpiDsBuildInternalBufferObj (
if (ByteList)
{
- ACPI_MEMCPY (ObjDesc->Buffer.Pointer, ByteList->Named.Data,
+ memcpy (ObjDesc->Buffer.Pointer, ByteList->Named.Data,
ByteListLength);
}
}
@@ -775,7 +775,7 @@ AcpiDsInitObjectFromOp (
case ACPI_TYPE_STRING:
ObjDesc->String.Pointer = Op->Common.Value.String;
- ObjDesc->String.Length = (UINT32) ACPI_STRLEN (Op->Common.Value.String);
+ ObjDesc->String.Length = (UINT32) strlen (Op->Common.Value.String);
/*
* The string is contained in the ACPI table, don't ever try
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsutils.c b/sys/contrib/dev/acpica/components/dispatcher/dsutils.c
index a115b2e..9b23c11 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dsutils.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dsutils.c
@@ -605,7 +605,7 @@ AcpiDsCreateOperand (
ObjDesc = AcpiUtCreateStringObject ((ACPI_SIZE) NameLength);
- ACPI_STRNCPY (ObjDesc->String.Pointer, NameString, NameLength);
+ strncpy (ObjDesc->String.Pointer, NameString, NameLength);
Status = AE_OK;
}
else
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dswload.c b/sys/contrib/dev/acpica/components/dispatcher/dswload.c
index 8bc425a..755b15e 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dswload.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dswload.c
@@ -325,9 +325,18 @@ AcpiDsLoad1BeginOp (
if ((WalkState->Opcode != AML_SCOPE_OP) &&
(!(WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP)))
{
- Flags |= ACPI_NS_ERROR_IF_FOUND;
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Cannot already exist\n",
- AcpiUtGetTypeName (ObjectType)));
+ if (WalkState->NamespaceOverride)
+ {
+ Flags |= ACPI_NS_OVERRIDE_IF_FOUND;
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Override allowed\n",
+ AcpiUtGetTypeName (ObjectType)));
+ }
+ else
+ {
+ Flags |= ACPI_NS_ERROR_IF_FOUND;
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Cannot already exist\n",
+ AcpiUtGetTypeName (ObjectType)));
+ }
}
else
{
diff --git a/sys/contrib/dev/acpica/components/events/evgpe.c b/sys/contrib/dev/acpica/components/events/evgpe.c
index 99043ad..0083e60 100644
--- a/sys/contrib/dev/acpica/components/events/evgpe.c
+++ b/sys/contrib/dev/acpica/components/events/evgpe.c
@@ -104,6 +104,7 @@ AcpiEvUpdateGpeEnableMask (
{
ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, (UINT8) RegisterBit);
}
+ GpeRegisterInfo->EnableMask = GpeRegisterInfo->EnableForRun;
return_ACPI_STATUS (AE_OK);
}
@@ -141,7 +142,7 @@ AcpiEvEnableGpe (
/* Enable the requested GPE */
- Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE_SAVE);
+ Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
return_ACPI_STATUS (Status);
}
@@ -231,7 +232,7 @@ AcpiEvRemoveGpeReference (
Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
if (ACPI_SUCCESS (Status))
{
- Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE_SAVE);
+ Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
}
if (ACPI_FAILURE (Status))
diff --git a/sys/contrib/dev/acpica/components/events/evgpeinit.c b/sys/contrib/dev/acpica/components/events/evgpeinit.c
index 0e53a1d..63a4c4a 100644
--- a/sys/contrib/dev/acpica/components/events/evgpeinit.c
+++ b/sys/contrib/dev/acpica/components/events/evgpeinit.c
@@ -395,7 +395,7 @@ AcpiEvMatchGpeMethod (
/* 4) The last two characters of the name are the hex GPE Number */
- GpeNumber = ACPI_STRTOUL (&Name[2], NULL, 16);
+ GpeNumber = strtoul (&Name[2], NULL, 16);
if (GpeNumber == ACPI_UINT32_MAX)
{
/* Conversion failed; invalid method, just ignore it */
diff --git a/sys/contrib/dev/acpica/components/executer/exconfig.c b/sys/contrib/dev/acpica/components/executer/exconfig.c
index 0627f99..96188e6 100644
--- a/sys/contrib/dev/acpica/components/executer/exconfig.c
+++ b/sys/contrib/dev/acpica/components/executer/exconfig.c
@@ -515,7 +515,7 @@ AcpiExLoadOp (
return_ACPI_STATUS (AE_NO_MEMORY);
}
- ACPI_MEMCPY (Table, TableHeader, Length);
+ memcpy (Table, TableHeader, Length);
break;
default:
diff --git a/sys/contrib/dev/acpica/components/executer/exconvrt.c b/sys/contrib/dev/acpica/components/executer/exconvrt.c
index 50ccf26..ac881cb 100644
--- a/sys/contrib/dev/acpica/components/executer/exconvrt.c
+++ b/sys/contrib/dev/acpica/components/executer/exconvrt.c
@@ -251,7 +251,7 @@ AcpiExConvertToBuffer (
/* Copy the integer to the buffer, LSB first */
NewBuf = ReturnDesc->Buffer.Pointer;
- ACPI_MEMCPY (NewBuf,
+ memcpy (NewBuf,
&ObjDesc->Integer.Value,
AcpiGbl_IntegerByteWidth);
break;
@@ -276,7 +276,7 @@ AcpiExConvertToBuffer (
/* Copy the string to the buffer */
NewBuf = ReturnDesc->Buffer.Pointer;
- ACPI_STRNCPY ((char *) NewBuf, (char *) ObjDesc->String.Pointer,
+ strncpy ((char *) NewBuf, (char *) ObjDesc->String.Pointer,
ObjDesc->String.Length);
break;
diff --git a/sys/contrib/dev/acpica/components/executer/exdebug.c b/sys/contrib/dev/acpica/components/executer/exdebug.c
index 5e98fd5..d174ccd 100644
--- a/sys/contrib/dev/acpica/components/executer/exdebug.c
+++ b/sys/contrib/dev/acpica/components/executer/exdebug.c
@@ -81,6 +81,8 @@ AcpiExDoDebugObject (
{
UINT32 i;
UINT32 Timer;
+ ACPI_OPERAND_OBJECT *ObjectDesc;
+ UINT32 Value;
ACPI_FUNCTION_TRACE_PTR (ExDoDebugObject, SourceDesc);
@@ -267,8 +269,37 @@ AcpiExDoDebugObject (
}
else
{
- AcpiExDoDebugObject (SourceDesc->Reference.Object,
- Level+4, 0);
+ ObjectDesc = SourceDesc->Reference.Object;
+ Value = SourceDesc->Reference.Value;
+
+ switch (ObjectDesc->Common.Type)
+ {
+ case ACPI_TYPE_BUFFER:
+
+ AcpiOsPrintf ("Buffer[%u] = 0x%2.2X\n",
+ Value, *SourceDesc->Reference.IndexPointer);
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ AcpiOsPrintf ("String[%u] = \"%c\" (0x%2.2X)\n",
+ Value, *SourceDesc->Reference.IndexPointer,
+ *SourceDesc->Reference.IndexPointer);
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ AcpiOsPrintf ("Package[%u] = ", Value);
+ AcpiExDoDebugObject (*SourceDesc->Reference.Where,
+ Level+4, 0);
+ break;
+
+ default:
+
+ AcpiOsPrintf ("Unknown Reference object type %X\n",
+ ObjectDesc->Common.Type);
+ break;
+ }
}
}
break;
diff --git a/sys/contrib/dev/acpica/components/executer/exdump.c b/sys/contrib/dev/acpica/components/executer/exdump.c
index 622dc14..1a14d38 100644
--- a/sys/contrib/dev/acpica/components/executer/exdump.c
+++ b/sys/contrib/dev/acpica/components/executer/exdump.c
@@ -238,7 +238,7 @@ static ACPI_EXDUMP_INFO AcpiExDumpIndexField[5] =
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET (IndexField.DataObj), "Data Object"}
};
-static ACPI_EXDUMP_INFO AcpiExDumpReference[8] =
+static ACPI_EXDUMP_INFO AcpiExDumpReference[9] =
{
{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpReference), NULL},
{ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Reference.Class), "Class"},
@@ -247,6 +247,7 @@ static ACPI_EXDUMP_INFO AcpiExDumpReference[8] =
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Reference.Object), "Object Desc"},
{ACPI_EXD_NODE, ACPI_EXD_OFFSET (Reference.Node), "Node"},
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Reference.Where), "Where"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Reference.IndexPointer), "Index Pointer"},
{ACPI_EXD_REFERENCE,0, NULL}
};
@@ -1053,16 +1054,18 @@ AcpiExDumpReferenceObj (
{
if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND)
{
- AcpiOsPrintf (" Target: %p", ObjDesc->Reference.Object);
+ AcpiOsPrintf ("%22s %p", "Target :",
+ ObjDesc->Reference.Object);
if (ObjDesc->Reference.Class == ACPI_REFCLASS_TABLE)
{
- AcpiOsPrintf (" Table Index: %X\n", ObjDesc->Reference.Value);
+ AcpiOsPrintf (" Table Index: %X\n",
+ ObjDesc->Reference.Value);
}
else
{
- AcpiOsPrintf (" Target: %p [%s]\n", ObjDesc->Reference.Object,
+ AcpiOsPrintf (" [%s]\n",
AcpiUtGetTypeName (((ACPI_OPERAND_OBJECT *)
- ObjDesc->Reference.Object)->Common.Type));
+ ObjDesc->Reference.Object)->Common.Type));
}
}
else
diff --git a/sys/contrib/dev/acpica/components/executer/exfield.c b/sys/contrib/dev/acpica/components/executer/exfield.c
index 836a378..ad2d05a 100644
--- a/sys/contrib/dev/acpica/components/executer/exfield.c
+++ b/sys/contrib/dev/acpica/components/executer/exfield.c
@@ -460,7 +460,7 @@ AcpiExWriteDataToField (
}
Buffer = BufferDesc->Buffer.Pointer;
- ACPI_MEMCPY (Buffer, SourceDesc->Buffer.Pointer, Length);
+ memcpy (Buffer, SourceDesc->Buffer.Pointer, Length);
/* Lock entire transaction if requested */
diff --git a/sys/contrib/dev/acpica/components/executer/exfldio.c b/sys/contrib/dev/acpica/components/executer/exfldio.c
index 2908da4..31727de 100644
--- a/sys/contrib/dev/acpica/components/executer/exfldio.c
+++ b/sys/contrib/dev/acpica/components/executer/exfldio.c
@@ -456,7 +456,7 @@ AcpiExFieldDatumIo (
* Copy the data from the source buffer.
* Length is the field width in bytes.
*/
- ACPI_MEMCPY (Value,
+ memcpy (Value,
(ObjDesc->BufferField.BufferObj)->Buffer.Pointer +
ObjDesc->BufferField.BaseByteOffset +
FieldDatumByteOffset,
@@ -468,7 +468,7 @@ AcpiExFieldDatumIo (
* Copy the data to the target buffer.
* Length is the field width in bytes.
*/
- ACPI_MEMCPY ((ObjDesc->BufferField.BufferObj)->Buffer.Pointer +
+ memcpy ((ObjDesc->BufferField.BufferObj)->Buffer.Pointer +
ObjDesc->BufferField.BaseByteOffset +
FieldDatumByteOffset,
Value, ObjDesc->CommonField.AccessByteWidth);
@@ -748,7 +748,7 @@ AcpiExExtractFromField (
return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
}
- ACPI_MEMSET (Buffer, 0, BufferLength);
+ memset (Buffer, 0, BufferLength);
AccessBitWidth = ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth);
/* Handle the simple case here */
@@ -765,7 +765,7 @@ AcpiExExtractFromField (
/* Use RawDatum (UINT64) to handle buffers < 64 bits */
Status = AcpiExFieldDatumIo (ObjDesc, 0, &RawDatum, ACPI_READ);
- ACPI_MEMCPY (Buffer, &RawDatum, BufferLength);
+ memcpy (Buffer, &RawDatum, BufferLength);
}
return_ACPI_STATUS (Status);
@@ -835,7 +835,7 @@ AcpiExExtractFromField (
/* Write merged datum to target buffer */
- ACPI_MEMCPY (((char *) Buffer) + BufferOffset, &MergedDatum,
+ memcpy (((char *) Buffer) + BufferOffset, &MergedDatum,
ACPI_MIN(ObjDesc->CommonField.AccessByteWidth,
BufferLength - BufferOffset));
@@ -853,7 +853,7 @@ AcpiExExtractFromField (
/* Write the last datum to the buffer */
- ACPI_MEMCPY (((char *) Buffer) + BufferOffset, &MergedDatum,
+ memcpy (((char *) Buffer) + BufferOffset, &MergedDatum,
ACPI_MIN(ObjDesc->CommonField.AccessByteWidth,
BufferLength - BufferOffset));
@@ -926,7 +926,7 @@ AcpiExInsertIntoField (
* at Byte zero. All unused (upper) bytes of the
* buffer will be 0.
*/
- ACPI_MEMCPY ((char *) NewBuffer, (char *) Buffer, BufferLength);
+ memcpy ((char *) NewBuffer, (char *) Buffer, BufferLength);
Buffer = NewBuffer;
BufferLength = RequiredLength;
}
@@ -969,7 +969,7 @@ AcpiExInsertIntoField (
/* Get initial Datum from the input buffer */
- ACPI_MEMCPY (&RawDatum, Buffer,
+ memcpy (&RawDatum, Buffer,
ACPI_MIN(ObjDesc->CommonField.AccessByteWidth,
BufferLength - BufferOffset));
@@ -1021,7 +1021,7 @@ AcpiExInsertIntoField (
/* Get the next input datum from the buffer */
BufferOffset += ObjDesc->CommonField.AccessByteWidth;
- ACPI_MEMCPY (&RawDatum, ((char *) Buffer) + BufferOffset,
+ memcpy (&RawDatum, ((char *) Buffer) + BufferOffset,
ACPI_MIN(ObjDesc->CommonField.AccessByteWidth,
BufferLength - BufferOffset));
diff --git a/sys/contrib/dev/acpica/components/executer/exmisc.c b/sys/contrib/dev/acpica/components/executer/exmisc.c
index d4e1a3b..df02e03 100644
--- a/sys/contrib/dev/acpica/components/executer/exmisc.c
+++ b/sys/contrib/dev/acpica/components/executer/exmisc.c
@@ -225,8 +225,8 @@ AcpiExConcatTemplate (
* EndTag descriptor is copied from Operand1.
*/
NewBuf = ReturnDesc->Buffer.Pointer;
- ACPI_MEMCPY (NewBuf, Operand0->Buffer.Pointer, Length0);
- ACPI_MEMCPY (NewBuf + Length0, Operand1->Buffer.Pointer, Length1);
+ memcpy (NewBuf, Operand0->Buffer.Pointer, Length0);
+ memcpy (NewBuf + Length0, Operand1->Buffer.Pointer, Length1);
/* Insert EndTag and set the checksum to zero, means "ignore checksum" */
@@ -340,12 +340,12 @@ AcpiExDoConcatenate (
/* Copy the first integer, LSB first */
- ACPI_MEMCPY (NewBuf, &Operand0->Integer.Value,
+ memcpy (NewBuf, &Operand0->Integer.Value,
AcpiGbl_IntegerByteWidth);
/* Copy the second integer (LSB first) after the first */
- ACPI_MEMCPY (NewBuf + AcpiGbl_IntegerByteWidth,
+ memcpy (NewBuf + AcpiGbl_IntegerByteWidth,
&LocalOperand1->Integer.Value,
AcpiGbl_IntegerByteWidth);
break;
@@ -367,8 +367,8 @@ AcpiExDoConcatenate (
/* Concatenate the strings */
- ACPI_STRCPY (NewBuf, Operand0->String.Pointer);
- ACPI_STRCPY (NewBuf + Operand0->String.Length,
+ strcpy (NewBuf, Operand0->String.Pointer);
+ strcpy (NewBuf + Operand0->String.Length,
LocalOperand1->String.Pointer);
break;
@@ -389,9 +389,9 @@ AcpiExDoConcatenate (
/* Concatenate the buffers */
- ACPI_MEMCPY (NewBuf, Operand0->Buffer.Pointer,
+ memcpy (NewBuf, Operand0->Buffer.Pointer,
Operand0->Buffer.Length);
- ACPI_MEMCPY (NewBuf + Operand0->Buffer.Length,
+ memcpy (NewBuf + Operand0->Buffer.Length,
LocalOperand1->Buffer.Pointer,
LocalOperand1->Buffer.Length);
break;
@@ -712,7 +712,7 @@ AcpiExDoLogicalOp (
/* Lexicographic compare: compare the data bytes */
- Compare = ACPI_MEMCMP (Operand0->Buffer.Pointer,
+ Compare = memcmp (Operand0->Buffer.Pointer,
LocalOperand1->Buffer.Pointer,
(Length0 > Length1) ? Length1 : Length0);
diff --git a/sys/contrib/dev/acpica/components/executer/exnames.c b/sys/contrib/dev/acpica/components/executer/exnames.c
index b213165..a6c9e6b 100644
--- a/sys/contrib/dev/acpica/components/executer/exnames.c
+++ b/sys/contrib/dev/acpica/components/executer/exnames.c
@@ -221,7 +221,7 @@ AcpiExNameSegment (
if (NameString)
{
- ACPI_STRCAT (NameString, CharBuf);
+ strcat (NameString, CharBuf);
ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
"Appended to - %s\n", NameString));
}
diff --git a/sys/contrib/dev/acpica/components/executer/exoparg2.c b/sys/contrib/dev/acpica/components/executer/exoparg2.c
index da1eb6c..e11c0b3 100644
--- a/sys/contrib/dev/acpica/components/executer/exoparg2.c
+++ b/sys/contrib/dev/acpica/components/executer/exoparg2.c
@@ -368,7 +368,7 @@ AcpiExOpcode_2A_1T_1R (
* Copy the raw buffer data with no transform.
* (NULL terminated already)
*/
- ACPI_MEMCPY (ReturnDesc->String.Pointer,
+ memcpy (ReturnDesc->String.Pointer,
Operand[0]->Buffer.Pointer, Length);
break;
@@ -412,6 +412,8 @@ AcpiExOpcode_2A_1T_1R (
}
ReturnDesc->Reference.TargetType = ACPI_TYPE_BUFFER_FIELD;
+ ReturnDesc->Reference.IndexPointer =
+ &(Operand[0]->Buffer.Pointer [Index]);
break;
case ACPI_TYPE_BUFFER:
@@ -423,6 +425,8 @@ AcpiExOpcode_2A_1T_1R (
}
ReturnDesc->Reference.TargetType = ACPI_TYPE_BUFFER_FIELD;
+ ReturnDesc->Reference.IndexPointer =
+ &(Operand[0]->Buffer.Pointer [Index]);
break;
case ACPI_TYPE_PACKAGE:
@@ -434,7 +438,8 @@ AcpiExOpcode_2A_1T_1R (
}
ReturnDesc->Reference.TargetType = ACPI_TYPE_PACKAGE;
- ReturnDesc->Reference.Where = &Operand[0]->Package.Elements [Index];
+ ReturnDesc->Reference.Where =
+ &Operand[0]->Package.Elements [Index];
break;
default:
diff --git a/sys/contrib/dev/acpica/components/executer/exoparg3.c b/sys/contrib/dev/acpica/components/executer/exoparg3.c
index da873c3..54636bc 100644
--- a/sys/contrib/dev/acpica/components/executer/exoparg3.c
+++ b/sys/contrib/dev/acpica/components/executer/exoparg3.c
@@ -261,7 +261,7 @@ AcpiExOpcode_3A_1T_1R (
{
/* We have a buffer, copy the portion requested */
- ACPI_MEMCPY (Buffer, Operand[0]->String.Pointer + Index,
+ memcpy (Buffer, Operand[0]->String.Pointer + Index,
Length);
}
diff --git a/sys/contrib/dev/acpica/components/executer/exregion.c b/sys/contrib/dev/acpica/components/executer/exregion.c
index 59b4612..6bfdf7b 100644
--- a/sys/contrib/dev/acpica/components/executer/exregion.c
+++ b/sys/contrib/dev/acpica/components/executer/exregion.c
@@ -558,13 +558,13 @@ AcpiExDataTableSpaceHandler (
{
case ACPI_READ:
- ACPI_MEMCPY (ACPI_CAST_PTR (char, Value), ACPI_PHYSADDR_TO_PTR (Address),
+ memcpy (ACPI_CAST_PTR (char, Value), ACPI_PHYSADDR_TO_PTR (Address),
ACPI_DIV_8 (BitWidth));
break;
case ACPI_WRITE:
- ACPI_MEMCPY (ACPI_PHYSADDR_TO_PTR (Address), ACPI_CAST_PTR (char, Value),
+ memcpy (ACPI_PHYSADDR_TO_PTR (Address), ACPI_CAST_PTR (char, Value),
ACPI_DIV_8 (BitWidth));
break;
diff --git a/sys/contrib/dev/acpica/components/executer/exstorob.c b/sys/contrib/dev/acpica/components/executer/exstorob.c
index c238310..683bfce 100644
--- a/sys/contrib/dev/acpica/components/executer/exstorob.c
+++ b/sys/contrib/dev/acpica/components/executer/exstorob.c
@@ -109,8 +109,8 @@ AcpiExStoreBufferToBuffer (
{
/* Clear existing buffer and copy in the new one */
- ACPI_MEMSET (TargetDesc->Buffer.Pointer, 0, TargetDesc->Buffer.Length);
- ACPI_MEMCPY (TargetDesc->Buffer.Pointer, Buffer, Length);
+ memset (TargetDesc->Buffer.Pointer, 0, TargetDesc->Buffer.Length);
+ memcpy (TargetDesc->Buffer.Pointer, Buffer, Length);
#ifdef ACPI_OBSOLETE_BEHAVIOR
/*
@@ -139,7 +139,7 @@ AcpiExStoreBufferToBuffer (
{
/* Truncate the source, copy only what will fit */
- ACPI_MEMCPY (TargetDesc->Buffer.Pointer, Buffer,
+ memcpy (TargetDesc->Buffer.Pointer, Buffer,
TargetDesc->Buffer.Length);
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
@@ -203,9 +203,9 @@ AcpiExStoreStringToString (
* String will fit in existing non-static buffer.
* Clear old string and copy in the new one
*/
- ACPI_MEMSET (TargetDesc->String.Pointer, 0,
+ memset (TargetDesc->String.Pointer, 0,
(ACPI_SIZE) TargetDesc->String.Length + 1);
- ACPI_MEMCPY (TargetDesc->String.Pointer, Buffer, Length);
+ memcpy (TargetDesc->String.Pointer, Buffer, Length);
}
else
{
@@ -229,7 +229,7 @@ AcpiExStoreStringToString (
}
TargetDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER;
- ACPI_MEMCPY (TargetDesc->String.Pointer, Buffer, Length);
+ memcpy (TargetDesc->String.Pointer, Buffer, Length);
}
/* Set the new target length */
diff --git a/sys/contrib/dev/acpica/components/executer/exutils.c b/sys/contrib/dev/acpica/components/executer/exutils.c
index a55b171..1cd60fa 100644
--- a/sys/contrib/dev/acpica/components/executer/exutils.c
+++ b/sys/contrib/dev/acpica/components/executer/exutils.c
@@ -433,6 +433,43 @@ AcpiExIntegerToString (
/*******************************************************************************
*
+ * FUNCTION: AcpiExPciClsToString
+ *
+ * PARAMETERS: OutString - Where to put the converted string (7 bytes)
+ * PARAMETERS: ClassCode - PCI class code to be converted (3 bytes)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert 3-bytes PCI class code to string representation.
+ * Return buffer must be large enough to hold the string. The
+ * string returned is always exactly of length
+ * ACPI_PCICLS_STRING_SIZE (includes null terminator).
+ *
+ ******************************************************************************/
+
+void
+AcpiExPciClsToString (
+ char *OutString,
+ UINT8 ClassCode[3])
+{
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* All 3 bytes are hexadecimal */
+
+ OutString[0] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[0], 4);
+ OutString[1] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[0], 0);
+ OutString[2] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[1], 4);
+ OutString[3] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[1], 0);
+ OutString[4] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[2], 4);
+ OutString[5] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[2], 0);
+ OutString[6] = 0;
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiIsValidSpaceId
*
* PARAMETERS: SpaceId - ID to be validated
diff --git a/sys/contrib/dev/acpica/components/hardware/hwgpe.c b/sys/contrib/dev/acpica/components/hardware/hwgpe.c
index 093ba80..c293bef 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwgpe.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwgpe.c
@@ -97,6 +97,8 @@ AcpiHwGetGpeRegisterBit (
* RETURN: Status
*
* DESCRIPTION: Enable or disable a single GPE in the parent enable register.
+ * The EnableMask field of the involved GPE register must be
+ * updated by the caller if necessary.
*
******************************************************************************/
@@ -133,7 +135,7 @@ AcpiHwLowSetGpe (
/* Set or clear just the bit that corresponds to this GPE */
RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
- switch (Action & ~ACPI_GPE_SAVE_MASK)
+ switch (Action)
{
case ACPI_GPE_CONDITIONAL_ENABLE:
@@ -165,10 +167,6 @@ AcpiHwLowSetGpe (
/* Write the updated enable mask */
Status = AcpiHwWrite (EnableMask, &GpeRegisterInfo->EnableAddress);
- if (ACPI_SUCCESS (Status) && (Action & ACPI_GPE_SAVE_MASK))
- {
- GpeRegisterInfo->EnableMask = (UINT8) EnableMask;
- }
return (Status);
}
@@ -334,11 +332,8 @@ AcpiHwGpeEnableWrite (
ACPI_STATUS Status;
+ GpeRegisterInfo->EnableMask = EnableMask;
Status = AcpiHwWrite (EnableMask, &GpeRegisterInfo->EnableAddress);
- if (ACPI_SUCCESS (Status))
- {
- GpeRegisterInfo->EnableMask = EnableMask;
- }
return (Status);
}
diff --git a/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c b/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c
index 8d5ba97..5610398 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c
@@ -51,6 +51,14 @@
/* Local prototypes */
+#if (!ACPI_REDUCED_HARDWARE)
+static ACPI_STATUS
+AcpiHwSetFirmwareWakingVector (
+ ACPI_TABLE_FACS *Facs,
+ ACPI_PHYSICAL_ADDRESS PhysicalAddress,
+ ACPI_PHYSICAL_ADDRESS PhysicalAddress64);
+#endif
+
static ACPI_STATUS
AcpiHwSleepDispatch (
UINT8 SleepState,
@@ -77,29 +85,33 @@ static ACPI_SLEEP_FUNCTIONS AcpiSleepDispatch[] =
/*
* These functions are removed for the ACPI_REDUCED_HARDWARE case:
* AcpiSetFirmwareWakingVector
- * AcpiSetFirmwareWakingVector64
* AcpiEnterSleepStateS4bios
*/
#if (!ACPI_REDUCED_HARDWARE)
/*******************************************************************************
*
- * FUNCTION: AcpiSetFirmwareWakingVector
+ * FUNCTION: AcpiHwSetFirmwareWakingVector
*
- * PARAMETERS: PhysicalAddress - 32-bit physical address of ACPI real mode
- * entry point.
+ * PARAMETERS: Facs - Pointer to FACS table
+ * PhysicalAddress - 32-bit physical address of ACPI real mode
+ * entry point
+ * PhysicalAddress64 - 64-bit physical address of ACPI protected
+ * entry point
*
* RETURN: Status
*
- * DESCRIPTION: Sets the 32-bit FirmwareWakingVector field of the FACS
+ * DESCRIPTION: Sets the FirmwareWakingVector fields of the FACS
*
******************************************************************************/
-ACPI_STATUS
-AcpiSetFirmwareWakingVector (
- UINT32 PhysicalAddress)
+static ACPI_STATUS
+AcpiHwSetFirmwareWakingVector (
+ ACPI_TABLE_FACS *Facs,
+ ACPI_PHYSICAL_ADDRESS PhysicalAddress,
+ ACPI_PHYSICAL_ADDRESS PhysicalAddress64)
{
- ACPI_FUNCTION_TRACE (AcpiSetFirmwareWakingVector);
+ ACPI_FUNCTION_TRACE (AcpiHwSetFirmwareWakingVector);
/*
@@ -112,60 +124,73 @@ AcpiSetFirmwareWakingVector (
/* Set the 32-bit vector */
- AcpiGbl_FACS->FirmwareWakingVector = PhysicalAddress;
+ Facs->FirmwareWakingVector = (UINT32) PhysicalAddress;
- /* Clear the 64-bit vector if it exists */
-
- if ((AcpiGbl_FACS->Length > 32) && (AcpiGbl_FACS->Version >= 1))
+ if (Facs->Length > 32)
{
- AcpiGbl_FACS->XFirmwareWakingVector = 0;
+ if (Facs->Version >= 1)
+ {
+ /* Set the 64-bit vector */
+
+ Facs->XFirmwareWakingVector = PhysicalAddress64;
+ }
+ else
+ {
+ /* Clear the 64-bit vector if it exists */
+
+ Facs->XFirmwareWakingVector = 0;
+ }
}
return_ACPI_STATUS (AE_OK);
}
-ACPI_EXPORT_SYMBOL (AcpiSetFirmwareWakingVector)
-
-#if ACPI_MACHINE_WIDTH == 64
/*******************************************************************************
*
- * FUNCTION: AcpiSetFirmwareWakingVector64
+ * FUNCTION: AcpiSetFirmwareWakingVector
*
- * PARAMETERS: PhysicalAddress - 64-bit physical address of ACPI protected
- * mode entry point.
+ * PARAMETERS: PhysicalAddress - 32-bit physical address of ACPI real mode
+ * entry point
+ * PhysicalAddress64 - 64-bit physical address of ACPI protected
+ * entry point
*
* RETURN: Status
*
- * DESCRIPTION: Sets the 64-bit X_FirmwareWakingVector field of the FACS, if
- * it exists in the table. This function is intended for use with
- * 64-bit host operating systems.
+ * DESCRIPTION: Sets the FirmwareWakingVector fields of the FACS
*
******************************************************************************/
ACPI_STATUS
-AcpiSetFirmwareWakingVector64 (
- UINT64 PhysicalAddress)
+AcpiSetFirmwareWakingVector (
+ ACPI_PHYSICAL_ADDRESS PhysicalAddress,
+ ACPI_PHYSICAL_ADDRESS PhysicalAddress64)
{
- ACPI_FUNCTION_TRACE (AcpiSetFirmwareWakingVector64);
+ ACPI_FUNCTION_TRACE (AcpiSetFirmwareWakingVector);
- /* Determine if the 64-bit vector actually exists */
+ /* If Hardware Reduced flag is set, there is no FACS */
- if ((AcpiGbl_FACS->Length <= 32) || (AcpiGbl_FACS->Version < 1))
+ if (AcpiGbl_ReducedHardware)
{
- return_ACPI_STATUS (AE_NOT_EXIST);
+ return_ACPI_STATUS (AE_OK);
}
- /* Clear 32-bit vector, set the 64-bit X_ vector */
+ if (AcpiGbl_Facs32)
+ {
+ (void) AcpiHwSetFirmwareWakingVector (AcpiGbl_Facs32,
+ PhysicalAddress, PhysicalAddress64);
+ }
+ if (AcpiGbl_Facs64)
+ {
+ (void) AcpiHwSetFirmwareWakingVector (AcpiGbl_Facs64,
+ PhysicalAddress, PhysicalAddress64);
+ }
- AcpiGbl_FACS->FirmwareWakingVector = 0;
- AcpiGbl_FACS->XFirmwareWakingVector = PhysicalAddress;
return_ACPI_STATUS (AE_OK);
}
-ACPI_EXPORT_SYMBOL (AcpiSetFirmwareWakingVector64)
-#endif
+ACPI_EXPORT_SYMBOL (AcpiSetFirmwareWakingVector)
/*******************************************************************************
diff --git a/sys/contrib/dev/acpica/components/namespace/nsaccess.c b/sys/contrib/dev/acpica/components/namespace/nsaccess.c
index 667b5af..46a64f5 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsaccess.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsaccess.c
@@ -111,7 +111,7 @@ AcpiNsRootInitialize (
{
/* _OSI is optional for now, will be permanent later */
- if (!ACPI_STRCMP (InitVal->Name, "_OSI") && !AcpiGbl_CreateOsiMethod)
+ if (!strcmp (InitVal->Name, "_OSI") && !AcpiGbl_CreateOsiMethod)
{
continue;
}
@@ -191,7 +191,7 @@ AcpiNsRootInitialize (
/* Build an object around the static string */
- ObjDesc->String.Length = (UINT32) ACPI_STRLEN (Val);
+ ObjDesc->String.Length = (UINT32) strlen (Val);
ObjDesc->String.Pointer = Val;
ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER;
break;
@@ -212,7 +212,7 @@ AcpiNsRootInitialize (
/* Special case for ACPI Global Lock */
- if (ACPI_STRCMP (InitVal->Name, "_GL_") == 0)
+ if (strcmp (InitVal->Name, "_GL_") == 0)
{
AcpiGbl_GlobalLockMutex = ObjDesc;
@@ -319,7 +319,9 @@ AcpiNsLookup (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
- LocalFlags = Flags & ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_SEARCH_PARENT);
+ LocalFlags = Flags &
+ ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_OVERRIDE_IF_FOUND |
+ ACPI_NS_SEARCH_PARENT);
*ReturnNode = ACPI_ENTRY_NOT_FOUND;
AcpiGbl_NsLookupCount++;
@@ -571,6 +573,13 @@ AcpiNsLookup (
{
LocalFlags |= ACPI_NS_ERROR_IF_FOUND;
}
+
+ /* Set override flag according to caller */
+
+ if (Flags & ACPI_NS_OVERRIDE_IF_FOUND)
+ {
+ LocalFlags |= ACPI_NS_OVERRIDE_IF_FOUND;
+ }
}
/* Extract one ACPI name from the front of the pathname */
diff --git a/sys/contrib/dev/acpica/components/namespace/nsconvert.c b/sys/contrib/dev/acpica/components/namespace/nsconvert.c
index 091c5cc..99883c2 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsconvert.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsconvert.c
@@ -202,7 +202,7 @@ AcpiNsConvertToString (
* Copy the raw buffer data with no transform. String is already NULL
* terminated at Length+1.
*/
- ACPI_MEMCPY (NewObject->String.Pointer,
+ memcpy (NewObject->String.Pointer,
OriginalObject->Buffer.Pointer, Length);
break;
@@ -269,7 +269,7 @@ AcpiNsConvertToBuffer (
return (AE_NO_MEMORY);
}
- ACPI_MEMCPY (NewObject->Buffer.Pointer,
+ memcpy (NewObject->Buffer.Pointer,
OriginalObject->String.Pointer, OriginalObject->String.Length);
break;
diff --git a/sys/contrib/dev/acpica/components/namespace/nsdump.c b/sys/contrib/dev/acpica/components/namespace/nsdump.c
index 77fb279..f3f3fed 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsdump.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsdump.c
@@ -122,7 +122,7 @@ AcpiNsPrintPathname (
{
for (i = 0; i < 4; i++)
{
- ACPI_IS_PRINT (Pathname[i]) ?
+ isprint ((int) Pathname[i]) ?
AcpiOsPrintf ("%c", Pathname[i]) :
AcpiOsPrintf ("?");
}
diff --git a/sys/contrib/dev/acpica/components/namespace/nseval.c b/sys/contrib/dev/acpica/components/namespace/nseval.c
index ac1d9a9..fb39171 100644
--- a/sys/contrib/dev/acpica/components/namespace/nseval.c
+++ b/sys/contrib/dev/acpica/components/namespace/nseval.c
@@ -63,15 +63,14 @@ AcpiNsExecModuleCode (
*
* FUNCTION: AcpiNsEvaluate
*
- * PARAMETERS: Info - Evaluation info block, contains:
+ * PARAMETERS: Info - Evaluation info block, contains these fields
+ * and more:
* PrefixNode - Prefix or Method/Object Node to execute
* RelativePath - Name of method to execute, If NULL, the
* Node is the object to execute
* Parameters - List of parameters to pass to the method,
* terminated by NULL. Params itself may be
* NULL if no parameters are being passed.
- * ReturnObject - Where to put method's return value (if
- * any). If NULL, no value is returned.
* ParameterType - Type of Parameter list
* ReturnObject - Where to put method's return value (if
* any). If NULL, no value is returned.
@@ -463,7 +462,7 @@ AcpiNsExecModuleCode (
/* Initialize the evaluation information block */
- ACPI_MEMSET (Info, 0, sizeof (ACPI_EVALUATE_INFO));
+ memset (Info, 0, sizeof (ACPI_EVALUATE_INFO));
Info->PrefixNode = ParentNode;
/*
diff --git a/sys/contrib/dev/acpica/components/namespace/nsinit.c b/sys/contrib/dev/acpica/components/namespace/nsinit.c
index 847bf72..cbfc4a6f 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsinit.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsinit.c
@@ -105,7 +105,7 @@ AcpiNsInitializeObjects (
/* Set all init info to zero */
- ACPI_MEMSET (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));
+ memset (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));
/* Walk entire namespace from the supplied root */
@@ -614,7 +614,7 @@ AcpiNsInitOneDevice (
ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__INI));
- ACPI_MEMSET (Info, 0, sizeof (ACPI_EVALUATE_INFO));
+ memset (Info, 0, sizeof (ACPI_EVALUATE_INFO));
Info->PrefixNode = DeviceNode;
Info->RelativePathname = METHOD_NAME__INI;
Info->Parameters = NULL;
diff --git a/sys/contrib/dev/acpica/components/namespace/nsparse.c b/sys/contrib/dev/acpica/components/namespace/nsparse.c
index 0f87fa1..7c6d29a 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsparse.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsparse.c
@@ -129,6 +129,14 @@ AcpiNsOneCompleteParse (
AmlStart, AmlLength, NULL, (UINT8) PassNumber);
}
+ /* Found OSDT table, enable the namespace override feature */
+
+ if (ACPI_COMPARE_NAME(Table->Signature, ACPI_SIG_OSDT) &&
+ PassNumber == ACPI_IMODE_LOAD_PASS1)
+ {
+ WalkState->NamespaceOverride = TRUE;
+ }
+
if (ACPI_FAILURE (Status))
{
AcpiDsDeleteWalkState (WalkState);
diff --git a/sys/contrib/dev/acpica/components/namespace/nsrepair2.c b/sys/contrib/dev/acpica/components/namespace/nsrepair2.c
index 410b009..24ac8b4 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsrepair2.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsrepair2.c
@@ -637,7 +637,7 @@ AcpiNsRepair_HID (
*/
for (Dest = NewString->String.Pointer; *Source; Dest++, Source++)
{
- *Dest = (char) ACPI_TOUPPER (*Source);
+ *Dest = (char) toupper ((int) *Source);
}
AcpiUtRemoveReference (ReturnObject);
diff --git a/sys/contrib/dev/acpica/components/namespace/nssearch.c b/sys/contrib/dev/acpica/components/namespace/nssearch.c
index 9f24f1c..a1e6d1a 100644
--- a/sys/contrib/dev/acpica/components/namespace/nssearch.c
+++ b/sys/contrib/dev/acpica/components/namespace/nssearch.c
@@ -338,10 +338,42 @@ AcpiNsSearchAndEnter (
* If we found it AND the request specifies that a find is an error,
* return the error
*/
- if ((Status == AE_OK) &&
- (Flags & ACPI_NS_ERROR_IF_FOUND))
+ if (Status == AE_OK)
{
- Status = AE_ALREADY_EXISTS;
+ /* The node was found in the namespace */
+
+ /*
+ * If the namespace override feature is enabled for this node,
+ * delete any existing attached sub-object and make the node
+ * look like a new node that is owned by the override table.
+ */
+ if (Flags & ACPI_NS_OVERRIDE_IF_FOUND)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+ "Namespace override: %4.4s pass %u type %X Owner %X\n",
+ ACPI_CAST_PTR(char, &TargetName), InterpreterMode,
+ (*ReturnNode)->Type, WalkState->OwnerId));
+
+ AcpiNsDeleteChildren (*ReturnNode);
+ if (AcpiGbl_RuntimeNamespaceOverride)
+ {
+ AcpiUtRemoveReference ((*ReturnNode)->Object);
+ (*ReturnNode)->Object = NULL;
+ (*ReturnNode)->OwnerId = WalkState->OwnerId;
+ }
+ else
+ {
+ AcpiNsRemoveNode (*ReturnNode);
+ *ReturnNode = ACPI_ENTRY_NOT_FOUND;
+ }
+ }
+
+ /* Return an error if we don't expect to find the object */
+
+ else if (Flags & ACPI_NS_ERROR_IF_FOUND)
+ {
+ Status = AE_ALREADY_EXISTS;
+ }
}
#ifdef ACPI_ASL_COMPILER
diff --git a/sys/contrib/dev/acpica/components/namespace/nsutils.c b/sys/contrib/dev/acpica/components/namespace/nsutils.c
index d7320a6..4a59784 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsutils.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsutils.c
@@ -347,7 +347,7 @@ AcpiNsBuildInternalName (
{
/* Convert the character to uppercase and save it */
- Result[i] = (char) ACPI_TOUPPER ((int) *ExternalName);
+ Result[i] = (char) toupper ((int) *ExternalName);
ExternalName++;
}
}
diff --git a/sys/contrib/dev/acpica/components/namespace/nsxfeval.c b/sys/contrib/dev/acpica/components/namespace/nsxfeval.c
index 93226ef..9b4d2db 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsxfeval.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsxfeval.c
@@ -758,7 +758,7 @@ AcpiNsGetDeviceCallback (
return (AE_CTRL_DEPTH);
}
- NoMatch = ACPI_STRCMP (Hid->String, Info->Hid);
+ NoMatch = strcmp (Hid->String, Info->Hid);
ACPI_FREE (Hid);
if (NoMatch)
@@ -782,7 +782,7 @@ AcpiNsGetDeviceCallback (
Found = FALSE;
for (i = 0; i < Cid->Count; i++)
{
- if (ACPI_STRCMP (Cid->Ids[i].String, Info->Hid) == 0)
+ if (strcmp (Cid->Ids[i].String, Info->Hid) == 0)
{
/* Found a matching CID */
diff --git a/sys/contrib/dev/acpica/components/namespace/nsxfname.c b/sys/contrib/dev/acpica/components/namespace/nsxfname.c
index 804ea94..7ee3fdd 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsxfname.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsxfname.c
@@ -126,7 +126,7 @@ AcpiGetHandle (
/* Special case for root-only, since we can't search for it */
- if (!ACPI_STRCMP (Pathname, ACPI_NS_ROOT_PATH))
+ if (!strcmp (Pathname, ACPI_NS_ROOT_PATH))
{
*RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, AcpiGbl_RootNode);
return (AE_OK);
@@ -271,7 +271,7 @@ AcpiNsCopyDeviceId (
/* Copy actual string and return a pointer to the next string area */
- ACPI_MEMCPY (StringArea, Source->String, Source->Length);
+ memcpy (StringArea, Source->String, Source->Length);
return (StringArea + Source->Length);
}
@@ -290,7 +290,7 @@ AcpiNsCopyDeviceId (
* control methods (Such as in the case of a device.)
*
* For Device and Processor objects, run the Device _HID, _UID, _CID, _SUB,
- * _STA, _ADR, _SxW, and _SxD methods.
+ * _CLS, _STA, _ADR, _SxW, and _SxD methods.
*
* Note: Allocates the return buffer, must be freed by the caller.
*
@@ -307,11 +307,12 @@ AcpiGetObjectInfo (
ACPI_PNP_DEVICE_ID *Hid = NULL;
ACPI_PNP_DEVICE_ID *Uid = NULL;
ACPI_PNP_DEVICE_ID *Sub = NULL;
+ ACPI_PNP_DEVICE_ID *Cls = NULL;
char *NextIdString;
ACPI_OBJECT_TYPE Type;
ACPI_NAME Name;
UINT8 ParamCount= 0;
- UINT8 Valid = 0;
+ UINT16 Valid = 0;
UINT32 InfoSize;
UINT32 i;
ACPI_STATUS Status;
@@ -359,7 +360,7 @@ AcpiGetObjectInfo (
{
/*
* Get extra info for ACPI Device/Processor objects only:
- * Run the Device _HID, _UID, _SUB, and _CID methods.
+ * Run the Device _HID, _UID, _SUB, _CID, and _CLS methods.
*
* Note: none of these methods are required, so they may or may
* not be present for this device. The Info->Valid bitfield is used
@@ -403,6 +404,15 @@ AcpiGetObjectInfo (
InfoSize += (CidList->ListSize - sizeof (ACPI_PNP_DEVICE_ID_LIST));
Valid |= ACPI_VALID_CID;
}
+
+ /* Execute the Device._CLS method */
+
+ Status = AcpiUtExecute_CLS (Node, &Cls);
+ if (ACPI_SUCCESS (Status))
+ {
+ InfoSize += Cls->Length;
+ Valid |= ACPI_VALID_CLS;
+ }
}
/*
@@ -534,6 +544,12 @@ AcpiGetObjectInfo (
}
}
+ if (Cls)
+ {
+ NextIdString = AcpiNsCopyDeviceId (&Info->ClassCode,
+ Cls, NextIdString);
+ }
+
/* Copy the fixed-length data */
Info->InfoSize = InfoSize;
@@ -563,6 +579,10 @@ Cleanup:
{
ACPI_FREE (CidList);
}
+ if (Cls)
+ {
+ ACPI_FREE (Cls);
+ }
return (Status);
}
@@ -684,7 +704,7 @@ AcpiInstallMethod (
/* Copy the method AML to the local buffer */
- ACPI_MEMCPY (AmlBuffer, AmlStart, AmlLength);
+ memcpy (AmlBuffer, AmlStart, AmlLength);
/* Initialize the method object with the new method's information */
diff --git a/sys/contrib/dev/acpica/components/parser/psutils.c b/sys/contrib/dev/acpica/components/parser/psutils.c
index 1a269a6..8581a94 100644
--- a/sys/contrib/dev/acpica/components/parser/psutils.c
+++ b/sys/contrib/dev/acpica/components/parser/psutils.c
@@ -104,7 +104,7 @@ AcpiPsInitOp (
Op->Common.DescriptorType = ACPI_DESC_TYPE_PARSER;
Op->Common.AmlOpcode = Opcode;
- ACPI_DISASM_ONLY_MEMBERS (ACPI_STRNCPY (Op->Common.AmlOpName,
+ ACPI_DISASM_ONLY_MEMBERS (strncpy (Op->Common.AmlOpName,
(AcpiPsGetOpcodeInfo (Opcode))->Name,
sizeof (Op->Common.AmlOpName)));
}
diff --git a/sys/contrib/dev/acpica/components/resources/rscreate.c b/sys/contrib/dev/acpica/components/resources/rscreate.c
index c646129..6225590 100644
--- a/sys/contrib/dev/acpica/components/resources/rscreate.c
+++ b/sys/contrib/dev/acpica/components/resources/rscreate.c
@@ -374,12 +374,12 @@ AcpiRsCreatePciRoutingTable (
/* +1 to include null terminator */
- UserPrt->Length += (UINT32) ACPI_STRLEN (UserPrt->Source) + 1;
+ UserPrt->Length += (UINT32) strlen (UserPrt->Source) + 1;
break;
case ACPI_TYPE_STRING:
- ACPI_STRCPY (UserPrt->Source, ObjDesc->String.Pointer);
+ strcpy (UserPrt->Source, ObjDesc->String.Pointer);
/*
* Add to the Length field the length of the string
diff --git a/sys/contrib/dev/acpica/components/resources/rsmisc.c b/sys/contrib/dev/acpica/components/resources/rsmisc.c
index bc5b803..cef8000 100644
--- a/sys/contrib/dev/acpica/components/resources/rsmisc.c
+++ b/sys/contrib/dev/acpica/components/resources/rsmisc.c
@@ -130,7 +130,7 @@ AcpiRsConvertAmlToResource (
/*
* Get the resource type and the initial (minimum) length
*/
- ACPI_MEMSET (Resource, 0, INIT_RESOURCE_LENGTH (Info));
+ memset (Resource, 0, INIT_RESOURCE_LENGTH (Info));
Resource->Type = INIT_RESOURCE_TYPE (Info);
Resource->Length = INIT_RESOURCE_LENGTH (Info);
break;
@@ -326,13 +326,13 @@ AcpiRsConvertAmlToResource (
case ACPI_RSC_SET8:
- ACPI_MEMSET (Destination, Info->AmlOffset, Info->Value);
+ memset (Destination, Info->AmlOffset, Info->Value);
break;
case ACPI_RSC_DATA8:
Target = ACPI_ADD_PTR (char, Resource, Info->Value);
- ACPI_MEMCPY (Destination, Source, ACPI_GET16 (Target));
+ memcpy (Destination, Source, ACPI_GET16 (Target));
break;
case ACPI_RSC_ADDRESS:
@@ -505,7 +505,7 @@ AcpiRsConvertResourceToAml (
{
case ACPI_RSC_INITSET:
- ACPI_MEMSET (Aml, 0, INIT_RESOURCE_LENGTH (Info));
+ memset (Aml, 0, INIT_RESOURCE_LENGTH (Info));
AmlLength = INIT_RESOURCE_LENGTH (Info);
AcpiRsSetResourceHeader (INIT_RESOURCE_TYPE (Info), AmlLength, Aml);
break;
diff --git a/sys/contrib/dev/acpica/components/resources/rsutils.c b/sys/contrib/dev/acpica/components/resources/rsutils.c
index c0e7b78..1bab925 100644
--- a/sys/contrib/dev/acpica/components/resources/rsutils.c
+++ b/sys/contrib/dev/acpica/components/resources/rsutils.c
@@ -174,7 +174,7 @@ AcpiRsMoveData (
case ACPI_RSC_MOVE_SERIAL_VEN:
case ACPI_RSC_MOVE_SERIAL_RES:
- ACPI_MEMCPY (Destination, Source, ItemCount);
+ memcpy (Destination, Source, ItemCount);
return;
/*
@@ -408,11 +408,11 @@ AcpiRsGetResourceSource (
*
* Zero the entire area of the buffer.
*/
- TotalLength = (UINT32) ACPI_STRLEN (
+ TotalLength = (UINT32) strlen (
ACPI_CAST_PTR (char, &AmlResourceSource[1])) + 1;
TotalLength = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (TotalLength);
- ACPI_MEMSET (ResourceSource->StringPtr, 0, TotalLength);
+ memset (ResourceSource->StringPtr, 0, TotalLength);
/* Copy the ResourceSource string to the destination */
@@ -477,7 +477,7 @@ AcpiRsSetResourceSource (
/* Copy the ResourceSource string */
- ACPI_STRCPY (ACPI_CAST_PTR (char, &AmlResourceSource[1]),
+ strcpy (ACPI_CAST_PTR (char, &AmlResourceSource[1]),
ResourceSource->StringPtr);
/*
diff --git a/sys/contrib/dev/acpica/components/resources/rsxface.c b/sys/contrib/dev/acpica/components/resources/rsxface.c
index a477f20..66c26e1 100644
--- a/sys/contrib/dev/acpica/components/resources/rsxface.c
+++ b/sys/contrib/dev/acpica/components/resources/rsxface.c
@@ -447,7 +447,7 @@ AcpiResourceToAddress64 (
/* Simple copy for 64 bit source */
- ACPI_MEMCPY (Out, &Resource->Data, sizeof (ACPI_RESOURCE_ADDRESS64));
+ memcpy (Out, &Resource->Data, sizeof (ACPI_RESOURCE_ADDRESS64));
break;
default:
@@ -558,7 +558,7 @@ AcpiRsMatchVendorResource (
*/
if ((Vendor->ByteLength < (ACPI_UUID_LENGTH + 1)) ||
(Vendor->UuidSubtype != Info->Uuid->Subtype) ||
- (ACPI_MEMCMP (Vendor->Uuid, Info->Uuid->Data, ACPI_UUID_LENGTH)))
+ (memcmp (Vendor->Uuid, Info->Uuid->Data, ACPI_UUID_LENGTH)))
{
return (AE_OK);
}
@@ -574,7 +574,7 @@ AcpiRsMatchVendorResource (
/* Found the correct resource, copy and return it */
- ACPI_MEMCPY (Buffer->Pointer, Resource, Resource->Length);
+ memcpy (Buffer->Pointer, Resource, Resource->Length);
Buffer->Length = Resource->Length;
/* Found the desired descriptor, terminate resource walk */
diff --git a/sys/contrib/dev/acpica/components/tables/tbdata.c b/sys/contrib/dev/acpica/components/tables/tbdata.c
index 70bac2c..b44dec0 100644
--- a/sys/contrib/dev/acpica/components/tables/tbdata.c
+++ b/sys/contrib/dev/acpica/components/tables/tbdata.c
@@ -77,7 +77,7 @@ AcpiTbInitTableDescriptor (
* Initialize the table descriptor. Set the pointer to NULL, since the
* table is not fully mapped at this time.
*/
- ACPI_MEMSET (TableDesc, 0, sizeof (ACPI_TABLE_DESC));
+ memset (TableDesc, 0, sizeof (ACPI_TABLE_DESC));
TableDesc->Address = Address;
TableDesc->Length = Table->Length;
TableDesc->Flags = Flags;
@@ -511,7 +511,7 @@ AcpiTbResizeRootTableList (
if (AcpiGbl_RootTableList.Tables)
{
- ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables,
+ memcpy (Tables, AcpiGbl_RootTableList.Tables,
(ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC));
if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
diff --git a/sys/contrib/dev/acpica/components/tables/tbfadt.c b/sys/contrib/dev/acpica/components/tables/tbfadt.c
index f35e217..0917157 100644
--- a/sys/contrib/dev/acpica/components/tables/tbfadt.c
+++ b/sys/contrib/dev/acpica/components/tables/tbfadt.c
@@ -382,8 +382,16 @@ AcpiTbParseFadt (
if (!AcpiGbl_ReducedHardware)
{
- AcpiTbInstallFixedTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs,
- ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
+ if (AcpiGbl_FADT.Facs)
+ {
+ AcpiTbInstallFixedTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.Facs,
+ ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
+ }
+ if (AcpiGbl_FADT.XFacs)
+ {
+ AcpiTbInstallFixedTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs,
+ ACPI_SIG_FACS, ACPI_TABLE_INDEX_X_FACS);
+ }
}
}
@@ -425,11 +433,11 @@ AcpiTbCreateLocalFadt (
/* Clear the entire local FADT */
- ACPI_MEMSET (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT));
+ memset (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT));
/* Copy the original FADT, up to sizeof (ACPI_TABLE_FADT) */
- ACPI_MEMCPY (&AcpiGbl_FADT, Table,
+ memcpy (&AcpiGbl_FADT, Table,
ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT)));
/* Take a copy of the Hardware Reduced flag */
@@ -533,12 +541,9 @@ AcpiTbConvertFadt (
AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT);
/*
- * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary.
+ * Expand the 32-bit DSDT addresses to 64-bit as necessary.
* Later ACPICA code will always use the X 64-bit field.
*/
- AcpiGbl_FADT.XFacs = AcpiTbSelectAddress ("FACS",
- AcpiGbl_FADT.Facs, AcpiGbl_FADT.XFacs);
-
AcpiGbl_FADT.XDsdt = AcpiTbSelectAddress ("DSDT",
AcpiGbl_FADT.Dsdt, AcpiGbl_FADT.XDsdt);
diff --git a/sys/contrib/dev/acpica/components/tables/tbfind.c b/sys/contrib/dev/acpica/components/tables/tbfind.c
index 30a5750..e5c4cee 100644
--- a/sys/contrib/dev/acpica/components/tables/tbfind.c
+++ b/sys/contrib/dev/acpica/components/tables/tbfind.c
@@ -83,16 +83,16 @@ AcpiTbFindTable (
/* Normalize the input strings */
- ACPI_MEMSET (&Header, 0, sizeof (ACPI_TABLE_HEADER));
+ memset (&Header, 0, sizeof (ACPI_TABLE_HEADER));
ACPI_MOVE_NAME (Header.Signature, Signature);
- ACPI_STRNCPY (Header.OemId, OemId, ACPI_OEM_ID_SIZE);
- ACPI_STRNCPY (Header.OemTableId, OemTableId, ACPI_OEM_TABLE_ID_SIZE);
+ strncpy (Header.OemId, OemId, ACPI_OEM_ID_SIZE);
+ strncpy (Header.OemTableId, OemTableId, ACPI_OEM_TABLE_ID_SIZE);
/* Search for the table */
for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
{
- if (ACPI_MEMCMP (&(AcpiGbl_RootTableList.Tables[i].Signature),
+ if (memcmp (&(AcpiGbl_RootTableList.Tables[i].Signature),
Header.Signature, ACPI_NAME_SIZE))
{
/* Not the requested table */
@@ -120,13 +120,13 @@ AcpiTbFindTable (
/* Check for table match on all IDs */
- if (!ACPI_MEMCMP (AcpiGbl_RootTableList.Tables[i].Pointer->Signature,
+ if (!memcmp (AcpiGbl_RootTableList.Tables[i].Pointer->Signature,
Header.Signature, ACPI_NAME_SIZE) &&
(!OemId[0] ||
- !ACPI_MEMCMP (AcpiGbl_RootTableList.Tables[i].Pointer->OemId,
+ !memcmp (AcpiGbl_RootTableList.Tables[i].Pointer->OemId,
Header.OemId, ACPI_OEM_ID_SIZE)) &&
(!OemTableId[0] ||
- !ACPI_MEMCMP (AcpiGbl_RootTableList.Tables[i].Pointer->OemTableId,
+ !memcmp (AcpiGbl_RootTableList.Tables[i].Pointer->OemTableId,
Header.OemTableId, ACPI_OEM_TABLE_ID_SIZE)))
{
*TableIndex = i;
diff --git a/sys/contrib/dev/acpica/components/tables/tbinstal.c b/sys/contrib/dev/acpica/components/tables/tbinstal.c
index d77d2c8..a6680cf 100644
--- a/sys/contrib/dev/acpica/components/tables/tbinstal.c
+++ b/sys/contrib/dev/acpica/components/tables/tbinstal.c
@@ -94,7 +94,7 @@ AcpiTbCompareTables (
* not just the header.
*/
IsIdentical = (BOOLEAN)((TableDesc->Length != TableLength ||
- ACPI_MEMCMP (TableDesc->Pointer, Table, TableLength)) ?
+ memcmp (TableDesc->Pointer, Table, TableLength)) ?
FALSE : TRUE);
/* Release the acquired table */
@@ -309,7 +309,7 @@ AcpiTbInstallStandardTable (
*/
if ((NewTableDesc.Signature.Ascii[0] != 0x00) &&
(!ACPI_COMPARE_NAME (&NewTableDesc.Signature, ACPI_SIG_SSDT)) &&
- (ACPI_STRNCMP (NewTableDesc.Signature.Ascii, "OEM", 3)))
+ (strncmp (NewTableDesc.Signature.Ascii, "OEM", 3)))
{
ACPI_BIOS_ERROR ((AE_INFO,
"Table has invalid signature [%4.4s] (0x%8.8X), "
diff --git a/sys/contrib/dev/acpica/components/tables/tbprint.c b/sys/contrib/dev/acpica/components/tables/tbprint.c
index f0ea090..f56d002 100644
--- a/sys/contrib/dev/acpica/components/tables/tbprint.c
+++ b/sys/contrib/dev/acpica/components/tables/tbprint.c
@@ -84,7 +84,7 @@ AcpiTbFixString (
while (Length && *String)
{
- if (!ACPI_IS_PRINT (*String))
+ if (!isprint ((int) *String))
{
*String = '?';
}
@@ -114,7 +114,7 @@ AcpiTbCleanupTableHeader (
ACPI_TABLE_HEADER *Header)
{
- ACPI_MEMCPY (OutHeader, Header, sizeof (ACPI_TABLE_HEADER));
+ memcpy (OutHeader, Header, sizeof (ACPI_TABLE_HEADER));
AcpiTbFixString (OutHeader->Signature, ACPI_NAME_SIZE);
AcpiTbFixString (OutHeader->OemId, ACPI_OEM_ID_SIZE);
@@ -156,7 +156,7 @@ AcpiTbPrintTableHeader (
{
/* RSDP has no common fields */
- ACPI_MEMCPY (LocalHeader.OemId,
+ memcpy (LocalHeader.OemId,
ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->OemId, ACPI_OEM_ID_SIZE);
AcpiTbFixString (LocalHeader.OemId, ACPI_OEM_ID_SIZE);
diff --git a/sys/contrib/dev/acpica/components/tables/tbutils.c b/sys/contrib/dev/acpica/components/tables/tbutils.c
index 8b80025..94ac4f9 100644
--- a/sys/contrib/dev/acpica/components/tables/tbutils.c
+++ b/sys/contrib/dev/acpica/components/tables/tbutils.c
@@ -75,8 +75,6 @@ ACPI_STATUS
AcpiTbInitializeFacs (
void)
{
- ACPI_STATUS Status;
-
/* If Hardware Reduced flag is set, there is no FACS */
@@ -86,9 +84,23 @@ AcpiTbInitializeFacs (
return (AE_OK);
}
- Status = AcpiGetTableByIndex (ACPI_TABLE_INDEX_FACS,
- ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &AcpiGbl_FACS));
- return (Status);
+ (void) AcpiGetTableByIndex (ACPI_TABLE_INDEX_FACS,
+ ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &AcpiGbl_Facs32));
+ (void) AcpiGetTableByIndex (ACPI_TABLE_INDEX_X_FACS,
+ ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &AcpiGbl_Facs64));
+
+ if (AcpiGbl_Facs64 && (!AcpiGbl_Facs32 || !AcpiGbl_Use32BitFacsAddresses))
+ {
+ AcpiGbl_FACS = AcpiGbl_Facs64;
+ }
+ else if (AcpiGbl_Facs32)
+ {
+ AcpiGbl_FACS = AcpiGbl_Facs32;
+ }
+
+ /* If there is no FACS, just continue. There was already an error msg */
+
+ return (AE_OK);
}
#endif /* !ACPI_REDUCED_HARDWARE */
@@ -111,7 +123,7 @@ AcpiTbTablesLoaded (
void)
{
- if (AcpiGbl_RootTableList.CurrentTableCount >= 3)
+ if (AcpiGbl_RootTableList.CurrentTableCount >= 4)
{
return (TRUE);
}
@@ -190,7 +202,7 @@ AcpiTbCopyDsdt (
return (NULL);
}
- ACPI_MEMCPY (NewTable, TableDesc->Pointer, TableDesc->Length);
+ memcpy (NewTable, TableDesc->Pointer, TableDesc->Length);
AcpiTbUninstallTable (TableDesc);
AcpiTbInitTableDescriptor (
@@ -389,11 +401,11 @@ AcpiTbParseRootTable (
TableEntry = ACPI_ADD_PTR (UINT8, Table, sizeof (ACPI_TABLE_HEADER));
/*
- * First two entries in the table array are reserved for the DSDT
- * and FACS, which are not actually present in the RSDT/XSDT - they
- * come from the FADT
+ * First three entries in the table array are reserved for the DSDT
+ * and 32bit/64bit FACS, which are not actually present in the
+ * RSDT/XSDT - they come from the FADT
*/
- AcpiGbl_RootTableList.CurrentTableCount = 2;
+ AcpiGbl_RootTableList.CurrentTableCount = 3;
/* Initialize the root table array from the RSDT/XSDT */
diff --git a/sys/contrib/dev/acpica/components/tables/tbxface.c b/sys/contrib/dev/acpica/components/tables/tbxface.c
index 7336b18..67f6fea 100644
--- a/sys/contrib/dev/acpica/components/tables/tbxface.c
+++ b/sys/contrib/dev/acpica/components/tables/tbxface.c
@@ -132,7 +132,7 @@ AcpiInitializeTables (
{
/* Root Table Array has been statically allocated by the host */
- ACPI_MEMSET (InitialTableArray, 0,
+ memset (InitialTableArray, 0,
(ACPI_SIZE) InitialTableCount * sizeof (ACPI_TABLE_DESC));
AcpiGbl_RootTableList.Tables = InitialTableArray;
@@ -271,7 +271,7 @@ AcpiGetTableHeader (
return (AE_NO_MEMORY);
}
- ACPI_MEMCPY (OutTableHeader, Header,
+ memcpy (OutTableHeader, Header,
sizeof (ACPI_TABLE_HEADER));
AcpiOsUnmapMemory (Header, sizeof (ACPI_TABLE_HEADER));
}
@@ -282,7 +282,7 @@ AcpiGetTableHeader (
}
else
{
- ACPI_MEMCPY (OutTableHeader,
+ memcpy (OutTableHeader,
AcpiGbl_RootTableList.Tables[i].Pointer,
sizeof (ACPI_TABLE_HEADER));
}
diff --git a/sys/contrib/dev/acpica/components/tables/tbxfload.c b/sys/contrib/dev/acpica/components/tables/tbxfload.c
index 805bbad..014d68b 100644
--- a/sys/contrib/dev/acpica/components/tables/tbxfload.c
+++ b/sys/contrib/dev/acpica/components/tables/tbxfload.c
@@ -164,7 +164,7 @@ AcpiTbLoadNamespace (
* Save the original DSDT header for detection of table corruption
* and/or replacement of the DSDT from outside the OS.
*/
- ACPI_MEMCPY (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
+ memcpy (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
sizeof (ACPI_TABLE_HEADER));
(void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
@@ -182,10 +182,13 @@ AcpiTbLoadNamespace (
(void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
{
- if ((!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
+ if (!AcpiGbl_RootTableList.Tables[i].Address ||
+ (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
ACPI_SIG_SSDT) &&
!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
- ACPI_SIG_PSDT)) ||
+ ACPI_SIG_PSDT) &&
+ !ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
+ ACPI_SIG_OSDT)) ||
ACPI_FAILURE (AcpiTbValidateTable (
&AcpiGbl_RootTableList.Tables[i])))
{
@@ -238,11 +241,11 @@ AcpiInstallTable (
if (Physical)
{
- Flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL;
+ Flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL;
}
else
{
- Flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL;
+ Flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL;
}
Status = AcpiTbInstallStandardTable (Address, Flags,
diff --git a/sys/contrib/dev/acpica/components/utilities/utalloc.c b/sys/contrib/dev/acpica/components/utilities/utalloc.c
index 99fb15a1..c26259d 100644
--- a/sys/contrib/dev/acpica/components/utilities/utalloc.c
+++ b/sys/contrib/dev/acpica/components/utilities/utalloc.c
@@ -79,7 +79,7 @@ AcpiOsAllocateZeroed (
{
/* Clear the memory block */
- ACPI_MEMSET (Allocation, 0, Size);
+ memset (Allocation, 0, Size);
}
return (Allocation);
@@ -189,7 +189,7 @@ AcpiUtDeleteCaches (
if (AcpiGbl_DisplayFinalMemStats)
{
- ACPI_STRCPY (Buffer, "MEMORY");
+ strcpy (Buffer, "MEMORY");
(void) AcpiDbDisplayStatistics (Buffer);
}
#endif
@@ -359,6 +359,6 @@ AcpiUtInitializeBuffer (
/* Have a valid buffer, clear it */
- ACPI_MEMSET (Buffer->Pointer, 0, RequiredLength);
+ memset (Buffer->Pointer, 0, RequiredLength);
return (AE_OK);
}
diff --git a/sys/contrib/dev/acpica/components/utilities/utbuffer.c b/sys/contrib/dev/acpica/components/utilities/utbuffer.c
index cc41419..08a42cd 100644
--- a/sys/contrib/dev/acpica/components/utilities/utbuffer.c
+++ b/sys/contrib/dev/acpica/components/utilities/utbuffer.c
@@ -168,7 +168,7 @@ AcpiUtDumpBuffer (
}
BufChar = Buffer[(ACPI_SIZE) i + j];
- if (ACPI_IS_PRINT (BufChar))
+ if (isprint (BufChar))
{
AcpiOsPrintf ("%c", BufChar);
}
@@ -341,7 +341,7 @@ AcpiUtDumpBufferToFile (
}
BufChar = Buffer[(ACPI_SIZE) i + j];
- if (ACPI_IS_PRINT (BufChar))
+ if (isprint (BufChar))
{
AcpiUtFilePrintf (File, "%c", BufChar);
}
diff --git a/sys/contrib/dev/acpica/components/utilities/utcache.c b/sys/contrib/dev/acpica/components/utilities/utcache.c
index aa0161c..c252d8a 100644
--- a/sys/contrib/dev/acpica/components/utilities/utcache.c
+++ b/sys/contrib/dev/acpica/components/utilities/utcache.c
@@ -92,7 +92,7 @@ AcpiOsCreateCache (
/* Populate the cache object and return it */
- ACPI_MEMSET (Cache, 0, sizeof (ACPI_MEMORY_LIST));
+ memset (Cache, 0, sizeof (ACPI_MEMORY_LIST));
Cache->ListName = CacheName;
Cache->ObjectSize = ObjectSize;
Cache->MaxDepth = MaxDepth;
@@ -242,7 +242,7 @@ AcpiOsReleaseObject (
/* Mark the object as cached */
- ACPI_MEMSET (Object, 0xCA, Cache->ObjectSize);
+ memset (Object, 0xCA, Cache->ObjectSize);
ACPI_SET_DESCRIPTOR_TYPE (Object, ACPI_DESC_TYPE_CACHED);
/* Put the object at the head of the cache list */
@@ -318,7 +318,7 @@ AcpiOsAcquireObject (
/* Clear (zero) the previously used Object */
- ACPI_MEMSET (Object, 0, Cache->ObjectSize);
+ memset (Object, 0, Cache->ObjectSize);
}
else
{
diff --git a/sys/contrib/dev/acpica/components/utilities/utcopy.c b/sys/contrib/dev/acpica/components/utilities/utcopy.c
index 8a94ea6..2032dd4 100644
--- a/sys/contrib/dev/acpica/components/utilities/utcopy.c
+++ b/sys/contrib/dev/acpica/components/utilities/utcopy.c
@@ -146,7 +146,7 @@ AcpiUtCopyIsimpleToEsimple (
/* Always clear the external object */
- ACPI_MEMSET (ExternalObject, 0, sizeof (ACPI_OBJECT));
+ memset (ExternalObject, 0, sizeof (ACPI_OBJECT));
/*
* In general, the external object will be the same type as
@@ -165,7 +165,7 @@ AcpiUtCopyIsimpleToEsimple (
*BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD (
(ACPI_SIZE) InternalObject->String.Length + 1);
- ACPI_MEMCPY ((void *) DataSpace,
+ memcpy ((void *) DataSpace,
(void *) InternalObject->String.Pointer,
(ACPI_SIZE) InternalObject->String.Length + 1);
break;
@@ -177,7 +177,7 @@ AcpiUtCopyIsimpleToEsimple (
*BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD (
InternalObject->String.Length);
- ACPI_MEMCPY ((void *) DataSpace,
+ memcpy ((void *) DataSpace,
(void *) InternalObject->Buffer.Pointer,
InternalObject->Buffer.Length);
break;
@@ -528,7 +528,7 @@ AcpiUtCopyEsimpleToIsimple (
goto ErrorExit;
}
- ACPI_MEMCPY (InternalObject->String.Pointer,
+ memcpy (InternalObject->String.Pointer,
ExternalObject->String.Pointer,
ExternalObject->String.Length);
@@ -544,7 +544,7 @@ AcpiUtCopyEsimpleToIsimple (
goto ErrorExit;
}
- ACPI_MEMCPY (InternalObject->Buffer.Pointer,
+ memcpy (InternalObject->Buffer.Pointer,
ExternalObject->Buffer.Pointer,
ExternalObject->Buffer.Length);
@@ -732,7 +732,7 @@ AcpiUtCopySimpleObject (
CopySize = sizeof (ACPI_NAMESPACE_NODE);
}
- ACPI_MEMCPY (ACPI_CAST_PTR (char, DestDesc),
+ memcpy (ACPI_CAST_PTR (char, DestDesc),
ACPI_CAST_PTR (char, SourceDesc), CopySize);
/* Restore the saved fields */
@@ -766,7 +766,7 @@ AcpiUtCopySimpleObject (
/* Copy the actual buffer data */
- ACPI_MEMCPY (DestDesc->Buffer.Pointer,
+ memcpy (DestDesc->Buffer.Pointer,
SourceDesc->Buffer.Pointer, SourceDesc->Buffer.Length);
}
break;
@@ -788,7 +788,7 @@ AcpiUtCopySimpleObject (
/* Copy the actual string data */
- ACPI_MEMCPY (DestDesc->String.Pointer, SourceDesc->String.Pointer,
+ memcpy (DestDesc->String.Pointer, SourceDesc->String.Pointer,
(ACPI_SIZE) SourceDesc->String.Length + 1);
}
break;
diff --git a/sys/contrib/dev/acpica/components/utilities/utids.c b/sys/contrib/dev/acpica/components/utilities/utids.c
index 7d31429..6378e26 100644
--- a/sys/contrib/dev/acpica/components/utilities/utids.c
+++ b/sys/contrib/dev/acpica/components/utilities/utids.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Module Name: utids - support for device IDs - HID, UID, CID
+ * Module Name: utids - support for device IDs - HID, UID, CID, SUB, CLS
*
*****************************************************************************/
@@ -121,7 +121,7 @@ AcpiUtExecute_HID (
}
else
{
- ACPI_STRCPY (Hid->String, ObjDesc->String.Pointer);
+ strcpy (Hid->String, ObjDesc->String.Pointer);
}
Hid->Length = Length;
@@ -194,7 +194,7 @@ AcpiUtExecute_SUB (
/* Simply copy existing string */
- ACPI_STRCPY (Sub->String, ObjDesc->String.Pointer);
+ strcpy (Sub->String, ObjDesc->String.Pointer);
Sub->Length = Length;
*ReturnId = Sub;
@@ -279,7 +279,7 @@ AcpiUtExecute_UID (
}
else
{
- ACPI_STRCPY (Uid->String, ObjDesc->String.Pointer);
+ strcpy (Uid->String, ObjDesc->String.Pointer);
}
Uid->Length = Length;
@@ -426,7 +426,7 @@ AcpiUtExecute_CID (
{
/* Copy the String CID from the returned object */
- ACPI_STRCPY (NextIdString, CidObjects[i]->String.Pointer);
+ strcpy (NextIdString, CidObjects[i]->String.Pointer);
Length = CidObjects[i]->String.Length + 1;
}
@@ -449,3 +449,97 @@ Cleanup:
AcpiUtRemoveReference (ObjDesc);
return_ACPI_STATUS (Status);
}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtExecute_CLS
+ *
+ * PARAMETERS: DeviceNode - Node for the device
+ * ReturnId - Where the _CLS is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Executes the _CLS control method that returns PCI-defined
+ * class code of the device. The _CLS value is always a package
+ * containing PCI class information as a list of integers.
+ * The returned string has format "BBSSPP", where:
+ * BB = Base-class code
+ * SS = Sub-class code
+ * PP = Programming Interface code
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtExecute_CLS (
+ ACPI_NAMESPACE_NODE *DeviceNode,
+ ACPI_PNP_DEVICE_ID **ReturnId)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT **ClsObjects;
+ UINT32 Count;
+ ACPI_PNP_DEVICE_ID *Cls;
+ UINT32 Length;
+ ACPI_STATUS Status;
+ UINT8 ClassCode[3] = {0, 0, 0};
+
+
+ ACPI_FUNCTION_TRACE (UtExecute_CLS);
+
+
+ Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__CLS,
+ ACPI_BTYPE_PACKAGE, &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Get the size of the String to be returned, includes null terminator */
+
+ Length = ACPI_PCICLS_STRING_SIZE;
+ ClsObjects = ObjDesc->Package.Elements;
+ Count = ObjDesc->Package.Count;
+
+ if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE)
+ {
+ if (Count > 0 && ClsObjects[0]->Common.Type == ACPI_TYPE_INTEGER)
+ {
+ ClassCode[0] = (UINT8) ClsObjects[0]->Integer.Value;
+ }
+ if (Count > 1 && ClsObjects[1]->Common.Type == ACPI_TYPE_INTEGER)
+ {
+ ClassCode[1] = (UINT8) ClsObjects[1]->Integer.Value;
+ }
+ if (Count > 2 && ClsObjects[2]->Common.Type == ACPI_TYPE_INTEGER)
+ {
+ ClassCode[2] = (UINT8) ClsObjects[2]->Integer.Value;
+ }
+ }
+
+ /* Allocate a buffer for the CLS */
+
+ Cls = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PNP_DEVICE_ID) + (ACPI_SIZE) Length);
+ if (!Cls)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Area for the string starts after PNP_DEVICE_ID struct */
+
+ Cls->String = ACPI_ADD_PTR (char, Cls, sizeof (ACPI_PNP_DEVICE_ID));
+
+ /* Simply copy existing string */
+
+ AcpiExPciClsToString (Cls->String, ClassCode);
+ Cls->Length = Length;
+ *ReturnId = Cls;
+
+
+Cleanup:
+
+ /* On exit, we must delete the return object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
diff --git a/sys/contrib/dev/acpica/components/utilities/utmisc.c b/sys/contrib/dev/acpica/components/utilities/utmisc.c
index f3d2222..1aa02b8 100644
--- a/sys/contrib/dev/acpica/components/utilities/utmisc.c
+++ b/sys/contrib/dev/acpica/components/utilities/utmisc.c
@@ -71,10 +71,10 @@ AcpiUtIsPciRootBridge (
* Check if this is a PCI root bridge.
* ACPI 3.0+: check for a PCI Express root also.
*/
- if (!(ACPI_STRCMP (Id,
+ if (!(strcmp (Id,
PCI_ROOT_HID_STRING)) ||
- !(ACPI_STRCMP (Id,
+ !(strcmp (Id,
PCI_EXPRESS_ROOT_HID_STRING)))
{
return (TRUE);
@@ -108,7 +108,8 @@ AcpiUtIsAmlTable (
if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) ||
ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_PSDT) ||
- ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT))
+ ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT) ||
+ ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_OSDT))
{
return (TRUE);
}
diff --git a/sys/contrib/dev/acpica/components/utilities/utosi.c b/sys/contrib/dev/acpica/components/utilities/utosi.c
index bf6ba86..d0dd1dc 100644
--- a/sys/contrib/dev/acpica/components/utilities/utosi.c
+++ b/sys/contrib/dev/acpica/components/utilities/utosi.c
@@ -256,7 +256,7 @@ AcpiUtInstallInterface (
return (AE_NO_MEMORY);
}
- InterfaceInfo->Name = ACPI_ALLOCATE_ZEROED (ACPI_STRLEN (InterfaceName) + 1);
+ InterfaceInfo->Name = ACPI_ALLOCATE_ZEROED (strlen (InterfaceName) + 1);
if (!InterfaceInfo->Name)
{
ACPI_FREE (InterfaceInfo);
@@ -265,7 +265,7 @@ AcpiUtInstallInterface (
/* Initialize new info and insert at the head of the global list */
- ACPI_STRCPY (InterfaceInfo->Name, InterfaceName);
+ strcpy (InterfaceInfo->Name, InterfaceName);
InterfaceInfo->Flags = ACPI_OSI_DYNAMIC;
InterfaceInfo->Next = AcpiGbl_SupportedInterfaces;
@@ -298,7 +298,7 @@ AcpiUtRemoveInterface (
PreviousInterface = NextInterface = AcpiGbl_SupportedInterfaces;
while (NextInterface)
{
- if (!ACPI_STRCMP (InterfaceName, NextInterface->Name))
+ if (!strcmp (InterfaceName, NextInterface->Name))
{
/* Found: name is in either the static list or was added at runtime */
@@ -419,7 +419,7 @@ AcpiUtGetInterface (
NextInterface = AcpiGbl_SupportedInterfaces;
while (NextInterface)
{
- if (!ACPI_STRCMP (InterfaceName, NextInterface->Name))
+ if (!strcmp (InterfaceName, NextInterface->Name))
{
return (NextInterface);
}
diff --git a/sys/contrib/dev/acpica/components/utilities/utpredef.c b/sys/contrib/dev/acpica/components/utilities/utpredef.c
index a445f85..fed8154 100644
--- a/sys/contrib/dev/acpica/components/utilities/utpredef.c
+++ b/sys/contrib/dev/acpica/components/utilities/utpredef.c
@@ -166,7 +166,7 @@ AcpiUtGetExpectedReturnTypes (
if (!ExpectedBtypes)
{
- ACPI_STRCPY (Buffer, "NONE");
+ strcpy (Buffer, "NONE");
return;
}
@@ -180,7 +180,7 @@ AcpiUtGetExpectedReturnTypes (
if (ExpectedBtypes & ThisRtype)
{
- ACPI_STRCAT (Buffer, &UtRtypeNames[i][j]);
+ strcat (Buffer, &UtRtypeNames[i][j]);
j = 0; /* Use name separator from now on */
}
diff --git a/sys/contrib/dev/acpica/components/utilities/utprint.c b/sys/contrib/dev/acpica/components/utilities/utprint.c
index 62aecf0..dee3a71 100644
--- a/sys/contrib/dev/acpica/components/utilities/utprint.c
+++ b/sys/contrib/dev/acpica/components/utilities/utprint.c
@@ -227,7 +227,7 @@ AcpiUtScanNumber (
UINT64 Number = 0;
- while (ACPI_IS_DIGIT (*String))
+ while (isdigit ((int) *String))
{
Number *= 10;
Number += *(String++) - '0';
@@ -505,7 +505,7 @@ AcpiUtVsnprintf (
/* Process width */
Width = -1;
- if (ACPI_IS_DIGIT (*Format))
+ if (isdigit ((int) *Format))
{
Format = AcpiUtScanNumber (Format, &Number);
Width = (INT32) Number;
@@ -527,7 +527,7 @@ AcpiUtVsnprintf (
if (*Format == '.')
{
++Format;
- if (ACPI_IS_DIGIT(*Format))
+ if (isdigit ((int) *Format))
{
Format = AcpiUtScanNumber (Format, &Number);
Precision = (INT32) Number;
diff --git a/sys/contrib/dev/acpica/components/utilities/utstring.c b/sys/contrib/dev/acpica/components/utilities/utstring.c
index 4cbf435..6d38a5b 100644
--- a/sys/contrib/dev/acpica/components/utilities/utstring.c
+++ b/sys/contrib/dev/acpica/components/utilities/utstring.c
@@ -89,7 +89,7 @@ AcpiUtStrlwr (
for (String = SrcString; *String; String++)
{
- *String = (char) ACPI_TOLOWER (*String);
+ *String = (char) tolower ((int) *String);
}
return;
@@ -168,7 +168,7 @@ AcpiUtStrupr (
for (String = SrcString; *String; String++)
{
- *String = (char) ACPI_TOUPPER (*String);
+ *String = (char) toupper ((int) *String);
}
return;
@@ -234,7 +234,7 @@ AcpiUtStrtoul64 (
/* Skip over any white space in the buffer */
- while ((*String) && (ACPI_IS_SPACE (*String) || *String == '\t'))
+ while ((*String) && (isspace ((int) *String) || *String == '\t'))
{
String++;
}
@@ -245,7 +245,7 @@ AcpiUtStrtoul64 (
* Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
* We need to determine if it is decimal or hexadecimal.
*/
- if ((*String == '0') && (ACPI_TOLOWER (*(String + 1)) == 'x'))
+ if ((*String == '0') && (tolower ((int) *(String + 1)) == 'x'))
{
SignOf0x = 1;
Base = 16;
@@ -261,7 +261,7 @@ AcpiUtStrtoul64 (
/* Any string left? Check that '0x' is not followed by white space. */
- if (!(*String) || ACPI_IS_SPACE (*String) || *String == '\t')
+ if (!(*String) || isspace ((int) *String) || *String == '\t')
{
if (ToIntegerOp)
{
@@ -283,7 +283,7 @@ AcpiUtStrtoul64 (
while (*String)
{
- if (ACPI_IS_DIGIT (*String))
+ if (isdigit ((int) *String))
{
/* Convert ASCII 0-9 to Decimal value */
@@ -297,8 +297,8 @@ AcpiUtStrtoul64 (
}
else
{
- ThisDigit = (UINT8) ACPI_TOUPPER (*String);
- if (ACPI_IS_XDIGIT ((char) ThisDigit))
+ ThisDigit = (UINT8) toupper ((int) *String);
+ if (isxdigit ((int) ThisDigit))
{
/* Convert ASCII Hex char to value */
@@ -469,7 +469,7 @@ AcpiUtPrintString (
/* Check for printable character or hex escape */
- if (ACPI_IS_PRINT (String[i]))
+ if (isprint ((int) String[i]))
{
/* This is a normal character */
@@ -711,12 +711,12 @@ AcpiUtSafeStrcpy (
char *Source)
{
- if (ACPI_STRLEN (Source) >= DestSize)
+ if (strlen (Source) >= DestSize)
{
return (TRUE);
}
- ACPI_STRCPY (Dest, Source);
+ strcpy (Dest, Source);
return (FALSE);
}
@@ -727,12 +727,12 @@ AcpiUtSafeStrcat (
char *Source)
{
- if ((ACPI_STRLEN (Dest) + ACPI_STRLEN (Source)) >= DestSize)
+ if ((strlen (Dest) + strlen (Source)) >= DestSize)
{
return (TRUE);
}
- ACPI_STRCAT (Dest, Source);
+ strcat (Dest, Source);
return (FALSE);
}
@@ -747,14 +747,14 @@ AcpiUtSafeStrncat (
ACPI_SIZE ActualTransferLength;
- ActualTransferLength = ACPI_MIN (MaxTransferLength, ACPI_STRLEN (Source));
+ ActualTransferLength = ACPI_MIN (MaxTransferLength, strlen (Source));
- if ((ACPI_STRLEN (Dest) + ActualTransferLength) >= DestSize)
+ if ((strlen (Dest) + ActualTransferLength) >= DestSize)
{
return (TRUE);
}
- ACPI_STRNCAT (Dest, Source, MaxTransferLength);
+ strncat (Dest, Source, MaxTransferLength);
return (FALSE);
}
#endif
diff --git a/sys/contrib/dev/acpica/components/utilities/uttrack.c b/sys/contrib/dev/acpica/components/utilities/uttrack.c
index 5f208b5..d780397 100644
--- a/sys/contrib/dev/acpica/components/utilities/uttrack.c
+++ b/sys/contrib/dev/acpica/components/utilities/uttrack.c
@@ -113,7 +113,7 @@ AcpiUtCreateList (
return (AE_NO_MEMORY);
}
- ACPI_MEMSET (Cache, 0, sizeof (ACPI_MEMORY_LIST));
+ memset (Cache, 0, sizeof (ACPI_MEMORY_LIST));
Cache->ListName = ListName;
Cache->ObjectSize = ObjectSize;
@@ -445,7 +445,7 @@ AcpiUtTrackAllocation (
Allocation->Component = Component;
Allocation->Line = Line;
- ACPI_STRNCPY (Allocation->Module, Module, ACPI_MAX_MODULE_NAME);
+ strncpy (Allocation->Module, Module, ACPI_MAX_MODULE_NAME);
Allocation->Module[ACPI_MAX_MODULE_NAME-1] = 0;
if (!Element)
@@ -556,7 +556,7 @@ AcpiUtRemoveAllocation (
/* Mark the segment as deleted */
- ACPI_MEMSET (&Allocation->UserSpace, 0xEA, Allocation->Size);
+ memset (&Allocation->UserSpace, 0xEA, Allocation->Size);
Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY);
return (Status);
@@ -667,7 +667,7 @@ AcpiUtDumpAllocations (
while (Element)
{
if ((Element->Component & Component) &&
- ((Module == NULL) || (0 == ACPI_STRCMP (Module, Element->Module))))
+ ((Module == NULL) || (0 == strcmp (Module, Element->Module))))
{
Descriptor = ACPI_CAST_PTR (ACPI_DESCRIPTOR, &Element->UserSpace);
diff --git a/sys/contrib/dev/acpica/components/utilities/utxface.c b/sys/contrib/dev/acpica/components/utilities/utxface.c
index aab7473..eb311ec 100644
--- a/sys/contrib/dev/acpica/components/utilities/utxface.c
+++ b/sys/contrib/dev/acpica/components/utilities/utxface.c
@@ -263,7 +263,7 @@ AcpiGetStatistics (
Stats->SciCount = AcpiSciCount;
Stats->GpeCount = AcpiGpeCount;
- ACPI_MEMCPY (Stats->FixedEventCount, AcpiFixedEventCount,
+ memcpy (Stats->FixedEventCount, AcpiFixedEventCount,
sizeof (AcpiFixedEventCount));
@@ -367,7 +367,7 @@ AcpiInstallInterface (
/* Parameter validation */
- if (!InterfaceName || (ACPI_STRLEN (InterfaceName) == 0))
+ if (!InterfaceName || (strlen (InterfaceName) == 0))
{
return (AE_BAD_PARAMETER);
}
@@ -432,7 +432,7 @@ AcpiRemoveInterface (
/* Parameter validation */
- if (!InterfaceName || (ACPI_STRLEN (InterfaceName) == 0))
+ if (!InterfaceName || (strlen (InterfaceName) == 0))
{
return (AE_BAD_PARAMETER);
}
diff --git a/sys/contrib/dev/acpica/components/utilities/utxfinit.c b/sys/contrib/dev/acpica/components/utilities/utxfinit.c
index 36107ca..04cd24f 100644
--- a/sys/contrib/dev/acpica/components/utilities/utxfinit.c
+++ b/sys/contrib/dev/acpica/components/utilities/utxfinit.c
@@ -194,11 +194,14 @@ AcpiEnableSubsystem (
* Obtain a permanent mapping for the FACS. This is required for the
* Global Lock and the Firmware Waking Vector
*/
- Status = AcpiTbInitializeFacs ();
- if (ACPI_FAILURE (Status))
+ if (!(Flags & ACPI_NO_FACS_INIT))
{
- ACPI_WARNING ((AE_INFO, "Could not map the FACS table"));
- return_ACPI_STATUS (Status);
+ Status = AcpiTbInitializeFacs ();
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_WARNING ((AE_INFO, "Could not map the FACS table"));
+ return_ACPI_STATUS (Status);
+ }
}
#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/sys/contrib/dev/acpica/include/acclib.h b/sys/contrib/dev/acpica/include/acclib.h
new file mode 100644
index 0000000..ed310cc
--- /dev/null
+++ b/sys/contrib/dev/acpica/include/acclib.h
@@ -0,0 +1,167 @@
+/******************************************************************************
+ *
+ * Name: acclib.h -- C library support. Prototypes for the (optional) local
+ * implementations of required C library functions.
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifndef _ACCLIB_H
+#define _ACCLIB_H
+
+
+/*
+ * Prototypes and macros for local implementations of C library functions
+ */
+
+/* is* functions. The AcpiGbl_Ctypes array is defined in utclib.c */
+
+extern const UINT8 AcpiGbl_Ctypes[];
+
+#define _ACPI_XA 0x00 /* extra alphabetic - not supported */
+#define _ACPI_XS 0x40 /* extra space */
+#define _ACPI_BB 0x00 /* BEL, BS, etc. - not supported */
+#define _ACPI_CN 0x20 /* CR, FF, HT, NL, VT */
+#define _ACPI_DI 0x04 /* '0'-'9' */
+#define _ACPI_LO 0x02 /* 'a'-'z' */
+#define _ACPI_PU 0x10 /* punctuation */
+#define _ACPI_SP 0x08 /* space, tab, CR, LF, VT, FF */
+#define _ACPI_UP 0x01 /* 'A'-'Z' */
+#define _ACPI_XD 0x80 /* '0'-'9', 'A'-'F', 'a'-'f' */
+
+#define isdigit(c) (AcpiGbl_Ctypes[(unsigned char)(c)] & (_ACPI_DI))
+#define isspace(c) (AcpiGbl_Ctypes[(unsigned char)(c)] & (_ACPI_SP))
+#define isxdigit(c) (AcpiGbl_Ctypes[(unsigned char)(c)] & (_ACPI_XD))
+#define isupper(c) (AcpiGbl_Ctypes[(unsigned char)(c)] & (_ACPI_UP))
+#define islower(c) (AcpiGbl_Ctypes[(unsigned char)(c)] & (_ACPI_LO))
+#define isprint(c) (AcpiGbl_Ctypes[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_XS | _ACPI_PU))
+#define isalpha(c) (AcpiGbl_Ctypes[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP))
+
+
+/* Strings */
+
+char *
+strcat (
+ char *DstString,
+ const char *SrcString);
+
+char *
+strchr (
+ const char *String,
+ int ch);
+
+char *
+strcpy (
+ char *DstString,
+ const char *SrcString);
+
+int
+strcmp (
+ const char *String1,
+ const char *String2);
+
+ACPI_SIZE
+strlen (
+ const char *String);
+
+char *
+strncat (
+ char *DstString,
+ const char *SrcString,
+ ACPI_SIZE Count);
+
+int
+strncmp (
+ const char *String1,
+ const char *String2,
+ ACPI_SIZE Count);
+
+char *
+strncpy (
+ char *DstString,
+ const char *SrcString,
+ ACPI_SIZE Count);
+
+char *
+strstr (
+ char *String1,
+ char *String2);
+
+
+/* Conversion */
+
+UINT32
+strtoul (
+ const char *String,
+ char **Terminator,
+ UINT32 Base);
+
+
+/* Memory */
+
+int
+memcmp (
+ void *Buffer1,
+ void *Buffer2,
+ ACPI_SIZE Count);
+
+void *
+memcpy (
+ void *Dest,
+ const void *Src,
+ ACPI_SIZE Count);
+
+void *
+memset (
+ void *Dest,
+ int Value,
+ ACPI_SIZE Count);
+
+
+/* upper/lower case */
+
+int
+tolower (
+ int c);
+
+int
+toupper (
+ int c);
+
+#endif /* _ACCLIB_H */
diff --git a/sys/contrib/dev/acpica/include/accommon.h b/sys/contrib/dev/acpica/include/accommon.h
index e63943b..322222a 100644
--- a/sys/contrib/dev/acpica/include/accommon.h
+++ b/sys/contrib/dev/acpica/include/accommon.h
@@ -59,6 +59,9 @@
#include <contrib/dev/acpica/include/acglobal.h> /* All global variables */
#include <contrib/dev/acpica/include/achware.h> /* Hardware defines and interfaces */
#include <contrib/dev/acpica/include/acutils.h> /* Utility interfaces */
+#ifndef ACPI_USE_SYSTEM_CLIBRARY
+#include <contrib/dev/acpica/include/acclib.h> /* C library interfaces */
+#endif /* !ACPI_USE_SYSTEM_CLIBRARY */
#endif /* __ACCOMMON_H__ */
diff --git a/sys/contrib/dev/acpica/include/acglobal.h b/sys/contrib/dev/acpica/include/acglobal.h
index ab2fc26..9e7da94 100644
--- a/sys/contrib/dev/acpica/include/acglobal.h
+++ b/sys/contrib/dev/acpica/include/acglobal.h
@@ -62,6 +62,8 @@ ACPI_GLOBAL (ACPI_TABLE_HEADER, AcpiGbl_OriginalDsdtHeader);
#if (!ACPI_REDUCED_HARDWARE)
ACPI_GLOBAL (ACPI_TABLE_FACS *, AcpiGbl_FACS);
+ACPI_GLOBAL (ACPI_TABLE_FACS *, AcpiGbl_Facs32);
+ACPI_GLOBAL (ACPI_TABLE_FACS *, AcpiGbl_Facs64);
#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/sys/contrib/dev/acpica/include/acinterp.h b/sys/contrib/dev/acpica/include/acinterp.h
index 66463d6..00eb8f0 100644
--- a/sys/contrib/dev/acpica/include/acinterp.h
+++ b/sys/contrib/dev/acpica/include/acinterp.h
@@ -638,6 +638,11 @@ AcpiExIntegerToString (
char *Dest,
UINT64 Value);
+void
+AcpiExPciClsToString (
+ char *Dest,
+ UINT8 ClassCode[3]);
+
BOOLEAN
AcpiIsValidSpaceId (
UINT8 SpaceId);
diff --git a/sys/contrib/dev/acpica/include/aclocal.h b/sys/contrib/dev/acpica/include/aclocal.h
index 4c96303..dc1afff 100644
--- a/sys/contrib/dev/acpica/include/aclocal.h
+++ b/sys/contrib/dev/acpica/include/aclocal.h
@@ -238,6 +238,7 @@ typedef struct acpi_table_list
#define ACPI_TABLE_INDEX_DSDT (0)
#define ACPI_TABLE_INDEX_FACS (1)
+#define ACPI_TABLE_INDEX_X_FACS (2)
typedef struct acpi_find_context
diff --git a/sys/contrib/dev/acpica/include/acnames.h b/sys/contrib/dev/acpica/include/acnames.h
index 6bb6bbf..6887d42 100644
--- a/sys/contrib/dev/acpica/include/acnames.h
+++ b/sys/contrib/dev/acpica/include/acnames.h
@@ -51,6 +51,7 @@
#define METHOD_NAME__BBN "_BBN"
#define METHOD_NAME__CBA "_CBA"
#define METHOD_NAME__CID "_CID"
+#define METHOD_NAME__CLS "_CLS"
#define METHOD_NAME__CRS "_CRS"
#define METHOD_NAME__DDN "_DDN"
#define METHOD_NAME__HID "_HID"
diff --git a/sys/contrib/dev/acpica/include/acnamesp.h b/sys/contrib/dev/acpica/include/acnamesp.h
index 07e76b5..786fd29 100644
--- a/sys/contrib/dev/acpica/include/acnamesp.h
+++ b/sys/contrib/dev/acpica/include/acnamesp.h
@@ -67,6 +67,7 @@
#define ACPI_NS_PREFIX_IS_SCOPE 0x10
#define ACPI_NS_EXTERNAL 0x20
#define ACPI_NS_TEMPORARY 0x40
+#define ACPI_NS_OVERRIDE_IF_FOUND 0x80
/* Flags for AcpiNsWalkNamespace */
diff --git a/sys/contrib/dev/acpica/include/acobject.h b/sys/contrib/dev/acpica/include/acobject.h
index b7b624b..481eb44 100644
--- a/sys/contrib/dev/acpica/include/acobject.h
+++ b/sys/contrib/dev/acpica/include/acobject.h
@@ -430,13 +430,14 @@ typedef struct acpi_object_addr_handler
typedef struct acpi_object_reference
{
ACPI_OBJECT_COMMON_HEADER
- UINT8 Class; /* Reference Class */
- UINT8 TargetType; /* Used for Index Op */
- UINT8 Reserved;
- void *Object; /* NameOp=>HANDLE to obj, IndexOp=>ACPI_OPERAND_OBJECT */
- ACPI_NAMESPACE_NODE *Node; /* RefOf or Namepath */
- union acpi_operand_object **Where; /* Target of Index */
- UINT32 Value; /* Used for Local/Arg/Index/DdbHandle */
+ UINT8 Class; /* Reference Class */
+ UINT8 TargetType; /* Used for Index Op */
+ UINT8 Reserved;
+ void *Object; /* NameOp=>HANDLE to obj, IndexOp=>ACPI_OPERAND_OBJECT */
+ ACPI_NAMESPACE_NODE *Node; /* RefOf or Namepath */
+ union acpi_operand_object **Where; /* Target of Index */
+ UINT8 *IndexPointer; /* Used for Buffers and Strings */
+ UINT32 Value; /* Used for Local/Arg/Index/DdbHandle */
} ACPI_OBJECT_REFERENCE;
diff --git a/sys/contrib/dev/acpica/include/acoutput.h b/sys/contrib/dev/acpica/include/acoutput.h
index ab07809..0ef98eb 100644
--- a/sys/contrib/dev/acpica/include/acoutput.h
+++ b/sys/contrib/dev/acpica/include/acoutput.h
@@ -298,8 +298,12 @@
/* DEBUG_PRINT functions */
-#define ACPI_DEBUG_PRINT(plist) ACPI_ACTUAL_DEBUG plist
-#define ACPI_DEBUG_PRINT_RAW(plist) ACPI_ACTUAL_DEBUG_RAW plist
+#ifndef COMPILER_VA_MACRO
+
+#define ACPI_DEBUG_PRINT(plist) AcpiDebugPrint plist
+#define ACPI_DEBUG_PRINT_RAW(plist) AcpiDebugPrintRaw plist
+
+#else
/* Helper macros for DEBUG_PRINT */
@@ -319,6 +323,11 @@
ACPI_DO_DEBUG_PRINT (AcpiDebugPrintRaw, Level, Line, \
Filename, Modulename, Component, __VA_ARGS__)
+#define ACPI_DEBUG_PRINT(plist) ACPI_ACTUAL_DEBUG plist
+#define ACPI_DEBUG_PRINT_RAW(plist) ACPI_ACTUAL_DEBUG_RAW plist
+
+#endif
+
/*
* Function entry tracing
diff --git a/sys/contrib/dev/acpica/include/acpixf.h b/sys/contrib/dev/acpica/include/acpixf.h
index 8d972eb..037ffef 100644
--- a/sys/contrib/dev/acpica/include/acpixf.h
+++ b/sys/contrib/dev/acpica/include/acpixf.h
@@ -46,7 +46,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
-#define ACPI_CA_VERSION 0x20150515
+#define ACPI_CA_VERSION 0x20150619
#include <contrib/dev/acpica/include/acconfig.h>
#include <contrib/dev/acpica/include/actypes.h>
@@ -202,6 +202,15 @@ ACPI_INIT_GLOBAL (UINT8, AcpiGbl_DoNotUseXsdt, FALSE);
ACPI_INIT_GLOBAL (UINT8, AcpiGbl_Use32BitFadtAddresses, FALSE);
/*
+ * Optionally use 32-bit FACS table addresses.
+ * It is reported that some platforms fail to resume from system suspending
+ * if 64-bit FACS table address is selected:
+ * https://bugzilla.kernel.org/show_bug.cgi?id=74021
+ * Default is TRUE, favor the 32-bit addresses.
+ */
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_Use32BitFacsAddresses, TRUE);
+
+/*
* Optionally truncate I/O addresses to 16 bits. Provides compatibility
* with other ACPI implementations. NOTE: During ACPICA initialization,
* this value is set to TRUE if any Windows OSI strings have been
@@ -222,6 +231,11 @@ ACPI_INIT_GLOBAL (UINT8, AcpiGbl_DisableAutoRepair, FALSE);
ACPI_INIT_GLOBAL (UINT8, AcpiGbl_DisableSsdtTableInstall, FALSE);
/*
+ * Optionally enable runtime namespace override.
+ */
+ACPI_INIT_GLOBAL (UINT8, AcpiGbl_RuntimeNamespaceOverride, TRUE);
+
+/*
* We keep track of the latest version of Windows that has been requested by
* the BIOS. ACPI 5.0.
*/
@@ -1066,14 +1080,8 @@ AcpiLeaveSleepState (
ACPI_HW_DEPENDENT_RETURN_STATUS (
ACPI_STATUS
AcpiSetFirmwareWakingVector (
- UINT32 PhysicalAddress))
-
-#if ACPI_MACHINE_WIDTH == 64
-ACPI_HW_DEPENDENT_RETURN_STATUS (
-ACPI_STATUS
-AcpiSetFirmwareWakingVector64 (
- UINT64 PhysicalAddress))
-#endif
+ ACPI_PHYSICAL_ADDRESS PhysicalAddress,
+ ACPI_PHYSICAL_ADDRESS PhysicalAddress64))
/*
diff --git a/sys/contrib/dev/acpica/include/acstruct.h b/sys/contrib/dev/acpica/include/acstruct.h
index 547921b..3a6faa6 100644
--- a/sys/contrib/dev/acpica/include/acstruct.h
+++ b/sys/contrib/dev/acpica/include/acstruct.h
@@ -85,6 +85,7 @@ typedef struct acpi_walk_state
UINT8 ReturnUsed;
UINT8 ScopeDepth;
UINT8 PassNumber; /* Parse pass during table load */
+ BOOLEAN NamespaceOverride; /* Override existing objects */
UINT8 ResultSize; /* Total elements for the result stack */
UINT8 ResultCount; /* Current number of occupied elements of result stack */
UINT32 AmlOffset;
diff --git a/sys/contrib/dev/acpica/include/actbl.h b/sys/contrib/dev/acpica/include/actbl.h
index ceef763..f1c3496 100644
--- a/sys/contrib/dev/acpica/include/actbl.h
+++ b/sys/contrib/dev/acpica/include/actbl.h
@@ -67,6 +67,7 @@
#define ACPI_SIG_DSDT "DSDT" /* Differentiated System Description Table */
#define ACPI_SIG_FADT "FACP" /* Fixed ACPI Description Table */
#define ACPI_SIG_FACS "FACS" /* Firmware ACPI Control Structure */
+#define ACPI_SIG_OSDT "OSDT" /* Override System Description Table */
#define ACPI_SIG_PSDT "PSDT" /* Persistent System Description Table */
#define ACPI_SIG_RSDP "RSD PTR " /* Root System Description Pointer */
#define ACPI_SIG_RSDT "RSDT" /* Root System Description Table */
diff --git a/sys/contrib/dev/acpica/include/actbl1.h b/sys/contrib/dev/acpica/include/actbl1.h
index 962324a..3a11553 100644
--- a/sys/contrib/dev/acpica/include/actbl1.h
+++ b/sys/contrib/dev/acpica/include/actbl1.h
@@ -974,10 +974,22 @@ typedef struct acpi_madt_generic_distributor
UINT64 BaseAddress;
UINT32 GlobalIrqBase;
UINT8 Version;
- UINT8 Reserved2[3]; /* Reserved - must be zero */
+ UINT8 Reserved2[3]; /* Reserved - must be zero */
} ACPI_MADT_GENERIC_DISTRIBUTOR;
+/* Values for Version field above */
+
+enum AcpiMadtGicVersion
+{
+ ACPI_MADT_GIC_VERSION_NONE = 0,
+ ACPI_MADT_GIC_VERSION_V1 = 1,
+ ACPI_MADT_GIC_VERSION_V2 = 2,
+ ACPI_MADT_GIC_VERSION_V3 = 3,
+ ACPI_MADT_GIC_VERSION_V4 = 4,
+ ACPI_MADT_GIC_VERSION_RESERVED = 5 /* 5 and greater are reserved */
+};
+
/* 13: Generic MSI Frame (ACPI 5.1) */
diff --git a/sys/contrib/dev/acpica/include/actbl2.h b/sys/contrib/dev/acpica/include/actbl2.h
index 654495f..6ee36a6 100644
--- a/sys/contrib/dev/acpica/include/actbl2.h
+++ b/sys/contrib/dev/acpica/include/actbl2.h
@@ -52,8 +52,8 @@
* These tables are not consumed directly by the ACPICA subsystem, but are
* included here to support device drivers and the AML disassembler.
*
- * The tables in this file are defined by third-party specifications, and are
- * not defined directly by the ACPI specification itself.
+ * Generally, the tables in this file are defined by third-party specifications,
+ * and are not defined directly by the ACPI specification itself.
*
******************************************************************************/
@@ -82,6 +82,7 @@
#define ACPI_SIG_SPCR "SPCR" /* Serial Port Console Redirection table */
#define ACPI_SIG_SPMI "SPMI" /* Server Platform Management Interface table */
#define ACPI_SIG_TCPA "TCPA" /* Trusted Computing Platform Alliance table */
+#define ACPI_SIG_TPM2 "TPM2" /* Trusted Platform Module 2.0 H/W interface table */
#define ACPI_SIG_UEFI "UEFI" /* Uefi Boot Optimization Table */
#define ACPI_SIG_VRTC "VRTC" /* Virtual Real Time Clock Table */
#define ACPI_SIG_WAET "WAET" /* Windows ACPI Emulated devices Table */
@@ -1369,21 +1370,91 @@ enum AcpiSpmiInterfaceTypes
/*******************************************************************************
*
* TCPA - Trusted Computing Platform Alliance table
- * Version 1
+ * Version 2
+ *
+ * Conforms to "TCG ACPI Specification, Family 1.2 and 2.0",
+ * December 19, 2014
*
- * Conforms to "TCG PC Specific Implementation Specification",
- * Version 1.1, August 18, 2003
+ * NOTE: There are two versions of the table with the same signature --
+ * the client version and the server version.
*
******************************************************************************/
-typedef struct acpi_table_tcpa
+typedef struct acpi_table_tcpa_client
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT16 PlatformClass;
+ UINT32 MinimumLogLength; /* Minimum length for the event log area */
+ UINT64 LogAddress; /* Address of the event log area */
+
+} ACPI_TABLE_TCPA_CLIENT;
+
+typedef struct acpi_table_tcpa_server
{
ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT16 PlatformClass;
UINT16 Reserved;
- UINT32 MaxLogLength; /* Maximum length for the event log area */
+ UINT64 MinimumLogLength; /* Minimum length for the event log area */
UINT64 LogAddress; /* Address of the event log area */
+ UINT16 SpecRevision;
+ UINT8 DeviceFlags;
+ UINT8 InterruptFlags;
+ UINT8 GpeNumber;
+ UINT8 Reserved2[3];
+ UINT32 GlobalInterrupt;
+ ACPI_GENERIC_ADDRESS Address;
+ UINT32 Reserved3;
+ ACPI_GENERIC_ADDRESS ConfigAddress;
+ UINT8 Group;
+ UINT8 Bus; /* PCI Bus/Segment/Function numbers */
+ UINT8 Device;
+ UINT8 Function;
+
+} ACPI_TABLE_TCPA_SERVER;
+
+/* Values for DeviceFlags above */
+
+#define ACPI_TCPA_PCI_DEVICE (1)
+#define ACPI_TCPA_BUS_PNP (1<<1)
+#define ACPI_TCPA_ADDRESS_VALID (1<<2)
+
+/* Values for InterruptFlags above */
+
+#define ACPI_TCPA_INTERRUPT_MODE (1)
+#define ACPI_TCPA_INTERRUPT_POLARITY (1<<1)
+#define ACPI_TCPA_SCI_VIA_GPE (1<<2)
+#define ACPI_TCPA_GLOBAL_INTERRUPT (1<<3)
+
+
+/*******************************************************************************
+ *
+ * TPM2 - Trusted Platform Module (TPM) 2.0 Hardware Interface Table
+ * Version 4
+ *
+ * Conforms to "TCG ACPI Specification, Family 1.2 and 2.0",
+ * December 19, 2014
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_tpm2
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT16 PlatformClass;
+ UINT16 Reserved;
+ UINT64 ControlAddress;
+ UINT32 StartMethod;
+
+ /* Platform-specific data follows */
+
+} ACPI_TABLE_TPM2;
+
+/* Values for StartMethod above */
-} ACPI_TABLE_TCPA;
+#define ACPI_TPM2_NOT_ALLOWED 0
+#define ACPI_TPM2_START_METHOD 2
+#define ACPI_TPM2_MEMORY_MAPPED 6
+#define ACPI_TPM2_COMMAND_BUFFER 7
+#define ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD 8
/*******************************************************************************
diff --git a/sys/contrib/dev/acpica/include/actbl3.h b/sys/contrib/dev/acpica/include/actbl3.h
index f575d08..7da6bc6 100644
--- a/sys/contrib/dev/acpica/include/actbl3.h
+++ b/sys/contrib/dev/acpica/include/actbl3.h
@@ -52,7 +52,8 @@
* These tables are not consumed directly by the ACPICA subsystem, but are
* included here to support device drivers and the AML disassembler.
*
- * The tables in this file are fully defined within the ACPI specification.
+ * In general, the tables in this file are fully defined within the ACPI
+ * specification.
*
******************************************************************************/
@@ -71,7 +72,6 @@
#define ACPI_SIG_PMTT "PMTT" /* Platform Memory Topology Table */
#define ACPI_SIG_RASF "RASF" /* RAS Feature table */
#define ACPI_SIG_STAO "STAO" /* Status Override table */
-#define ACPI_SIG_TPM2 "TPM2" /* Trusted Platform Module 2.0 H/W interface table */
#define ACPI_SIG_WPBT "WPBT" /* Windows Platform Binary Table */
#define ACPI_SIG_XENV "XENV" /* Xen Environment table */
@@ -848,41 +848,6 @@ typedef struct acpi_table_stao
/*******************************************************************************
*
- * TPM2 - Trusted Platform Module (TPM) 2.0 Hardware Interface Table
- * Version 3
- *
- * Conforms to "TPM 2.0 Hardware Interface Table (TPM2)" 29 November 2011
- *
- ******************************************************************************/
-
-typedef struct acpi_table_tpm2
-{
- ACPI_TABLE_HEADER Header; /* Common ACPI table header */
- UINT32 Flags;
- UINT64 ControlAddress;
- UINT32 StartMethod;
-
-} ACPI_TABLE_TPM2;
-
-/* Control area structure (not part of table, pointed to by ControlAddress) */
-
-typedef struct acpi_tpm2_control
-{
- UINT32 Reserved;
- UINT32 Error;
- UINT32 Cancel;
- UINT32 Start;
- UINT64 InterruptControl;
- UINT32 CommandSize;
- UINT64 CommandAddress;
- UINT32 ResponseSize;
- UINT64 ResponseAddress;
-
-} ACPI_TPM2_CONTROL;
-
-
-/*******************************************************************************
- *
* WPBT - Windows Platform Environment Table (ACPI 6.0)
* Version 1
*
diff --git a/sys/contrib/dev/acpica/include/actypes.h b/sys/contrib/dev/acpica/include/actypes.h
index 0bee2a7..837c784 100644
--- a/sys/contrib/dev/acpica/include/actypes.h
+++ b/sys/contrib/dev/acpica/include/actypes.h
@@ -555,14 +555,14 @@ typedef UINT64 ACPI_INTEGER;
#define ACPI_COMPARE_NAME(a,b) (*ACPI_CAST_PTR (UINT32, (a)) == *ACPI_CAST_PTR (UINT32, (b)))
#define ACPI_MOVE_NAME(dest,src) (*ACPI_CAST_PTR (UINT32, (dest)) = *ACPI_CAST_PTR (UINT32, (src)))
#else
-#define ACPI_COMPARE_NAME(a,b) (!ACPI_STRNCMP (ACPI_CAST_PTR (char, (a)), ACPI_CAST_PTR (char, (b)), ACPI_NAME_SIZE))
-#define ACPI_MOVE_NAME(dest,src) (ACPI_STRNCPY (ACPI_CAST_PTR (char, (dest)), ACPI_CAST_PTR (char, (src)), ACPI_NAME_SIZE))
+#define ACPI_COMPARE_NAME(a,b) (!strncmp (ACPI_CAST_PTR (char, (a)), ACPI_CAST_PTR (char, (b)), ACPI_NAME_SIZE))
+#define ACPI_MOVE_NAME(dest,src) (strncpy (ACPI_CAST_PTR (char, (dest)), ACPI_CAST_PTR (char, (src)), ACPI_NAME_SIZE))
#endif
/* Support for the special RSDP signature (8 characters) */
-#define ACPI_VALIDATE_RSDP_SIG(a) (!ACPI_STRNCMP (ACPI_CAST_PTR (char, (a)), ACPI_SIG_RSDP, 8))
-#define ACPI_MAKE_RSDP_SIG(dest) (ACPI_MEMCPY (ACPI_CAST_PTR (char, (dest)), ACPI_SIG_RSDP, 8))
+#define ACPI_VALIDATE_RSDP_SIG(a) (!strncmp (ACPI_CAST_PTR (char, (a)), ACPI_SIG_RSDP, 8))
+#define ACPI_MAKE_RSDP_SIG(dest) (memcpy (ACPI_CAST_PTR (char, (dest)), ACPI_SIG_RSDP, 8))
/*******************************************************************************
@@ -582,6 +582,7 @@ typedef UINT64 ACPI_INTEGER;
#define ACPI_NO_ACPI_ENABLE 0x10
#define ACPI_NO_DEVICE_INIT 0x20
#define ACPI_NO_OBJECT_INIT 0x40
+#define ACPI_NO_FACS_INIT 0x80
/*
* Initialization state
@@ -767,10 +768,6 @@ typedef UINT32 ACPI_EVENT_STATUS;
#define ACPI_GPE_ENABLE 0
#define ACPI_GPE_DISABLE 1
#define ACPI_GPE_CONDITIONAL_ENABLE 2
-#define ACPI_GPE_SAVE_MASK 4
-
-#define ACPI_GPE_ENABLE_SAVE (ACPI_GPE_ENABLE | ACPI_GPE_SAVE_MASK)
-#define ACPI_GPE_DISABLE_SAVE (ACPI_GPE_DISABLE | ACPI_GPE_SAVE_MASK)
/*
* GPE info flags - Per GPE
@@ -1227,6 +1224,10 @@ UINT32 (*ACPI_INTERFACE_HANDLER) (
#define ACPI_UUID_LENGTH 16
+/* Length of 3-byte PCI class code values when converted back to a string */
+
+#define ACPI_PCICLS_STRING_SIZE 7 /* Includes null terminator */
+
/* Structures used for device/processor HID, UID, CID, and SUB */
@@ -1255,7 +1256,7 @@ typedef struct acpi_device_info
UINT32 Name; /* ACPI object Name */
ACPI_OBJECT_TYPE Type; /* ACPI object Type */
UINT8 ParamCount; /* If a method, required parameter count */
- UINT8 Valid; /* Indicates which optional fields are valid */
+ UINT16 Valid; /* Indicates which optional fields are valid */
UINT8 Flags; /* Miscellaneous info */
UINT8 HighestDstates[4]; /* _SxD values: 0xFF indicates not valid */
UINT8 LowestDstates[5]; /* _SxW values: 0xFF indicates not valid */
@@ -1264,6 +1265,7 @@ typedef struct acpi_device_info
ACPI_PNP_DEVICE_ID HardwareId; /* _HID value */
ACPI_PNP_DEVICE_ID UniqueId; /* _UID value */
ACPI_PNP_DEVICE_ID SubsystemId; /* _SUB value */
+ ACPI_PNP_DEVICE_ID ClassCode; /* _CLS value */
ACPI_PNP_DEVICE_ID_LIST CompatibleIdList; /* _CID list <must be last> */
} ACPI_DEVICE_INFO;
@@ -1274,14 +1276,15 @@ typedef struct acpi_device_info
/* Flags for Valid field above (AcpiGetObjectInfo) */
-#define ACPI_VALID_STA 0x01
-#define ACPI_VALID_ADR 0x02
-#define ACPI_VALID_HID 0x04
-#define ACPI_VALID_UID 0x08
-#define ACPI_VALID_SUB 0x10
-#define ACPI_VALID_CID 0x20
-#define ACPI_VALID_SXDS 0x40
-#define ACPI_VALID_SXWS 0x80
+#define ACPI_VALID_STA 0x0001
+#define ACPI_VALID_ADR 0x0002
+#define ACPI_VALID_HID 0x0004
+#define ACPI_VALID_UID 0x0008
+#define ACPI_VALID_SUB 0x0010
+#define ACPI_VALID_CID 0x0020
+#define ACPI_VALID_CLS 0x0040
+#define ACPI_VALID_SXDS 0x0100
+#define ACPI_VALID_SXWS 0x0200
/* Flags for _STA return value (CurrentStatus above) */
diff --git a/sys/contrib/dev/acpica/include/acutils.h b/sys/contrib/dev/acpica/include/acutils.h
index fe6c057..b7c2a64 100644
--- a/sys/contrib/dev/acpica/include/acutils.h
+++ b/sys/contrib/dev/acpica/include/acutils.h
@@ -246,116 +246,8 @@ AcpiUtSubsystemShutdown (
void);
-/*
- * utclib - Local implementations of C library functions
- */
-#ifndef ACPI_USE_SYSTEM_CLIBRARY
-
-ACPI_SIZE
-AcpiUtStrlen (
- const char *String);
-
-char *
-AcpiUtStrchr (
- const char *String,
- int ch);
-
-char *
-AcpiUtStrcpy (
- char *DstString,
- const char *SrcString);
-
-char *
-AcpiUtStrncpy (
- char *DstString,
- const char *SrcString,
- ACPI_SIZE Count);
-
-int
-AcpiUtMemcmp (
- const char *Buffer1,
- const char *Buffer2,
- ACPI_SIZE Count);
-
-int
-AcpiUtStrncmp (
- const char *String1,
- const char *String2,
- ACPI_SIZE Count);
-
-int
-AcpiUtStrcmp (
- const char *String1,
- const char *String2);
-
-char *
-AcpiUtStrcat (
- char *DstString,
- const char *SrcString);
-
-char *
-AcpiUtStrncat (
- char *DstString,
- const char *SrcString,
- ACPI_SIZE Count);
-
-UINT32
-AcpiUtStrtoul (
- const char *String,
- char **Terminator,
- UINT32 Base);
-
-char *
-AcpiUtStrstr (
- char *String1,
- char *String2);
-
-void *
-AcpiUtMemcpy (
- void *Dest,
- const void *Src,
- ACPI_SIZE Count);
-
-void *
-AcpiUtMemset (
- void *Dest,
- UINT8 Value,
- ACPI_SIZE Count);
-
-int
-AcpiUtToUpper (
- int c);
-
-int
-AcpiUtToLower (
- int c);
-
-extern const UINT8 _acpi_ctype[];
-
-#define _ACPI_XA 0x00 /* extra alphabetic - not supported */
-#define _ACPI_XS 0x40 /* extra space */
-#define _ACPI_BB 0x00 /* BEL, BS, etc. - not supported */
-#define _ACPI_CN 0x20 /* CR, FF, HT, NL, VT */
-#define _ACPI_DI 0x04 /* '0'-'9' */
-#define _ACPI_LO 0x02 /* 'a'-'z' */
-#define _ACPI_PU 0x10 /* punctuation */
-#define _ACPI_SP 0x08 /* space, tab, CR, LF, VT, FF */
-#define _ACPI_UP 0x01 /* 'A'-'Z' */
-#define _ACPI_XD 0x80 /* '0'-'9', 'A'-'F', 'a'-'f' */
-
-#define ACPI_IS_DIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_DI))
-#define ACPI_IS_SPACE(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_SP))
-#define ACPI_IS_XDIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_XD))
-#define ACPI_IS_UPPER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_UP))
-#define ACPI_IS_LOWER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO))
-#define ACPI_IS_PRINT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_XS | _ACPI_PU))
-#define ACPI_IS_ALPHA(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP))
-
-#endif /* !ACPI_USE_SYSTEM_CLIBRARY */
-
#define ACPI_IS_ASCII(c) ((c) < 0x80)
-
/*
* utcopy - Object construction and conversion interfaces
*/
@@ -602,6 +494,11 @@ AcpiUtExecute_CID (
ACPI_NAMESPACE_NODE *DeviceNode,
ACPI_PNP_DEVICE_ID_LIST **ReturnCidList);
+ACPI_STATUS
+AcpiUtExecute_CLS (
+ ACPI_NAMESPACE_NODE *DeviceNode,
+ ACPI_PNP_DEVICE_ID **ReturnId);
+
/*
* utlock - reader/writer locks
diff --git a/sys/contrib/dev/acpica/include/platform/acenv.h b/sys/contrib/dev/acpica/include/platform/acenv.h
index 88b1ffc..90ace88 100644
--- a/sys/contrib/dev/acpica/include/platform/acenv.h
+++ b/sys/contrib/dev/acpica/include/platform/acenv.h
@@ -349,28 +349,6 @@
/* We will be linking to the standard Clib functions */
-#define ACPI_STRSTR(s1,s2) strstr((s1), (s2))
-#define ACPI_STRCHR(s1,c) strchr((s1), (c))
-#define ACPI_STRLEN(s) (ACPI_SIZE) strlen((s))
-#define ACPI_STRCPY(d,s) (void) strcpy((d), (s))
-#define ACPI_STRNCPY(d,s,n) (void) strncpy((d), (s), (ACPI_SIZE)(n))
-#define ACPI_STRNCMP(d,s,n) strncmp((d), (s), (ACPI_SIZE)(n))
-#define ACPI_STRCMP(d,s) strcmp((d), (s))
-#define ACPI_STRCAT(d,s) (void) strcat((d), (s))
-#define ACPI_STRNCAT(d,s,n) strncat((d), (s), (ACPI_SIZE)(n))
-#define ACPI_STRTOUL(d,s,n) strtoul((d), (s), (ACPI_SIZE)(n))
-#define ACPI_MEMCMP(s1,s2,n) memcmp((const char *)(s1), (const char *)(s2), (ACPI_SIZE)(n))
-#define ACPI_MEMCPY(d,s,n) (void) memcpy((d), (s), (ACPI_SIZE)(n))
-#define ACPI_MEMSET(d,s,n) (void) memset((d), (s), (ACPI_SIZE)(n))
-#define ACPI_TOUPPER(i) toupper((int) (i))
-#define ACPI_TOLOWER(i) tolower((int) (i))
-#define ACPI_IS_XDIGIT(i) isxdigit((int) (i))
-#define ACPI_IS_DIGIT(i) isdigit((int) (i))
-#define ACPI_IS_SPACE(i) isspace((int) (i))
-#define ACPI_IS_UPPER(i) isupper((int) (i))
-#define ACPI_IS_PRINT(i) isprint((int) (i))
-#define ACPI_IS_ALPHA(i) isalpha((int) (i))
-
#else
/******************************************************************************
@@ -408,22 +386,6 @@ typedef char *va_list;
/* Use the local (ACPICA) definitions of the clib functions */
-#define ACPI_STRSTR(s1,s2) AcpiUtStrstr ((s1), (s2))
-#define ACPI_STRCHR(s1,c) AcpiUtStrchr ((s1), (c))
-#define ACPI_STRLEN(s) (ACPI_SIZE) AcpiUtStrlen ((s))
-#define ACPI_STRCPY(d,s) (void) AcpiUtStrcpy ((d), (s))
-#define ACPI_STRNCPY(d,s,n) (void) AcpiUtStrncpy ((d), (s), (ACPI_SIZE)(n))
-#define ACPI_STRNCMP(d,s,n) AcpiUtStrncmp ((d), (s), (ACPI_SIZE)(n))
-#define ACPI_STRCMP(d,s) AcpiUtStrcmp ((d), (s))
-#define ACPI_STRCAT(d,s) (void) AcpiUtStrcat ((d), (s))
-#define ACPI_STRNCAT(d,s,n) AcpiUtStrncat ((d), (s), (ACPI_SIZE)(n))
-#define ACPI_STRTOUL(d,s,n) AcpiUtStrtoul ((d), (s), (ACPI_SIZE)(n))
-#define ACPI_MEMCMP(s1,s2,n) AcpiUtMemcmp((const char *)(s1), (const char *)(s2), (ACPI_SIZE)(n))
-#define ACPI_MEMCPY(d,s,n) (void) AcpiUtMemcpy ((d), (s), (ACPI_SIZE)(n))
-#define ACPI_MEMSET(d,v,n) (void) AcpiUtMemset ((d), (v), (ACPI_SIZE)(n))
-#define ACPI_TOUPPER(c) AcpiUtToUpper ((int) (c))
-#define ACPI_TOLOWER(c) AcpiUtToLower ((int) (c))
-
#endif /* ACPI_USE_SYSTEM_CLIBRARY */
#ifndef ACPI_FILE
diff --git a/sys/contrib/dev/acpica/include/platform/acenvex.h b/sys/contrib/dev/acpica/include/platform/acenvex.h
index 6e1130e..c799fd8 100644
--- a/sys/contrib/dev/acpica/include/platform/acenvex.h
+++ b/sys/contrib/dev/acpica/include/platform/acenvex.h
@@ -56,6 +56,12 @@
#if defined(_LINUX) || defined(__linux__)
#include "aclinuxex.h"
+#elif defined(_AED_EFI)
+#include "acefiex.h"
+
+#elif defined(_GNU_EFI)
+#include "acefiex.h"
+
#elif defined(__DragonFly__)
#include "acdragonflyex.h"
diff --git a/sys/contrib/dev/acpica/include/platform/acgcc.h b/sys/contrib/dev/acpica/include/platform/acgcc.h
index 2a27445..472b6d7 100644
--- a/sys/contrib/dev/acpica/include/platform/acgcc.h
+++ b/sys/contrib/dev/acpica/include/platform/acgcc.h
@@ -75,4 +75,8 @@
#undef strchr
#endif
+/* GCC supports __VA_ARGS__ in macros */
+
+#define COMPILER_VA_MACRO 1
+
#endif /* __ACGCC_H__ */
diff --git a/sys/ddb/db_sym.c b/sys/ddb/db_sym.c
index 8386c64..61c1d5f 100644
--- a/sys/ddb/db_sym.c
+++ b/sys/ddb/db_sym.c
@@ -160,7 +160,7 @@ db_var_curvnet(struct db_variable *vp, db_expr_t *valuep, int op)
return (0);
default:
- db_printf("db_var_curcpu: unknown operation\n");
+ db_printf("db_var_curvnet: unknown operation\n");
return (0);
}
}
diff --git a/sys/dev/acpi_support/acpi_ibm.c b/sys/dev/acpi_support/acpi_ibm.c
index 1163681..735065a 100644
--- a/sys/dev/acpi_support/acpi_ibm.c
+++ b/sys/dev/acpi_support/acpi_ibm.c
@@ -485,6 +485,9 @@ acpi_ibm_attach(device_t dev)
/* Enable per-model events. */
maker = kern_getenv("smbios.system.maker");
product = kern_getenv("smbios.system.product");
+ if (maker == NULL || product == NULL)
+ goto nosmbios;
+
for (i = 0; i < nitems(acpi_ibm_models); i++) {
if (strcmp(maker, acpi_ibm_models[i].maker) == 0 &&
strcmp(product, acpi_ibm_models[i].product) == 0) {
@@ -494,6 +497,8 @@ acpi_ibm_attach(device_t dev)
ACPI_SERIAL_END(ibm);
}
}
+
+nosmbios:
freeenv(maker);
freeenv(product);
diff --git a/sys/dev/acpica/Osd/OsdHardware.c b/sys/dev/acpica/Osd/OsdHardware.c
index 1761670..8d94e7b 100644
--- a/sys/dev/acpica/Osd/OsdHardware.c
+++ b/sys/dev/acpica/Osd/OsdHardware.c
@@ -89,6 +89,10 @@ AcpiOsReadPciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, UINT64 *Value,
UINT32 Width)
{
+#ifdef __aarch64__
+ /* ARM64TODO: Add pci support */
+ return (AE_SUPPORT);
+#else
if (Width == 64)
return (AE_SUPPORT);
@@ -99,6 +103,7 @@ AcpiOsReadPciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, UINT64 *Value,
PciId->Function, Register, Width / 8);
return (AE_OK);
+#endif
}
@@ -107,6 +112,10 @@ AcpiOsWritePciConfiguration (ACPI_PCI_ID *PciId, UINT32 Register,
UINT64 Value, UINT32 Width)
{
+#ifdef __aarch64__
+ /* ARM64TODO: Add pci support */
+ return (AE_SUPPORT);
+#else
if (Width == 64)
return (AE_SUPPORT);
@@ -117,4 +126,5 @@ AcpiOsWritePciConfiguration (ACPI_PCI_ID *PciId, UINT32 Register,
Value, Width / 8);
return (AE_OK);
+#endif
}
diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c
index 21fccca..e3269db 100644
--- a/sys/dev/acpica/acpi_cpu.c
+++ b/sys/dev/acpica/acpi_cpu.c
@@ -183,7 +183,9 @@ static int acpi_cpu_cx_cst(struct acpi_cpu_softc *sc);
static void acpi_cpu_startup(void *arg);
static void acpi_cpu_startup_cx(struct acpi_cpu_softc *sc);
static void acpi_cpu_cx_list(struct acpi_cpu_softc *sc);
+#if defined(__i386__) || defined(__amd64__)
static void acpi_cpu_idle(sbintime_t sbt);
+#endif
static void acpi_cpu_notify(ACPI_HANDLE h, UINT32 notify, void *context);
static void acpi_cpu_quirks(void);
static void acpi_cpu_quirks_piix4(void);
@@ -475,12 +477,14 @@ enable_idle(struct acpi_cpu_softc *sc)
sc->cpu_disable_idle = FALSE;
}
+#if defined(__i386__) || defined(__amd64__)
static int
is_idle_disabled(struct acpi_cpu_softc *sc)
{
return (sc->cpu_disable_idle);
}
+#endif
/*
* Disable any entry to the idle function during suspend and re-enable it
@@ -999,7 +1003,9 @@ acpi_cpu_startup(void *arg)
sc = device_get_softc(cpu_devices[i]);
enable_idle(sc);
}
+#if defined(__i386__) || defined(__amd64__)
cpu_idle_hook = acpi_cpu_idle;
+#endif
}
static void
@@ -1061,6 +1067,7 @@ acpi_cpu_startup_cx(struct acpi_cpu_softc *sc)
}
}
+#if defined(__i386__) || defined(__amd64__)
/*
* Idle the CPU in the lowest state possible. This function is called with
* interrupts disabled. Note that once it re-enables interrupts, a task
@@ -1074,6 +1081,7 @@ acpi_cpu_idle(sbintime_t sbt)
struct acpi_cx *cx_next;
uint64_t cputicks;
uint32_t start_time, end_time;
+ ACPI_STATUS status;
int bm_active, cx_next_idx, i, us;
/*
@@ -1119,8 +1127,8 @@ acpi_cpu_idle(sbintime_t sbt)
*/
if ((cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0 &&
cx_next_idx > sc->cpu_non_c3) {
- AcpiReadBitRegister(ACPI_BITREG_BUS_MASTER_STATUS, &bm_active);
- if (bm_active != 0) {
+ status = AcpiReadBitRegister(ACPI_BITREG_BUS_MASTER_STATUS, &bm_active);
+ if (ACPI_SUCCESS(status) && bm_active != 0) {
AcpiWriteBitRegister(ACPI_BITREG_BUS_MASTER_STATUS, 1);
cx_next_idx = sc->cpu_non_c3;
}
@@ -1207,6 +1215,7 @@ acpi_cpu_idle(sbintime_t sbt)
sc->cpu_prev_sleep = (sc->cpu_prev_sleep * 3 + PM_USEC(end_time)) / 4;
}
+#endif
/*
* Re-evaluate the _CST object when we are notified that it changed.
@@ -1285,6 +1294,7 @@ acpi_cpu_quirks_piix4(void)
#ifdef __i386__
device_t acpi_dev;
uint32_t val;
+ ACPI_STATUS status;
acpi_dev = pci_find_device(PCI_VENDOR_INTEL, PCI_DEVICE_82371AB_3);
if (acpi_dev != NULL) {
@@ -1323,8 +1333,8 @@ acpi_cpu_quirks_piix4(void)
val |= PIIX4_STOP_BREAK_MASK;
pci_write_config(acpi_dev, PIIX4_DEVACTB_REG, val, 4);
}
- AcpiReadBitRegister(ACPI_BITREG_BUS_MASTER_RLD, &val);
- if (val) {
+ status = AcpiReadBitRegister(ACPI_BITREG_BUS_MASTER_RLD, &val);
+ if (ACPI_SUCCESS(status) && val != 0) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"acpi_cpu: PIIX4: reset BRLD_EN_BM\n"));
AcpiWriteBitRegister(ACPI_BITREG_BUS_MASTER_RLD, 0);
diff --git a/sys/dev/atkbdc/psm.c b/sys/dev/atkbdc/psm.c
index 7f3f97d..b034ef7 100644
--- a/sys/dev/atkbdc/psm.c
+++ b/sys/dev/atkbdc/psm.c
@@ -462,7 +462,8 @@ static int tame_mouse(struct psm_softc *, packetbuf_t *, mousestatus_t *,
u_char *);
/* vendor specific features */
-typedef int probefunc_t(KBDC, struct psm_softc *);
+enum probearg { PROBE, REINIT };
+typedef int probefunc_t(struct psm_softc *, enum probearg);
static int mouse_id_proc1(KBDC, int, int, int *);
static int mouse_ext_command(KBDC, int);
@@ -882,7 +883,7 @@ doinitialize(struct psm_softc *sc, mousemode_t *mode)
/* Re-enable the mouse. */
for (i = 0; vendortype[i].probefunc != NULL; ++i)
if (vendortype[i].model == sc->hw.model)
- (*vendortype[i].probefunc)(sc->kbdc, NULL);
+ (*vendortype[i].probefunc)(sc, REINIT);
/* set mouse parameters */
if (mode != (mousemode_t *)NULL) {
@@ -893,13 +894,6 @@ doinitialize(struct psm_softc *sc, mousemode_t *mode)
set_mouse_resolution(kbdc, mode->resolution);
set_mouse_scaling(kbdc, 1);
set_mouse_mode(kbdc);
-
- /*
- * Trackpoint settings are lost on resume.
- * Restore them here.
- */
- if (sc->tphw > 0)
- set_trackpoint_parameters(sc);
}
/* Record sync on the next data packet we see. */
@@ -1388,7 +1382,7 @@ psmprobe(device_t dev)
/* other parameters */
for (i = 0; vendortype[i].probefunc != NULL; ++i)
- if ((*vendortype[i].probefunc)(sc->kbdc, sc)) {
+ if ((*vendortype[i].probefunc)(sc, PROBE)) {
if (verbose >= 2)
printf("psm%d: found %s\n", unit,
model_name(vendortype[i].model));
@@ -3731,8 +3725,9 @@ mouse_ext_command(KBDC kbdc, int command)
#ifdef notyet
/* Logitech MouseMan Cordless II */
static int
-enable_lcordless(KDBC kbdc, struct psm_softc *sc)
+enable_lcordless(struct psm_softc *sc, enum probearg arg)
{
+ KBDC kbdc = sc->kbdc;
int status[3];
int ch;
@@ -3753,8 +3748,9 @@ enable_lcordless(KDBC kbdc, struct psm_softc *sc)
/* Genius NetScroll Mouse, MouseSystems SmartScroll Mouse */
static int
-enable_groller(KBDC kbdc, struct psm_softc *sc)
+enable_groller(struct psm_softc *sc, enum probearg arg)
{
+ KBDC kbdc = sc->kbdc;
int status[3];
/*
@@ -3783,15 +3779,16 @@ enable_groller(KBDC kbdc, struct psm_softc *sc)
if ((status[1] != '3') || (status[2] != 'D'))
return (FALSE);
/* FIXME: SmartScroll Mouse has 5 buttons! XXX */
- if (sc != NULL)
+ if (arg == PROBE)
sc->hw.buttons = 4;
return (TRUE);
}
/* Genius NetMouse/NetMouse Pro, ASCII Mie Mouse, NetScroll Optical */
static int
-enable_gmouse(KBDC kbdc, struct psm_softc *sc)
+enable_gmouse(struct psm_softc *sc, enum probearg arg)
{
+ KBDC kbdc = sc->kbdc;
int status[3];
/*
@@ -3813,8 +3810,9 @@ enable_gmouse(KBDC kbdc, struct psm_softc *sc)
/* ALPS GlidePoint */
static int
-enable_aglide(KBDC kbdc, struct psm_softc *sc)
+enable_aglide(struct psm_softc *sc, enum probearg arg)
{
+ KBDC kbdc = sc->kbdc;
int status[3];
/*
@@ -3835,9 +3833,10 @@ enable_aglide(KBDC kbdc, struct psm_softc *sc)
/* Kensington ThinkingMouse/Trackball */
static int
-enable_kmouse(KBDC kbdc, struct psm_softc *sc)
+enable_kmouse(struct psm_softc *sc, enum probearg arg)
{
static u_char rate[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20 };
+ KBDC kbdc = sc->kbdc;
int status[3];
int id1;
int id2;
@@ -3888,8 +3887,9 @@ enable_kmouse(KBDC kbdc, struct psm_softc *sc)
/* Logitech MouseMan+/FirstMouse+, IBM ScrollPoint Mouse */
static int
-enable_mmanplus(KBDC kbdc, struct psm_softc *sc)
+enable_mmanplus(struct psm_softc *sc, enum probearg arg)
{
+ KBDC kbdc = sc->kbdc;
int data[3];
/* the special sequence to enable the fourth button and the roller. */
@@ -3930,7 +3930,7 @@ enable_mmanplus(KBDC kbdc, struct psm_softc *sc)
if (MOUSE_PS2PLUS_PACKET_TYPE(data) != 0)
return (FALSE);
- if (sc != NULL) {
+ if (arg == PROBE) {
sc->hw.hwid &= 0x00ff;
sc->hw.hwid |= data[2] << 8; /* save model ID */
}
@@ -3946,8 +3946,9 @@ enable_mmanplus(KBDC kbdc, struct psm_softc *sc)
/* MS IntelliMouse Explorer */
static int
-enable_msexplorer(KBDC kbdc, struct psm_softc *sc)
+enable_msexplorer(struct psm_softc *sc, enum probearg arg)
{
+ KBDC kbdc = sc->kbdc;
static u_char rate0[] = { 200, 100, 80, };
static u_char rate1[] = { 200, 200, 80, };
int id;
@@ -3958,7 +3959,7 @@ enable_msexplorer(KBDC kbdc, struct psm_softc *sc)
* straight to Explorer mode, but need to be set to Intelli mode
* first.
*/
- enable_msintelli(kbdc, sc);
+ enable_msintelli(sc, arg);
/* the special sequence to enable the extra buttons and the roller. */
for (i = 0; i < sizeof(rate1)/sizeof(rate1[0]); ++i)
@@ -3969,7 +3970,7 @@ enable_msexplorer(KBDC kbdc, struct psm_softc *sc)
if (id != PSM_EXPLORER_ID)
return (FALSE);
- if (sc != NULL) {
+ if (arg == PROBE) {
sc->hw.buttons = 5; /* IntelliMouse Explorer XXX */
sc->hw.hwid = id;
}
@@ -3992,15 +3993,15 @@ enable_msexplorer(KBDC kbdc, struct psm_softc *sc)
return (TRUE);
}
-/* MS IntelliMouse */
+/*
+ * MS IntelliMouse
+ * Logitech MouseMan+ and FirstMouse+ will also respond to this
+ * probe routine and act like IntelliMouse.
+ */
static int
-enable_msintelli(KBDC kbdc, struct psm_softc *sc)
+enable_msintelli(struct psm_softc *sc, enum probearg arg)
{
- /*
- * Logitech MouseMan+ and FirstMouse+ will also respond to this
- * probe routine and act like IntelliMouse.
- */
-
+ KBDC kbdc = sc->kbdc;
static u_char rate[] = { 200, 100, 80, };
int id;
int i;
@@ -4014,7 +4015,7 @@ enable_msintelli(KBDC kbdc, struct psm_softc *sc)
if (id != PSM_INTELLI_ID)
return (FALSE);
- if (sc != NULL) {
+ if (arg == PROBE) {
sc->hw.buttons = 3;
sc->hw.hwid = id;
}
@@ -4022,15 +4023,15 @@ enable_msintelli(KBDC kbdc, struct psm_softc *sc)
return (TRUE);
}
-/* A4 Tech 4D Mouse */
+/*
+ * A4 Tech 4D Mouse
+ * Newer wheel mice from A4 Tech may use the 4D+ protocol.
+ */
static int
-enable_4dmouse(KBDC kbdc, struct psm_softc *sc)
+enable_4dmouse(struct psm_softc *sc, enum probearg arg)
{
- /*
- * Newer wheel mice from A4 Tech may use the 4D+ protocol.
- */
-
static u_char rate[] = { 200, 100, 80, 60, 40, 20 };
+ KBDC kbdc = sc->kbdc;
int id;
int i;
@@ -4046,7 +4047,7 @@ enable_4dmouse(KBDC kbdc, struct psm_softc *sc)
if (id != PSM_4DMOUSE_ID)
return (FALSE);
- if (sc != NULL) {
+ if (arg == PROBE) {
sc->hw.buttons = 3; /* XXX some 4D mice have 4? */
sc->hw.hwid = id;
}
@@ -4054,14 +4055,15 @@ enable_4dmouse(KBDC kbdc, struct psm_softc *sc)
return (TRUE);
}
-/* A4 Tech 4D+ Mouse */
+/*
+ * A4 Tech 4D+ Mouse
+ * Newer wheel mice from A4 Tech seem to use this protocol.
+ * Older models are recognized as either 4D Mouse or IntelliMouse.
+ */
static int
-enable_4dplus(KBDC kbdc, struct psm_softc *sc)
+enable_4dplus(struct psm_softc *sc, enum probearg arg)
{
- /*
- * Newer wheel mice from A4 Tech seem to use this protocol.
- * Older models are recognized as either 4D Mouse or IntelliMouse.
- */
+ KBDC kbdc = sc->kbdc;
int id;
/*
@@ -4084,7 +4086,7 @@ enable_4dplus(KBDC kbdc, struct psm_softc *sc)
return (FALSE);
}
- if (sc != NULL) {
+ if (arg == PROBE) {
sc->hw.buttons = (id == PSM_4DPLUS_ID) ? 4 : 3;
sc->hw.hwid = id;
}
@@ -4543,8 +4545,9 @@ synaptics_set_mode(struct psm_softc *sc, int mode_byte) {
}
static int
-enable_synaptics(KBDC kbdc, struct psm_softc *sc)
+enable_synaptics(struct psm_softc *sc, enum probearg arg)
{
+ KBDC kbdc = sc->kbdc;
synapticshw_t synhw;
int status[3];
int buttons;
@@ -4828,20 +4831,20 @@ enable_synaptics(KBDC kbdc, struct psm_softc *sc)
return (FALSE);
}
- if (sc != NULL)
+ if (arg == PROBE)
sc->synhw = synhw;
if (!synaptics_support)
return (FALSE);
+ synaptics_set_mode(sc, synaptics_preferred_mode(sc));
+
+ if (trackpoint_support && synhw.capPassthrough) {
+ enable_trackpoint(sc, arg);
+ }
+
VLOG(3, (LOG_DEBUG, "synaptics: END init (%d buttons)\n", buttons));
- if (sc != NULL) {
- synaptics_set_mode(sc, synaptics_preferred_mode(sc));
- if (trackpoint_support && synhw.capPassthrough) {
- synaptics_passthrough_on(sc);
- enable_trackpoint(kbdc, sc);
- synaptics_passthrough_off(sc);
- }
+ if (arg == PROBE) {
/* Create sysctl tree. */
synaptics_sysctl_create_tree(sc);
sc->hw.buttons = buttons;
@@ -5086,25 +5089,37 @@ set_trackpoint_parameters(struct psm_softc *sc)
}
static int
-enable_trackpoint(KBDC kbdc, struct psm_softc *sc)
+enable_trackpoint(struct psm_softc *sc, enum probearg arg)
{
+ KBDC kbdc = sc->kbdc;
int id;
+ /*
+ * If called from enable_synaptics(), make sure that passthrough
+ * mode is enabled so we can reach the trackpoint.
+ * However, passthrough mode must be disabled before setting the
+ * trackpoint parameters, as rackpoint_command() enables and disables
+ * passthrough mode on its own.
+ */
+ if (sc->synhw.capPassthrough)
+ synaptics_passthrough_on(sc);
+
if (send_aux_command(kbdc, 0xe1) != PSM_ACK ||
read_aux_data(kbdc) != 0x01)
- return (FALSE);
+ goto no_trackpoint;
id = read_aux_data(kbdc);
if (id < 0x01)
- return (FALSE);
- if (sc != NULL)
+ goto no_trackpoint;
+ if (arg == PROBE)
sc->tphw = id;
if (!trackpoint_support)
- return (FALSE);
+ goto no_trackpoint;
- if (sc != NULL) {
- /* Create sysctl tree. */
- trackpoint_sysctl_create_tree(sc);
+ if (sc->synhw.capPassthrough)
+ synaptics_passthrough_off(sc);
+ if (arg == PROBE) {
+ trackpoint_sysctl_create_tree(sc);
/*
* Don't overwrite hwid and buttons when we are
* a guest device.
@@ -5115,13 +5130,22 @@ enable_trackpoint(KBDC kbdc, struct psm_softc *sc)
}
}
+ set_trackpoint_parameters(sc);
+
return (TRUE);
+
+no_trackpoint:
+ if (sc->synhw.capPassthrough)
+ synaptics_passthrough_off(sc);
+
+ return (FALSE);
}
/* Interlink electronics VersaPad */
static int
-enable_versapad(KBDC kbdc, struct psm_softc *sc)
+enable_versapad(struct psm_softc *sc, enum probearg arg)
{
+ KBDC kbdc = sc->kbdc;
int data[3];
set_mouse_resolution(kbdc, PSMD_RES_MEDIUM_HIGH); /* set res. 2 */
diff --git a/sys/dev/bxe/bxe.c b/sys/dev/bxe/bxe.c
index 00e367a..2a2a81c 100644
--- a/sys/dev/bxe/bxe.c
+++ b/sys/dev/bxe/bxe.c
@@ -726,7 +726,6 @@ static __noinline int bxe_nic_unload(struct bxe_softc *sc,
uint8_t keep_link);
static void bxe_handle_sp_tq(void *context, int pending);
-static void bxe_handle_rx_mode_tq(void *context, int pending);
static void bxe_handle_fp_tq(void *context, int pending);
@@ -1174,7 +1173,17 @@ bxe_release_hw_lock(struct bxe_softc *sc,
REG_WR(sc, hw_lock_control_reg, resource_bit);
return (0);
}
+static void bxe_acquire_phy_lock(struct bxe_softc *sc)
+{
+ BXE_PHY_LOCK(sc);
+ bxe_acquire_hw_lock(sc,HW_LOCK_RESOURCE_MDIO);
+}
+static void bxe_release_phy_lock(struct bxe_softc *sc)
+{
+ bxe_release_hw_lock(sc,HW_LOCK_RESOURCE_MDIO);
+ BXE_PHY_UNLOCK(sc);
+}
/*
* Per pf misc lock must be acquired before the per port mcp lock. Otherwise,
* had we done things the other way around, if two pfs from the same port
@@ -4764,28 +4773,6 @@ bxe_handle_chip_tq(void *context,
switch (work)
{
- case CHIP_TQ_START:
- if ((if_getflags(sc->ifp) & IFF_UP) &&
- !(if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING)) {
- /* start the interface */
- BLOGD(sc, DBG_LOAD, "Starting the interface...\n");
- BXE_CORE_LOCK(sc);
- bxe_init_locked(sc);
- BXE_CORE_UNLOCK(sc);
- }
- break;
-
- case CHIP_TQ_STOP:
- if (!(if_getflags(sc->ifp) & IFF_UP) &&
- (if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING)) {
- /* bring down the interface */
- BLOGD(sc, DBG_LOAD, "Stopping the interface...\n");
- bxe_periodic_stop(sc);
- BXE_CORE_LOCK(sc);
- bxe_stop_locked(sc);
- BXE_CORE_UNLOCK(sc);
- }
- break;
case CHIP_TQ_REINIT:
if (if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING) {
@@ -4859,21 +4846,22 @@ bxe_ioctl(if_t ifp,
/* toggle the interface state up or down */
BLOGD(sc, DBG_IOCTL, "Received SIOCSIFFLAGS ioctl\n");
+ BXE_CORE_LOCK(sc);
/* check if the interface is up */
if (if_getflags(ifp) & IFF_UP) {
if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
/* set the receive mode flags */
bxe_set_rx_mode(sc);
} else {
- atomic_store_rel_long(&sc->chip_tq_flags, CHIP_TQ_START);
- taskqueue_enqueue(sc->chip_tq, &sc->chip_tq_task);
+ bxe_init_locked(sc);
}
} else {
if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
- atomic_store_rel_long(&sc->chip_tq_flags, CHIP_TQ_STOP);
- taskqueue_enqueue(sc->chip_tq, &sc->chip_tq_task);
+ bxe_periodic_stop(sc);
+ bxe_stop_locked(sc);
}
}
+ BXE_CORE_UNLOCK(sc);
break;
@@ -4885,7 +4873,9 @@ bxe_ioctl(if_t ifp,
/* check if the interface is up */
if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
/* set the receive mode flags */
+ BXE_CORE_LOCK(sc);
bxe_set_rx_mode(sc);
+ BXE_CORE_UNLOCK(sc);
}
break;
@@ -5044,8 +5034,11 @@ bxe_ioctl(if_t ifp,
if (reinit && (if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING)) {
BLOGD(sc, DBG_LOAD | DBG_IOCTL,
"Re-initializing hardware from IOCTL change\n");
- atomic_store_rel_long(&sc->chip_tq_flags, CHIP_TQ_REINIT);
- taskqueue_enqueue(sc->chip_tq, &sc->chip_tq_task);
+ bxe_periodic_stop(sc);
+ BXE_CORE_LOCK(sc);
+ bxe_stop_locked(sc);
+ bxe_init_locked(sc);
+ BXE_CORE_UNLOCK(sc);
}
return (error);
@@ -7487,8 +7480,7 @@ bxe_attn_int_asserted(struct bxe_softc *sc,
if (asserted & ATTN_HARD_WIRED_MASK) {
if (asserted & ATTN_NIG_FOR_FUNC) {
- BXE_PHY_LOCK(sc);
-
+ bxe_acquire_phy_lock(sc);
/* save nig interrupt mask */
nig_mask = REG_RD(sc, nig_int_mask_addr);
@@ -7581,7 +7573,7 @@ bxe_attn_int_asserted(struct bxe_softc *sc,
REG_WR(sc, nig_int_mask_addr, nig_mask);
- BXE_PHY_UNLOCK(sc);
+ bxe_release_phy_lock(sc);
}
}
@@ -8339,10 +8331,10 @@ bxe_attn_int_deasserted3(struct bxe_softc *sc,
if (sc->link_vars.periodic_flags &
ELINK_PERIODIC_FLAGS_LINK_EVENT) {
/* sync with link */
- BXE_PHY_LOCK(sc);
+ bxe_acquire_phy_lock(sc);
sc->link_vars.periodic_flags &=
~ELINK_PERIODIC_FLAGS_LINK_EVENT;
- BXE_PHY_UNLOCK(sc);
+ bxe_release_phy_lock(sc);
if (IS_MF(sc))
; // XXX bxe_link_sync_notify(sc);
bxe_link_report(sc);
@@ -8535,9 +8527,9 @@ bxe_attn_int_deasserted0(struct bxe_softc *sc,
}
if ((attn & sc->link_vars.aeu_int_mask) && sc->port.pmf) {
- BXE_PHY_LOCK(sc);
+ bxe_acquire_phy_lock(sc);
elink_handle_module_detect_int(&sc->link_params);
- BXE_PHY_UNLOCK(sc);
+ bxe_release_phy_lock(sc);
}
if (attn & HW_INTERRUT_ASSERT_SET_0) {
@@ -9564,11 +9556,6 @@ bxe_interrupt_detach(struct bxe_softc *sc)
}
}
- if (sc->rx_mode_tq) {
- taskqueue_drain(sc->rx_mode_tq, &sc->rx_mode_tq_task);
- taskqueue_free(sc->rx_mode_tq);
- sc->rx_mode_tq = NULL;
- }
if (sc->sp_tq) {
taskqueue_drain(sc->sp_tq, &sc->sp_tq_task);
@@ -9602,14 +9589,6 @@ bxe_interrupt_attach(struct bxe_softc *sc)
taskqueue_start_threads(&sc->sp_tq, 1, PWAIT, /* lower priority */
"%s", sc->sp_tq_name);
- snprintf(sc->rx_mode_tq_name, sizeof(sc->rx_mode_tq_name),
- "bxe%d_rx_mode_tq", sc->unit);
- TASK_INIT(&sc->rx_mode_tq_task, 0, bxe_handle_rx_mode_tq, sc);
- sc->rx_mode_tq = taskqueue_create_fast(sc->rx_mode_tq_name, M_NOWAIT,
- taskqueue_thread_enqueue,
- &sc->rx_mode_tq);
- taskqueue_start_threads(&sc->rx_mode_tq, 1, PWAIT, /* lower priority */
- "%s", sc->rx_mode_tq_name);
for (i = 0; i < sc->num_queues; i++) {
fp = &sc->fp[i];
@@ -12363,9 +12342,9 @@ bxe_link_report_locked(struct bxe_softc *sc)
static void
bxe_link_report(struct bxe_softc *sc)
{
- BXE_PHY_LOCK(sc);
+ bxe_acquire_phy_lock(sc);
bxe_link_report_locked(sc);
- BXE_PHY_UNLOCK(sc);
+ bxe_release_phy_lock(sc);
}
static void
@@ -12481,7 +12460,7 @@ bxe_initial_phy_init(struct bxe_softc *sc,
sc->link_params.feature_config_flags |= feat;
}
- BXE_PHY_LOCK(sc);
+ bxe_acquire_phy_lock(sc);
if (load_mode == LOAD_DIAG) {
lp->loopback_mode = ELINK_LOOPBACK_XGXS;
@@ -12502,7 +12481,7 @@ bxe_initial_phy_init(struct bxe_softc *sc,
rc = elink_phy_init(&sc->link_params, &sc->link_vars);
- BXE_PHY_UNLOCK(sc);
+ bxe_release_phy_lock(sc);
bxe_calc_fc_adv(sc);
@@ -12546,6 +12525,7 @@ bxe_init_mcast_macs_list(struct bxe_softc *sc,
BLOGE(sc, "Failed to allocate temp mcast list\n");
return (-1);
}
+ bzero(mta, (sizeof(unsigned char) * ETHER_ADDR_LEN * mc_count));
mc_mac = malloc(sizeof(*mc_mac) * mc_count, M_DEVBUF,
(M_NOWAIT | M_ZERO));
@@ -12554,12 +12534,13 @@ bxe_init_mcast_macs_list(struct bxe_softc *sc,
BLOGE(sc, "Failed to allocate temp mcast list\n");
return (-1);
}
+ bzero(mc_mac, (sizeof(*mc_mac) * mc_count));
if_multiaddr_array(ifp, mta, &mcnt, mc_count); /* mta and mcnt not expected
to be different */
for(i=0; i< mcnt; i++) {
- bcopy((mta + (i * ETHER_ADDR_LEN)), mc_mac->mac, ETHER_ADDR_LEN);
+ mc_mac->mac = (uint8_t *)(mta + (i * ETHER_ADDR_LEN));
ECORE_LIST_PUSH_TAIL(&mc_mac->link, &p->mcast_list);
BLOGD(sc, DBG_LOAD,
@@ -12604,6 +12585,7 @@ bxe_set_mc_list(struct bxe_softc *sc)
rc = ecore_config_mcast(sc, &rparam, ECORE_MCAST_CMD_DEL);
if (rc < 0) {
BLOGE(sc, "Failed to clear multicast configuration: %d\n", rc);
+ BXE_MCAST_UNLOCK(sc);
return (rc);
}
@@ -12694,18 +12676,13 @@ bxe_set_uc_list(struct bxe_softc *sc)
}
static void
-bxe_handle_rx_mode_tq(void *context,
- int pending)
+bxe_set_rx_mode(struct bxe_softc *sc)
{
- struct bxe_softc *sc = (struct bxe_softc *)context;
if_t ifp = sc->ifp;
uint32_t rx_mode = BXE_RX_MODE_NORMAL;
- BXE_CORE_LOCK(sc);
-
if (sc->state != BXE_STATE_OPEN) {
BLOGD(sc, DBG_SP, "state is %x, returning\n", sc->state);
- BXE_CORE_UNLOCK(sc);
return;
}
@@ -12747,7 +12724,6 @@ bxe_handle_rx_mode_tq(void *context,
if (bxe_test_bit(ECORE_FILTER_RX_MODE_PENDING, &sc->sp_state)) {
BLOGD(sc, DBG_LOAD, "Scheduled setting rx_mode with ECORE...\n");
bxe_set_bit(ECORE_FILTER_RX_MODE_SCHED, &sc->sp_state);
- BXE_CORE_UNLOCK(sc);
return;
}
@@ -12767,14 +12743,8 @@ bxe_handle_rx_mode_tq(void *context,
}
#endif
- BXE_CORE_UNLOCK(sc);
}
-static void
-bxe_set_rx_mode(struct bxe_softc *sc)
-{
- taskqueue_enqueue(sc->rx_mode_tq, &sc->rx_mode_tq_task);
-}
/* update flags in shmem */
static void
@@ -12845,13 +12815,13 @@ bxe_periodic_callout_func(void *xsc)
*/
mb();
if (sc->port.pmf) {
- BXE_PHY_LOCK(sc);
+ bxe_acquire_phy_lock(sc);
elink_period_func(&sc->link_params, &sc->link_vars);
- BXE_PHY_UNLOCK(sc);
+ bxe_release_phy_lock(sc);
}
}
- if (IS_PF(sc) && !BXE_NOMCP(sc)) {
+ if (IS_PF(sc) && !(sc->flags & BXE_NO_PULSE)) {
int mb_idx = SC_FW_MB_IDX(sc);
uint32_t drv_pulse;
uint32_t mcp_pulse;
@@ -12995,6 +12965,11 @@ bxe_nic_load(struct bxe_softc *sc,
}
}
+ /* set ALWAYS_ALIVE bit in shmem */
+ sc->fw_drv_pulse_wr_seq |= DRV_PULSE_ALWAYS_ALIVE;
+ bxe_drv_pulse(sc);
+ sc->flags |= BXE_NO_PULSE;
+
/* attach interrupts */
if (bxe_interrupt_attach(sc) != 0) {
sc->state = BXE_STATE_CLOSED;
@@ -16750,10 +16725,10 @@ bxe_common_init_phy(struct bxe_softc *sc)
shmem2_base[1] = SHMEM2_RD(sc, other_shmem2_base_addr);
}
- BXE_PHY_LOCK(sc);
+ bxe_acquire_phy_lock(sc);
elink_common_init_phy(sc, shmem_base, shmem2_base,
sc->devinfo.chip_id, 0);
- BXE_PHY_UNLOCK(sc);
+ bxe_release_phy_lock(sc);
}
static void
@@ -18630,9 +18605,9 @@ static void
bxe_link_reset(struct bxe_softc *sc)
{
if (!BXE_NOMCP(sc)) {
- BXE_PHY_LOCK(sc);
+ bxe_acquire_phy_lock(sc);
elink_lfa_reset(&sc->link_params, &sc->link_vars);
- BXE_PHY_UNLOCK(sc);
+ bxe_release_phy_lock(sc);
} else {
if (!CHIP_REV_IS_SLOW(sc)) {
BLOGW(sc, "Bootcode is missing - cannot reset link\n");
diff --git a/sys/dev/bxe/bxe.h b/sys/dev/bxe/bxe.h
index eb695d0..5fb31a3 100644
--- a/sys/dev/bxe/bxe.h
+++ b/sys/dev/bxe/bxe.h
@@ -1400,6 +1400,7 @@ struct bxe_softc {
//#define BXE_SAFC_TX_FLAG 0x00000400
#define BXE_MF_FUNC_DIS 0x00000800
#define BXE_TX_SWITCHING 0x00001000
+#define BXE_NO_PULSE 0x00002000
unsigned long debug; /* per-instance debug logging config */
@@ -1429,11 +1430,6 @@ struct bxe_softc {
struct taskqueue *sp_tq;
char sp_tq_name[32];
- /* set rx_mode asynchronous taskqueue */
- struct task rx_mode_tq_task;
- struct taskqueue *rx_mode_tq;
- char rx_mode_tq_name[32];
-
struct bxe_fastpath fp[MAX_RSS_CHAINS];
struct bxe_sp_objs sp_objs[MAX_RSS_CHAINS];
diff --git a/sys/dev/bxe/ecore_reg.h b/sys/dev/bxe/ecore_reg.h
index b256e78..850390c 100644
--- a/sys/dev/bxe/ecore_reg.h
+++ b/sys/dev/bxe/ecore_reg.h
@@ -1965,6 +1965,7 @@ __FBSDID("$FreeBSD$");
#define MISC_SPIO_SPIO5 0x20
#define HW_LOCK_MAX_RESOURCE_VALUE 31
#define HW_LOCK_RESOURCE_DRV_FLAGS 10
+#define HW_LOCK_RESOURCE_MDIO 0
#define HW_LOCK_RESOURCE_GPIO 1
#define HW_LOCK_RESOURCE_NVRAM 12
#define HW_LOCK_RESOURCE_PORT0_ATT_MASK 3
diff --git a/sys/dev/bxe/ecore_sp.c b/sys/dev/bxe/ecore_sp.c
index b716085..2685453 100644
--- a/sys/dev/bxe/ecore_sp.c
+++ b/sys/dev/bxe/ecore_sp.c
@@ -474,7 +474,7 @@ static void __ecore_vlan_mac_h_exec_pending(struct bxe_softc *sc,
o->head_exe_request = FALSE;
o->saved_ramrod_flags = 0;
rc = ecore_exe_queue_step(sc, &o->exe_queue, &ramrod_flags);
- if (rc != ECORE_SUCCESS) {
+ if ((rc != ECORE_SUCCESS) && (rc != ECORE_PENDING)) {
ECORE_ERR("execution of pending commands failed with rc %d\n",
rc);
#ifdef ECORE_STOP_ON_ERROR
diff --git a/sys/dev/cxgbe/adapter.h b/sys/dev/cxgbe/adapter.h
index 2655dae..c178297 100644
--- a/sys/dev/cxgbe/adapter.h
+++ b/sys/dev/cxgbe/adapter.h
@@ -206,6 +206,9 @@ enum {
INTR_OFLD_RXQ = (1 << 5), /* All TOE rxq's take interrupts */
INTR_NM_RXQ = (1 << 6), /* All netmap rxq's take interrupts */
INTR_ALL = (INTR_RXQ | INTR_OFLD_RXQ | INTR_NM_RXQ),
+
+ /* adapter debug_flags */
+ DF_DUMP_MBOX = (1 << 0),
};
#define IS_DOOMED(pi) ((pi)->flags & DOOMED)
@@ -762,6 +765,7 @@ struct adapter {
int active_ulds; /* ULDs activated on this adapter */
#endif
int flags;
+ int debug_flags;
char ifp_lockname[16];
struct mtx ifp_lock;
@@ -846,6 +850,24 @@ struct adapter {
#define TXQ_LOCK_ASSERT_OWNED(txq) EQ_LOCK_ASSERT_OWNED(&(txq)->eq)
#define TXQ_LOCK_ASSERT_NOTOWNED(txq) EQ_LOCK_ASSERT_NOTOWNED(&(txq)->eq)
+#define CH_DUMP_MBOX(sc, mbox, data_reg) \
+ do { \
+ if (sc->debug_flags & DF_DUMP_MBOX) { \
+ log(LOG_NOTICE, \
+ "%s mbox %u: %016llx %016llx %016llx %016llx " \
+ "%016llx %016llx %016llx %016llx\n", \
+ device_get_nameunit(sc->dev), mbox, \
+ (unsigned long long)t4_read_reg64(sc, data_reg), \
+ (unsigned long long)t4_read_reg64(sc, data_reg + 8), \
+ (unsigned long long)t4_read_reg64(sc, data_reg + 16), \
+ (unsigned long long)t4_read_reg64(sc, data_reg + 24), \
+ (unsigned long long)t4_read_reg64(sc, data_reg + 32), \
+ (unsigned long long)t4_read_reg64(sc, data_reg + 40), \
+ (unsigned long long)t4_read_reg64(sc, data_reg + 48), \
+ (unsigned long long)t4_read_reg64(sc, data_reg + 56)); \
+ } \
+ } while (0)
+
#define for_each_txq(pi, iter, q) \
for (q = &pi->adapter->sge.txq[pi->first_txq], iter = 0; \
iter < pi->ntxq; ++iter, ++q)
diff --git a/sys/dev/cxgbe/common/t4_hw.c b/sys/dev/cxgbe/common/t4_hw.c
index e2efb78..d140276 100644
--- a/sys/dev/cxgbe/common/t4_hw.c
+++ b/sys/dev/cxgbe/common/t4_hw.c
@@ -262,6 +262,8 @@ int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size,
for (i = 0; i < size; i += 8, p++)
t4_write_reg64(adap, data_reg + i, be64_to_cpu(*p));
+ CH_DUMP_MBOX(adap, mbox, data_reg);
+
t4_write_reg(adap, ctl_reg, F_MBMSGVALID | V_MBOWNER(X_MBOWNER_FW));
t4_read_reg(adap, ctl_reg); /* flush write */
@@ -287,6 +289,8 @@ int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size,
continue;
}
+ CH_DUMP_MBOX(adap, mbox, data_reg);
+
res = t4_read_reg64(adap, data_reg);
if (G_FW_CMD_OP(res >> 32) == FW_DEBUG_CMD) {
fw_asrt(adap, data_reg);
diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c
index b164cce..5c88059 100644
--- a/sys/dev/cxgbe/t4_main.c
+++ b/sys/dev/cxgbe/t4_main.c
@@ -585,6 +585,9 @@ t4_attach(device_t dev)
sc = device_get_softc(dev);
sc->dev = dev;
+#ifdef INVARIANTS
+ sc->debug_flags = DF_DUMP_MBOX;
+#endif
pci_enable_busmaster(dev);
if (pci_find_cap(dev, PCIY_EXPRESS, &i) == 0) {
@@ -4603,6 +4606,9 @@ t4_sysctls(struct adapter *sc)
SYSCTL_ADD_INT(ctx, children, OID_AUTO, "lro_timeout", CTLFLAG_RW,
&sc->lro_timeout, 0, "lro inactive-flush timeout (in us)");
+ SYSCTL_ADD_INT(ctx, children, OID_AUTO, "debug_flags", CTLFLAG_RW,
+ &sc->debug_flags, 0, "flags to enable runtime debugging");
+
#ifdef SBUF_DRAIN
/*
* dev.t4nex.X.misc. Marked CTLFLAG_SKIP to avoid information overload.
diff --git a/sys/dev/drm2/i915/i915_gem.c b/sys/dev/drm2/i915/i915_gem.c
index a473031..356ccc5 100644
--- a/sys/dev/drm2/i915/i915_gem.c
+++ b/sys/dev/drm2/i915/i915_gem.c
@@ -1874,7 +1874,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
map = &p->p_vmspace->vm_map;
size = round_page(args->size);
PROC_LOCK(p);
- if (map->size + size > lim_cur(p, RLIMIT_VMEM)) {
+ if (map->size + size > lim_cur_proc(p, RLIMIT_VMEM)) {
PROC_UNLOCK(p);
error = -ENOMEM;
goto out;
@@ -3175,9 +3175,6 @@ i915_gem_wire_page(vm_object_t object, vm_pindex_t pindex, bool *fresh)
if (m->valid != VM_PAGE_BITS_ALL) {
if (vm_pager_has_page(object, pindex, NULL, NULL)) {
rv = vm_pager_get_pages(object, &m, 1, 0);
- m = vm_page_lookup(object, pindex);
- if (m == NULL)
- return (NULL);
if (rv != VM_PAGER_OK) {
vm_page_lock(m);
vm_page_free(m);
diff --git a/sys/dev/drm2/ttm/ttm_page_alloc.c b/sys/dev/drm2/ttm/ttm_page_alloc.c
index 246afdf..75abd10 100644
--- a/sys/dev/drm2/ttm/ttm_page_alloc.c
+++ b/sys/dev/drm2/ttm/ttm_page_alloc.c
@@ -155,6 +155,66 @@ ttm_caching_state_to_vm(enum ttm_caching_state cstate)
panic("caching state %d\n", cstate);
}
+static vm_page_t
+ttm_vm_page_alloc_dma32(int req, vm_memattr_t memattr)
+{
+ vm_page_t p;
+ int tries;
+
+ for (tries = 0; ; tries++) {
+ p = vm_page_alloc_contig(NULL, 0, req, 1, 0, 0xffffffff,
+ PAGE_SIZE, 0, memattr);
+ if (p != NULL || tries > 2)
+ return (p);
+
+ /*
+ * Before growing the cache see if this is just a normal
+ * memory shortage.
+ */
+ VM_WAIT;
+ vm_pageout_grow_cache(tries, 0, 0xffffffff);
+ }
+}
+
+static vm_page_t
+ttm_vm_page_alloc_any(int req, vm_memattr_t memattr)
+{
+ vm_page_t p;
+
+ while (1) {
+ p = vm_page_alloc(NULL, 0, req);
+ if (p != NULL)
+ break;
+ VM_WAIT;
+ }
+ pmap_page_set_memattr(p, memattr);
+ return (p);
+}
+
+static vm_page_t
+ttm_vm_page_alloc(int flags, enum ttm_caching_state cstate)
+{
+ vm_page_t p;
+ vm_memattr_t memattr;
+ int req;
+
+ memattr = ttm_caching_state_to_vm(cstate);
+ req = VM_ALLOC_NORMAL | VM_ALLOC_WIRED | VM_ALLOC_NOOBJ;
+ if ((flags & TTM_PAGE_FLAG_ZERO_ALLOC) != 0)
+ req |= VM_ALLOC_ZERO;
+
+ if ((flags & TTM_PAGE_FLAG_DMA32) != 0)
+ p = ttm_vm_page_alloc_dma32(req, memattr);
+ else
+ p = ttm_vm_page_alloc_any(req, memattr);
+
+ if (p != NULL) {
+ p->oflags &= ~VPO_UNMANAGED;
+ p->flags |= PG_FICTITIOUS;
+ }
+ return (p);
+}
+
static void ttm_pool_kobj_release(struct ttm_pool_manager *m)
{
@@ -461,14 +521,6 @@ static void ttm_handle_caching_state_failure(struct pglist *pages,
}
}
-static vm_paddr_t
-ttm_alloc_high_bound(int ttm_alloc_flags)
-{
-
- return ((ttm_alloc_flags & TTM_PAGE_FLAG_DMA32) ? 0xffffffff :
- VM_MAX_ADDRESS);
-}
-
/**
* Allocate new pages with correct caching.
*
@@ -481,32 +533,17 @@ static int ttm_alloc_new_pages(struct pglist *pages, int ttm_alloc_flags,
vm_page_t *caching_array;
vm_page_t p;
int r = 0;
- unsigned i, cpages, aflags;
+ unsigned i, cpages;
unsigned max_cpages = min(count,
(unsigned)(PAGE_SIZE/sizeof(vm_page_t)));
- int tries;
- aflags = VM_ALLOC_NORMAL | VM_ALLOC_WIRED | VM_ALLOC_NOOBJ |
- ((ttm_alloc_flags & TTM_PAGE_FLAG_ZERO_ALLOC) != 0 ?
- VM_ALLOC_ZERO : 0);
-
/* allocate array for page caching change */
caching_array = malloc(max_cpages * sizeof(vm_page_t), M_TEMP,
M_WAITOK | M_ZERO);
for (i = 0, cpages = 0; i < count; ++i) {
- tries = 0;
-retry:
- p = vm_page_alloc_contig(NULL, 0, aflags, 1, 0,
- ttm_alloc_high_bound(ttm_alloc_flags),
- PAGE_SIZE, 0, ttm_caching_state_to_vm(cstate));
+ p = ttm_vm_page_alloc(ttm_alloc_flags, cstate);
if (!p) {
- if (tries < 3) {
- vm_pageout_grow_cache(tries, 0,
- ttm_alloc_high_bound(ttm_alloc_flags));
- tries++;
- goto retry;
- }
printf("[TTM] Unable to get page %u\n", i);
/* store already allocated pages in the pool after
@@ -522,8 +559,6 @@ retry:
r = -ENOMEM;
goto out;
}
- p->oflags &= ~VPO_UNMANAGED;
- p->flags |= PG_FICTITIOUS;
#ifdef CONFIG_HIGHMEM /* KIB: nop */
/* gfp flags of highmem page should never be dma32 so we
@@ -705,34 +740,18 @@ static int ttm_get_pages(vm_page_t *pages, unsigned npages, int flags,
struct ttm_page_pool *pool = ttm_get_pool(flags, cstate);
struct pglist plist;
vm_page_t p = NULL;
- int gfp_flags, aflags;
+ int gfp_flags;
unsigned count;
int r;
- int tries;
-
- aflags = VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED |
- ((flags & TTM_PAGE_FLAG_ZERO_ALLOC) != 0 ? VM_ALLOC_ZERO : 0);
/* No pool for cached pages */
if (pool == NULL) {
for (r = 0; r < npages; ++r) {
- tries = 0;
-retry:
- p = vm_page_alloc_contig(NULL, 0, aflags, 1, 0,
- ttm_alloc_high_bound(flags), PAGE_SIZE,
- 0, ttm_caching_state_to_vm(cstate));
+ p = ttm_vm_page_alloc(flags, cstate);
if (!p) {
- if (tries < 3) {
- vm_pageout_grow_cache(tries, 0,
- ttm_alloc_high_bound(flags));
- tries++;
- goto retry;
- }
printf("[TTM] Unable to allocate page\n");
return -ENOMEM;
}
- p->oflags &= ~VPO_UNMANAGED;
- p->flags |= PG_FICTITIOUS;
pages[r] = p;
}
return 0;
diff --git a/sys/dev/filemon/filemon.h b/sys/dev/filemon/filemon.h
index 95d2ef3..b3fa061 100644
--- a/sys/dev/filemon/filemon.h
+++ b/sys/dev/filemon/filemon.h
@@ -30,5 +30,5 @@
#define FILEMON_SET_FD _IOWR('S', 1, int)
#define FILEMON_SET_PID _IOWR('S', 2, pid_t)
-#define FILEMON_VERSION 4 /* output format
+#define FILEMON_VERSION 5 /* output format
(bump when adding record types) */
diff --git a/sys/dev/filemon/filemon_wrapper.c b/sys/dev/filemon/filemon_wrapper.c
index 2c6f20e..4a1259a 100644
--- a/sys/dev/filemon/filemon_wrapper.c
+++ b/sys/dev/filemon/filemon_wrapper.c
@@ -28,6 +28,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/sx.h>
+
#include "opt_compat.h"
#if __FreeBSD_version > 800032
@@ -84,13 +86,17 @@ filemon_pid_check(struct proc *p)
{
struct filemon *filemon;
- while (p->p_pptr) {
+ sx_slock(&proctree_lock);
+ while (p != initproc) {
TAILQ_FOREACH(filemon, &filemons_inuse, link) {
- if (p->p_pid == filemon->pid)
+ if (p->p_pid == filemon->pid) {
+ sx_sunlock(&proctree_lock);
return (filemon);
+ }
}
- p = p->p_pptr;
+ p = proc_realparent(p);
}
+ sx_sunlock(&proctree_lock);
return (NULL);
}
@@ -316,6 +322,68 @@ filemon_wrapper_open(struct thread *td, struct open_args *uap)
}
static int
+filemon_wrapper_openat(struct thread *td, struct openat_args *uap)
+{
+ int ret;
+ size_t done;
+ size_t len;
+ struct filemon *filemon;
+
+ if ((ret = sys_openat(td, uap)) == 0) {
+ /* Grab a read lock on the filemon inuse list. */
+ filemon_lock_read();
+
+ if ((filemon = filemon_pid_check(curproc)) != NULL) {
+ /* Lock the found filemon structure. */
+ filemon_filemon_lock(filemon);
+
+ copyinstr(uap->path, filemon->fname1,
+ sizeof(filemon->fname1), &done);
+
+ filemon->fname2[0] = '\0';
+ if (filemon->fname1[0] != '/' && uap->fd != AT_FDCWD) {
+ /*
+ * rats - we cannot do too much about this.
+ * the trace should show a dir we read
+ * recently.. output an A record as a clue
+ * until we can do better.
+ */
+ len = snprintf(filemon->msgbufr,
+ sizeof(filemon->msgbufr), "A %d %s\n",
+ curproc->p_pid, filemon->fname1);
+ filemon_output(filemon, filemon->msgbufr, len);
+ }
+ if (uap->flag & O_RDWR) {
+ /*
+ * We'll get the W record below, but need
+ * to also output an R to distingish from
+ * O_WRONLY.
+ */
+ len = snprintf(filemon->msgbufr,
+ sizeof(filemon->msgbufr), "R %d %s%s\n",
+ curproc->p_pid, filemon->fname2, filemon->fname1);
+ filemon_output(filemon, filemon->msgbufr, len);
+ }
+
+
+ len = snprintf(filemon->msgbufr,
+ sizeof(filemon->msgbufr), "%c %d %s%s\n",
+ (uap->flag & O_ACCMODE) ? 'W':'R',
+ curproc->p_pid, filemon->fname2, filemon->fname1);
+ filemon_output(filemon, filemon->msgbufr, len);
+
+ /* Unlock the found filemon structure. */
+ filemon_filemon_unlock(filemon);
+ }
+
+ /* Release the read lock. */
+ filemon_unlock_read();
+ }
+
+ return (ret);
+}
+
+static int
filemon_wrapper_rename(struct thread *td, struct rename_args *uap)
{
int ret;
@@ -669,6 +737,7 @@ filemon_wrapper_install(void)
sv_table[SYS_execve].sy_call = (sy_call_t *) filemon_wrapper_execve;
sv_table[SYS_fork].sy_call = (sy_call_t *) filemon_wrapper_fork;
sv_table[SYS_open].sy_call = (sy_call_t *) filemon_wrapper_open;
+ sv_table[SYS_openat].sy_call = (sy_call_t *) filemon_wrapper_openat;
sv_table[SYS_rename].sy_call = (sy_call_t *) filemon_wrapper_rename;
sv_table[SYS_stat].sy_call = (sy_call_t *) filemon_wrapper_stat;
sv_table[SYS_unlink].sy_call = (sy_call_t *) filemon_wrapper_unlink;
@@ -687,6 +756,7 @@ filemon_wrapper_install(void)
sv_table[FREEBSD32_SYS_freebsd32_execve].sy_call = (sy_call_t *) filemon_wrapper_freebsd32_execve;
sv_table[FREEBSD32_SYS_fork].sy_call = (sy_call_t *) filemon_wrapper_fork;
sv_table[FREEBSD32_SYS_open].sy_call = (sy_call_t *) filemon_wrapper_open;
+ sv_table[FREEBSD32_SYS_openat].sy_call = (sy_call_t *) filemon_wrapper_openat;
sv_table[FREEBSD32_SYS_rename].sy_call = (sy_call_t *) filemon_wrapper_rename;
sv_table[FREEBSD32_SYS_freebsd32_stat].sy_call = (sy_call_t *) filemon_wrapper_freebsd32_stat;
sv_table[FREEBSD32_SYS_unlink].sy_call = (sy_call_t *) filemon_wrapper_unlink;
@@ -713,6 +783,7 @@ filemon_wrapper_deinstall(void)
sv_table[SYS_execve].sy_call = (sy_call_t *)sys_execve;
sv_table[SYS_fork].sy_call = (sy_call_t *)sys_fork;
sv_table[SYS_open].sy_call = (sy_call_t *)sys_open;
+ sv_table[SYS_openat].sy_call = (sy_call_t *)sys_openat;
sv_table[SYS_rename].sy_call = (sy_call_t *)sys_rename;
sv_table[SYS_stat].sy_call = (sy_call_t *)sys_stat;
sv_table[SYS_unlink].sy_call = (sy_call_t *)sys_unlink;
@@ -731,6 +802,7 @@ filemon_wrapper_deinstall(void)
sv_table[FREEBSD32_SYS_freebsd32_execve].sy_call = (sy_call_t *)freebsd32_execve;
sv_table[FREEBSD32_SYS_fork].sy_call = (sy_call_t *)sys_fork;
sv_table[FREEBSD32_SYS_open].sy_call = (sy_call_t *)sys_open;
+ sv_table[FREEBSD32_SYS_openat].sy_call = (sy_call_t *)sys_openat;
sv_table[FREEBSD32_SYS_rename].sy_call = (sy_call_t *)sys_rename;
sv_table[FREEBSD32_SYS_freebsd32_stat].sy_call = (sy_call_t *)freebsd32_stat;
sv_table[FREEBSD32_SYS_unlink].sy_call = (sy_call_t *)sys_unlink;
diff --git a/sys/dev/gpio/ofw_gpiobus.c b/sys/dev/gpio/ofw_gpiobus.c
index 6646b7d..1dbb526 100644
--- a/sys/dev/gpio/ofw_gpiobus.c
+++ b/sys/dev/gpio/ofw_gpiobus.c
@@ -56,6 +56,14 @@ ofw_gpiobus_add_fdt_child(device_t bus, const char *drvname, phandle_t child)
struct ofw_gpiobus_devinfo *dinfo;
/*
+ * Check to see if we already have a child for @p child, and if so
+ * return it.
+ */
+ childdev = ofw_bus_find_child_device_by_phandle(bus, child);
+ if (childdev != NULL)
+ return (childdev);
+
+ /*
* Set up the GPIO child and OFW bus layer devinfo and add it to bus.
*/
childdev = device_add_child(bus, drvname, -1);
diff --git a/sys/dev/hwpmc/hwpmc_armv7.c b/sys/dev/hwpmc/hwpmc_armv7.c
index 66d4971..469eca8 100644
--- a/sys/dev/hwpmc/hwpmc_armv7.c
+++ b/sys/dev/hwpmc/hwpmc_armv7.c
@@ -39,9 +39,6 @@ __FBSDID("$FreeBSD$");
#include <machine/pmc_mdep.h>
#include <machine/cpu.h>
-#define CPU_ID_CORTEX_VER_MASK 0xff
-#define CPU_ID_CORTEX_VER_SHIFT 4
-
static int armv7_npmcs;
struct armv7_event_code_map {
@@ -49,49 +46,11 @@ struct armv7_event_code_map {
uint8_t pe_code;
};
-const struct armv7_event_code_map armv7_event_codes[] = {
- { PMC_EV_ARMV7_PMNC_SW_INCR, 0x00 },
- { PMC_EV_ARMV7_L1_ICACHE_REFILL, 0x01 },
- { PMC_EV_ARMV7_ITLB_REFILL, 0x02 },
- { PMC_EV_ARMV7_L1_DCACHE_REFILL, 0x03 },
- { PMC_EV_ARMV7_L1_DCACHE_ACCESS, 0x04 },
- { PMC_EV_ARMV7_DTLB_REFILL, 0x05 },
- { PMC_EV_ARMV7_MEM_READ, 0x06 },
- { PMC_EV_ARMV7_MEM_WRITE, 0x07 },
- { PMC_EV_ARMV7_INSTR_EXECUTED, 0x08 },
- { PMC_EV_ARMV7_EXC_TAKEN, 0x09 },
- { PMC_EV_ARMV7_EXC_EXECUTED, 0x0A },
- { PMC_EV_ARMV7_CID_WRITE, 0x0B },
- { PMC_EV_ARMV7_PC_WRITE, 0x0C },
- { PMC_EV_ARMV7_PC_IMM_BRANCH, 0x0D },
- { PMC_EV_ARMV7_PC_PROC_RETURN, 0x0E },
- { PMC_EV_ARMV7_MEM_UNALIGNED_ACCESS, 0x0F },
- { PMC_EV_ARMV7_PC_BRANCH_MIS_PRED, 0x10 },
- { PMC_EV_ARMV7_CLOCK_CYCLES, 0x11 },
- { PMC_EV_ARMV7_PC_BRANCH_PRED, 0x12 },
- { PMC_EV_ARMV7_MEM_ACCESS, 0x13 },
- { PMC_EV_ARMV7_L1_ICACHE_ACCESS, 0x14 },
- { PMC_EV_ARMV7_L1_DCACHE_WB, 0x15 },
- { PMC_EV_ARMV7_L2_CACHE_ACCESS, 0x16 },
- { PMC_EV_ARMV7_L2_CACHE_REFILL, 0x17 },
- { PMC_EV_ARMV7_L2_CACHE_WB, 0x18 },
- { PMC_EV_ARMV7_BUS_ACCESS, 0x19 },
- { PMC_EV_ARMV7_MEM_ERROR, 0x1A },
- { PMC_EV_ARMV7_INSTR_SPEC, 0x1B },
- { PMC_EV_ARMV7_TTBR_WRITE, 0x1C },
- { PMC_EV_ARMV7_BUS_CYCLES, 0x1D },
- { PMC_EV_ARMV7_CPU_CYCLES, 0xFF },
-};
-
-const int armv7_event_codes_size =
- sizeof(armv7_event_codes) / sizeof(armv7_event_codes[0]);
-
/*
* Per-processor information.
*/
struct armv7_cpu {
struct pmc_hw *pc_armv7pmcs;
- int cortex_ver;
};
static struct armv7_cpu **armv7_pcpu;
@@ -173,10 +132,10 @@ static int
armv7_allocate_pmc(int cpu, int ri, struct pmc *pm,
const struct pmc_op_pmcallocate *a)
{
- uint32_t caps, config;
struct armv7_cpu *pac;
enum pmc_event pe;
- int i;
+ uint32_t config;
+ uint32_t caps;
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[armv7,%d] illegal CPU value %d", __LINE__, cpu));
@@ -190,18 +149,10 @@ armv7_allocate_pmc(int cpu, int ri, struct pmc *pm,
return (EINVAL);
pe = a->pm_ev;
- for (i = 0; i < armv7_event_codes_size; i++) {
- if (armv7_event_codes[i].pe_ev == pe) {
- config = armv7_event_codes[i].pe_code;
- break;
- }
- }
- if (i == armv7_event_codes_size)
- return EINVAL;
-
+ config = (pe & EVENT_ID_MASK);
pm->pm_md.pm_armv7.pm_armv7_evsel = config;
- PMCDBG2(MDP,ALL,2,"armv7-allocate ri=%d -> config=0x%x", ri, config);
+ PMCDBG2(MDP, ALL, 2, "armv7-allocate ri=%d -> config=0x%x", ri, config);
return 0;
}
@@ -225,7 +176,7 @@ armv7_read_pmc(int cpu, int ri, pmc_value_t *v)
else
tmp = armv7_pmcn_read(ri);
- PMCDBG2(MDP,REA,2,"armv7-read id=%d -> %jd", ri, tmp);
+ PMCDBG2(MDP, REA, 2, "armv7-read id=%d -> %jd", ri, tmp);
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
*v = ARMV7_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp);
else
@@ -249,7 +200,7 @@ armv7_write_pmc(int cpu, int ri, pmc_value_t v)
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
v = ARMV7_RELOAD_COUNT_TO_PERFCTR_VALUE(v);
- PMCDBG3(MDP,WRI,1,"armv7-write cpu=%d ri=%d v=%jx", cpu, ri, v);
+ PMCDBG3(MDP, WRI, 1, "armv7-write cpu=%d ri=%d v=%jx", cpu, ri, v);
if (pm->pm_md.pm_armv7.pm_armv7_evsel == 0xFF)
cp15_pmccntr_set(v);
@@ -264,7 +215,7 @@ armv7_config_pmc(int cpu, int ri, struct pmc *pm)
{
struct pmc_hw *phw;
- PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
+ PMCDBG3(MDP, CFG, 1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[armv7,%d] illegal CPU value %d", __LINE__, cpu));
@@ -457,20 +408,15 @@ armv7_pcpu_init(struct pmc_mdep *md, int cpu)
struct pmc_cpu *pc;
uint32_t pmnc;
int first_ri;
- int cpuid;
int i;
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[armv7,%d] wrong cpu number %d", __LINE__, cpu));
- PMCDBG1(MDP,INI,1,"armv7-init cpu=%d", cpu);
+ PMCDBG1(MDP, INI, 1, "armv7-init cpu=%d", cpu);
armv7_pcpu[cpu] = pac = malloc(sizeof(struct armv7_cpu), M_PMC,
M_WAITOK|M_ZERO);
- cpuid = cpu_ident();
- pac->cortex_ver = (cpuid >> CPU_ID_CORTEX_VER_SHIFT) & \
- CPU_ID_CORTEX_VER_MASK;
-
pac->pc_armv7pmcs = malloc(sizeof(struct pmc_hw) * armv7_npmcs,
M_PMC, M_WAITOK|M_ZERO);
pc = pmc_pcpu[cpu];
@@ -509,14 +455,15 @@ pmc_armv7_initialize()
{
struct pmc_mdep *pmc_mdep;
struct pmc_classdep *pcd;
+ int idcode;
int reg;
reg = cp15_pmcr_get();
-
armv7_npmcs = (reg >> ARMV7_PMNC_N_SHIFT) & \
ARMV7_PMNC_N_MASK;
+ idcode = (reg & ARMV7_IDCODE_MASK) >> ARMV7_IDCODE_SHIFT;
- PMCDBG1(MDP,INI,1,"armv7-init npmcs=%d", armv7_npmcs);
+ PMCDBG1(MDP, INI, 1, "armv7-init npmcs=%d", armv7_npmcs);
/*
* Allocate space for pointers to PMC HW descriptors and for
@@ -527,7 +474,20 @@ pmc_armv7_initialize()
/* Just one class */
pmc_mdep = pmc_mdep_alloc(1);
- pmc_mdep->pmd_cputype = PMC_CPU_ARMV7;
+
+ switch (idcode) {
+ case ARMV7_IDCODE_CORTEX_A9:
+ pmc_mdep->pmd_cputype = PMC_CPU_ARMV7_CORTEX_A9;
+ break;
+ default:
+ case ARMV7_IDCODE_CORTEX_A8:
+ /*
+ * On A8 we implemented common events only,
+ * so use it for the rest of machines.
+ */
+ pmc_mdep->pmd_cputype = PMC_CPU_ARMV7_CORTEX_A8;
+ break;
+ }
pcd = &pmc_mdep->pmd_classdep[PMC_MDEP_CLASS_INDEX_ARMV7];
pcd->pcd_caps = ARMV7_PMC_CAPS;
diff --git a/sys/dev/hwpmc/hwpmc_armv7.h b/sys/dev/hwpmc/hwpmc_armv7.h
index 35f7d5b..5282345f 100644
--- a/sys/dev/hwpmc/hwpmc_armv7.h
+++ b/sys/dev/hwpmc/hwpmc_armv7.h
@@ -48,9 +48,14 @@
#define ARMV7_PMNC_N_SHIFT 11 /* Number of counters implemented */
#define ARMV7_PMNC_N_MASK 0x1f
#define ARMV7_PMNC_MASK 0x3f /* Writable bits */
+#define ARMV7_IDCODE_SHIFT 16 /* Identification code */
+#define ARMV7_IDCODE_MASK (0xff << ARMV7_IDCODE_SHIFT)
+#define ARMV7_IDCODE_CORTEX_A9 9
+#define ARMV7_IDCODE_CORTEX_A8 8
#define ARMV7_RELOAD_COUNT_TO_PERFCTR_VALUE(R) (-(R))
#define ARMV7_PERFCTR_VALUE_TO_RELOAD_COUNT(P) (-(P))
+#define EVENT_ID_MASK 0xFF
#ifdef _KERNEL
/* MD extension for 'struct pmc' */
diff --git a/sys/dev/hwpmc/pmc_events.h b/sys/dev/hwpmc/pmc_events.h
index 467367f..96dc900 100644
--- a/sys/dev/hwpmc/pmc_events.h
+++ b/sys/dev/hwpmc/pmc_events.h
@@ -4766,41 +4766,342 @@ __PMC_EV_ALIAS("IMPC_C0H_TRK_REQUEST.ALL", UCP_EVENT_84H_01H)
* ARMv7 Events
*/
-#define __PMC_EV_ARMV7() \
- __PMC_EV(ARMV7, PMNC_SW_INCR) \
- __PMC_EV(ARMV7, L1_ICACHE_REFILL) \
- __PMC_EV(ARMV7, ITLB_REFILL) \
- __PMC_EV(ARMV7, L1_DCACHE_REFILL) \
- __PMC_EV(ARMV7, L1_DCACHE_ACCESS) \
- __PMC_EV(ARMV7, DTLB_REFILL) \
- __PMC_EV(ARMV7, MEM_READ) \
- __PMC_EV(ARMV7, MEM_WRITE) \
- __PMC_EV(ARMV7, INSTR_EXECUTED) \
- __PMC_EV(ARMV7, EXC_TAKEN) \
- __PMC_EV(ARMV7, EXC_EXECUTED) \
- __PMC_EV(ARMV7, CID_WRITE) \
- __PMC_EV(ARMV7, PC_WRITE) \
- __PMC_EV(ARMV7, PC_IMM_BRANCH) \
- __PMC_EV(ARMV7, PC_PROC_RETURN) \
- __PMC_EV(ARMV7, MEM_UNALIGNED_ACCESS) \
- __PMC_EV(ARMV7, PC_BRANCH_MIS_PRED) \
- __PMC_EV(ARMV7, CLOCK_CYCLES) \
- __PMC_EV(ARMV7, PC_BRANCH_PRED) \
- __PMC_EV(ARMV7, MEM_ACCESS) \
- __PMC_EV(ARMV7, L1_ICACHE_ACCESS) \
- __PMC_EV(ARMV7, L1_DCACHE_WB) \
- __PMC_EV(ARMV7, L2_CACHE_ACCESS) \
- __PMC_EV(ARMV7, L2_CACHE_REFILL) \
- __PMC_EV(ARMV7, L2_CACHE_WB) \
- __PMC_EV(ARMV7, BUS_ACCESS) \
- __PMC_EV(ARMV7, MEM_ERROR) \
- __PMC_EV(ARMV7, INSTR_SPEC) \
- __PMC_EV(ARMV7, TTBR_WRITE) \
- __PMC_EV(ARMV7, BUS_CYCLES) \
- __PMC_EV(ARMV7, CPU_CYCLES)
+#define __PMC_EV_ARMV7() \
+ __PMC_EV(ARMV7, EVENT_00H) \
+ __PMC_EV(ARMV7, EVENT_01H) \
+ __PMC_EV(ARMV7, EVENT_02H) \
+ __PMC_EV(ARMV7, EVENT_03H) \
+ __PMC_EV(ARMV7, EVENT_04H) \
+ __PMC_EV(ARMV7, EVENT_05H) \
+ __PMC_EV(ARMV7, EVENT_06H) \
+ __PMC_EV(ARMV7, EVENT_07H) \
+ __PMC_EV(ARMV7, EVENT_08H) \
+ __PMC_EV(ARMV7, EVENT_09H) \
+ __PMC_EV(ARMV7, EVENT_0AH) \
+ __PMC_EV(ARMV7, EVENT_0BH) \
+ __PMC_EV(ARMV7, EVENT_0CH) \
+ __PMC_EV(ARMV7, EVENT_0DH) \
+ __PMC_EV(ARMV7, EVENT_0EH) \
+ __PMC_EV(ARMV7, EVENT_0FH) \
+ __PMC_EV(ARMV7, EVENT_10H) \
+ __PMC_EV(ARMV7, EVENT_11H) \
+ __PMC_EV(ARMV7, EVENT_12H) \
+ __PMC_EV(ARMV7, EVENT_13H) \
+ __PMC_EV(ARMV7, EVENT_14H) \
+ __PMC_EV(ARMV7, EVENT_15H) \
+ __PMC_EV(ARMV7, EVENT_16H) \
+ __PMC_EV(ARMV7, EVENT_17H) \
+ __PMC_EV(ARMV7, EVENT_18H) \
+ __PMC_EV(ARMV7, EVENT_19H) \
+ __PMC_EV(ARMV7, EVENT_1AH) \
+ __PMC_EV(ARMV7, EVENT_1BH) \
+ __PMC_EV(ARMV7, EVENT_1CH) \
+ __PMC_EV(ARMV7, EVENT_1DH) \
+ __PMC_EV(ARMV7, EVENT_1EH) \
+ __PMC_EV(ARMV7, EVENT_1FH) \
+ __PMC_EV(ARMV7, EVENT_20H) \
+ __PMC_EV(ARMV7, EVENT_21H) \
+ __PMC_EV(ARMV7, EVENT_22H) \
+ __PMC_EV(ARMV7, EVENT_23H) \
+ __PMC_EV(ARMV7, EVENT_24H) \
+ __PMC_EV(ARMV7, EVENT_25H) \
+ __PMC_EV(ARMV7, EVENT_26H) \
+ __PMC_EV(ARMV7, EVENT_27H) \
+ __PMC_EV(ARMV7, EVENT_28H) \
+ __PMC_EV(ARMV7, EVENT_29H) \
+ __PMC_EV(ARMV7, EVENT_2AH) \
+ __PMC_EV(ARMV7, EVENT_2BH) \
+ __PMC_EV(ARMV7, EVENT_2CH) \
+ __PMC_EV(ARMV7, EVENT_2DH) \
+ __PMC_EV(ARMV7, EVENT_2EH) \
+ __PMC_EV(ARMV7, EVENT_2FH) \
+ __PMC_EV(ARMV7, EVENT_30H) \
+ __PMC_EV(ARMV7, EVENT_31H) \
+ __PMC_EV(ARMV7, EVENT_32H) \
+ __PMC_EV(ARMV7, EVENT_33H) \
+ __PMC_EV(ARMV7, EVENT_34H) \
+ __PMC_EV(ARMV7, EVENT_35H) \
+ __PMC_EV(ARMV7, EVENT_36H) \
+ __PMC_EV(ARMV7, EVENT_37H) \
+ __PMC_EV(ARMV7, EVENT_38H) \
+ __PMC_EV(ARMV7, EVENT_39H) \
+ __PMC_EV(ARMV7, EVENT_3AH) \
+ __PMC_EV(ARMV7, EVENT_3BH) \
+ __PMC_EV(ARMV7, EVENT_3CH) \
+ __PMC_EV(ARMV7, EVENT_3DH) \
+ __PMC_EV(ARMV7, EVENT_3EH) \
+ __PMC_EV(ARMV7, EVENT_3FH) \
+ __PMC_EV(ARMV7, EVENT_40H) \
+ __PMC_EV(ARMV7, EVENT_41H) \
+ __PMC_EV(ARMV7, EVENT_42H) \
+ __PMC_EV(ARMV7, EVENT_43H) \
+ __PMC_EV(ARMV7, EVENT_44H) \
+ __PMC_EV(ARMV7, EVENT_45H) \
+ __PMC_EV(ARMV7, EVENT_46H) \
+ __PMC_EV(ARMV7, EVENT_47H) \
+ __PMC_EV(ARMV7, EVENT_48H) \
+ __PMC_EV(ARMV7, EVENT_49H) \
+ __PMC_EV(ARMV7, EVENT_4AH) \
+ __PMC_EV(ARMV7, EVENT_4BH) \
+ __PMC_EV(ARMV7, EVENT_4CH) \
+ __PMC_EV(ARMV7, EVENT_4DH) \
+ __PMC_EV(ARMV7, EVENT_4EH) \
+ __PMC_EV(ARMV7, EVENT_4FH) \
+ __PMC_EV(ARMV7, EVENT_50H) \
+ __PMC_EV(ARMV7, EVENT_51H) \
+ __PMC_EV(ARMV7, EVENT_52H) \
+ __PMC_EV(ARMV7, EVENT_53H) \
+ __PMC_EV(ARMV7, EVENT_54H) \
+ __PMC_EV(ARMV7, EVENT_55H) \
+ __PMC_EV(ARMV7, EVENT_56H) \
+ __PMC_EV(ARMV7, EVENT_57H) \
+ __PMC_EV(ARMV7, EVENT_58H) \
+ __PMC_EV(ARMV7, EVENT_59H) \
+ __PMC_EV(ARMV7, EVENT_5AH) \
+ __PMC_EV(ARMV7, EVENT_5BH) \
+ __PMC_EV(ARMV7, EVENT_5CH) \
+ __PMC_EV(ARMV7, EVENT_5DH) \
+ __PMC_EV(ARMV7, EVENT_5EH) \
+ __PMC_EV(ARMV7, EVENT_5FH) \
+ __PMC_EV(ARMV7, EVENT_60H) \
+ __PMC_EV(ARMV7, EVENT_61H) \
+ __PMC_EV(ARMV7, EVENT_62H) \
+ __PMC_EV(ARMV7, EVENT_63H) \
+ __PMC_EV(ARMV7, EVENT_64H) \
+ __PMC_EV(ARMV7, EVENT_65H) \
+ __PMC_EV(ARMV7, EVENT_66H) \
+ __PMC_EV(ARMV7, EVENT_67H) \
+ __PMC_EV(ARMV7, EVENT_68H) \
+ __PMC_EV(ARMV7, EVENT_69H) \
+ __PMC_EV(ARMV7, EVENT_6AH) \
+ __PMC_EV(ARMV7, EVENT_6BH) \
+ __PMC_EV(ARMV7, EVENT_6CH) \
+ __PMC_EV(ARMV7, EVENT_6DH) \
+ __PMC_EV(ARMV7, EVENT_6EH) \
+ __PMC_EV(ARMV7, EVENT_6FH) \
+ __PMC_EV(ARMV7, EVENT_70H) \
+ __PMC_EV(ARMV7, EVENT_71H) \
+ __PMC_EV(ARMV7, EVENT_72H) \
+ __PMC_EV(ARMV7, EVENT_73H) \
+ __PMC_EV(ARMV7, EVENT_74H) \
+ __PMC_EV(ARMV7, EVENT_75H) \
+ __PMC_EV(ARMV7, EVENT_76H) \
+ __PMC_EV(ARMV7, EVENT_77H) \
+ __PMC_EV(ARMV7, EVENT_78H) \
+ __PMC_EV(ARMV7, EVENT_79H) \
+ __PMC_EV(ARMV7, EVENT_7AH) \
+ __PMC_EV(ARMV7, EVENT_7BH) \
+ __PMC_EV(ARMV7, EVENT_7CH) \
+ __PMC_EV(ARMV7, EVENT_7DH) \
+ __PMC_EV(ARMV7, EVENT_7EH) \
+ __PMC_EV(ARMV7, EVENT_7FH) \
+ __PMC_EV(ARMV7, EVENT_80H) \
+ __PMC_EV(ARMV7, EVENT_81H) \
+ __PMC_EV(ARMV7, EVENT_82H) \
+ __PMC_EV(ARMV7, EVENT_83H) \
+ __PMC_EV(ARMV7, EVENT_84H) \
+ __PMC_EV(ARMV7, EVENT_85H) \
+ __PMC_EV(ARMV7, EVENT_86H) \
+ __PMC_EV(ARMV7, EVENT_87H) \
+ __PMC_EV(ARMV7, EVENT_88H) \
+ __PMC_EV(ARMV7, EVENT_89H) \
+ __PMC_EV(ARMV7, EVENT_8AH) \
+ __PMC_EV(ARMV7, EVENT_8BH) \
+ __PMC_EV(ARMV7, EVENT_8CH) \
+ __PMC_EV(ARMV7, EVENT_8DH) \
+ __PMC_EV(ARMV7, EVENT_8EH) \
+ __PMC_EV(ARMV7, EVENT_8FH) \
+ __PMC_EV(ARMV7, EVENT_90H) \
+ __PMC_EV(ARMV7, EVENT_91H) \
+ __PMC_EV(ARMV7, EVENT_92H) \
+ __PMC_EV(ARMV7, EVENT_93H) \
+ __PMC_EV(ARMV7, EVENT_94H) \
+ __PMC_EV(ARMV7, EVENT_95H) \
+ __PMC_EV(ARMV7, EVENT_96H) \
+ __PMC_EV(ARMV7, EVENT_97H) \
+ __PMC_EV(ARMV7, EVENT_98H) \
+ __PMC_EV(ARMV7, EVENT_99H) \
+ __PMC_EV(ARMV7, EVENT_9AH) \
+ __PMC_EV(ARMV7, EVENT_9BH) \
+ __PMC_EV(ARMV7, EVENT_9CH) \
+ __PMC_EV(ARMV7, EVENT_9DH) \
+ __PMC_EV(ARMV7, EVENT_9EH) \
+ __PMC_EV(ARMV7, EVENT_9FH) \
+ __PMC_EV(ARMV7, EVENT_A0H) \
+ __PMC_EV(ARMV7, EVENT_A1H) \
+ __PMC_EV(ARMV7, EVENT_A2H) \
+ __PMC_EV(ARMV7, EVENT_A3H) \
+ __PMC_EV(ARMV7, EVENT_A4H) \
+ __PMC_EV(ARMV7, EVENT_A5H) \
+ __PMC_EV(ARMV7, EVENT_A6H) \
+ __PMC_EV(ARMV7, EVENT_A7H) \
+ __PMC_EV(ARMV7, EVENT_A8H) \
+ __PMC_EV(ARMV7, EVENT_A9H) \
+ __PMC_EV(ARMV7, EVENT_AAH) \
+ __PMC_EV(ARMV7, EVENT_ABH) \
+ __PMC_EV(ARMV7, EVENT_ACH) \
+ __PMC_EV(ARMV7, EVENT_ADH) \
+ __PMC_EV(ARMV7, EVENT_AEH) \
+ __PMC_EV(ARMV7, EVENT_AFH) \
+ __PMC_EV(ARMV7, EVENT_B0H) \
+ __PMC_EV(ARMV7, EVENT_B1H) \
+ __PMC_EV(ARMV7, EVENT_B2H) \
+ __PMC_EV(ARMV7, EVENT_B3H) \
+ __PMC_EV(ARMV7, EVENT_B4H) \
+ __PMC_EV(ARMV7, EVENT_B5H) \
+ __PMC_EV(ARMV7, EVENT_B6H) \
+ __PMC_EV(ARMV7, EVENT_B7H) \
+ __PMC_EV(ARMV7, EVENT_B8H) \
+ __PMC_EV(ARMV7, EVENT_B9H) \
+ __PMC_EV(ARMV7, EVENT_BAH) \
+ __PMC_EV(ARMV7, EVENT_BBH) \
+ __PMC_EV(ARMV7, EVENT_BCH) \
+ __PMC_EV(ARMV7, EVENT_BDH) \
+ __PMC_EV(ARMV7, EVENT_BEH) \
+ __PMC_EV(ARMV7, EVENT_BFH) \
+ __PMC_EV(ARMV7, EVENT_C0H) \
+ __PMC_EV(ARMV7, EVENT_C1H) \
+ __PMC_EV(ARMV7, EVENT_C2H) \
+ __PMC_EV(ARMV7, EVENT_C3H) \
+ __PMC_EV(ARMV7, EVENT_C4H) \
+ __PMC_EV(ARMV7, EVENT_C5H) \
+ __PMC_EV(ARMV7, EVENT_C6H) \
+ __PMC_EV(ARMV7, EVENT_C7H) \
+ __PMC_EV(ARMV7, EVENT_C8H) \
+ __PMC_EV(ARMV7, EVENT_C9H) \
+ __PMC_EV(ARMV7, EVENT_CAH) \
+ __PMC_EV(ARMV7, EVENT_CBH) \
+ __PMC_EV(ARMV7, EVENT_CCH) \
+ __PMC_EV(ARMV7, EVENT_CDH) \
+ __PMC_EV(ARMV7, EVENT_CEH) \
+ __PMC_EV(ARMV7, EVENT_CFH) \
+ __PMC_EV(ARMV7, EVENT_D0H) \
+ __PMC_EV(ARMV7, EVENT_D1H) \
+ __PMC_EV(ARMV7, EVENT_D2H) \
+ __PMC_EV(ARMV7, EVENT_D3H) \
+ __PMC_EV(ARMV7, EVENT_D4H) \
+ __PMC_EV(ARMV7, EVENT_D5H) \
+ __PMC_EV(ARMV7, EVENT_D6H) \
+ __PMC_EV(ARMV7, EVENT_D7H) \
+ __PMC_EV(ARMV7, EVENT_D8H) \
+ __PMC_EV(ARMV7, EVENT_D9H) \
+ __PMC_EV(ARMV7, EVENT_DAH) \
+ __PMC_EV(ARMV7, EVENT_DBH) \
+ __PMC_EV(ARMV7, EVENT_DCH) \
+ __PMC_EV(ARMV7, EVENT_DDH) \
+ __PMC_EV(ARMV7, EVENT_DEH) \
+ __PMC_EV(ARMV7, EVENT_DFH) \
+ __PMC_EV(ARMV7, EVENT_E0H) \
+ __PMC_EV(ARMV7, EVENT_E1H) \
+ __PMC_EV(ARMV7, EVENT_E2H) \
+ __PMC_EV(ARMV7, EVENT_E3H) \
+ __PMC_EV(ARMV7, EVENT_E4H) \
+ __PMC_EV(ARMV7, EVENT_E5H) \
+ __PMC_EV(ARMV7, EVENT_E6H) \
+ __PMC_EV(ARMV7, EVENT_E7H) \
+ __PMC_EV(ARMV7, EVENT_E8H) \
+ __PMC_EV(ARMV7, EVENT_E9H) \
+ __PMC_EV(ARMV7, EVENT_EAH) \
+ __PMC_EV(ARMV7, EVENT_EBH) \
+ __PMC_EV(ARMV7, EVENT_ECH) \
+ __PMC_EV(ARMV7, EVENT_EDH) \
+ __PMC_EV(ARMV7, EVENT_EEH) \
+ __PMC_EV(ARMV7, EVENT_EFH) \
+ __PMC_EV(ARMV7, EVENT_F0H) \
+ __PMC_EV(ARMV7, EVENT_F1H) \
+ __PMC_EV(ARMV7, EVENT_F2H) \
+ __PMC_EV(ARMV7, EVENT_F3H) \
+ __PMC_EV(ARMV7, EVENT_F4H) \
+ __PMC_EV(ARMV7, EVENT_F5H) \
+ __PMC_EV(ARMV7, EVENT_F6H) \
+ __PMC_EV(ARMV7, EVENT_F7H) \
+ __PMC_EV(ARMV7, EVENT_F8H) \
+ __PMC_EV(ARMV7, EVENT_F9H) \
+ __PMC_EV(ARMV7, EVENT_FAH) \
+ __PMC_EV(ARMV7, EVENT_FBH) \
+ __PMC_EV(ARMV7, EVENT_FCH) \
+ __PMC_EV(ARMV7, EVENT_FDH) \
+ __PMC_EV(ARMV7, EVENT_FEH) \
+ __PMC_EV(ARMV7, EVENT_FFH)
-#define PMC_EV_ARMV7_FIRST PMC_EV_ARMV7_PMNC_SW_INCR
-#define PMC_EV_ARMV7_LAST PMC_EV_ARMV7_CPU_CYCLES
+#define PMC_EV_ARMV7_FIRST PMC_EV_ARMV7_EVENT_00H
+#define PMC_EV_ARMV7_LAST PMC_EV_ARMV7_EVENT_FFH
+
+#define __PMC_EV_ALIAS_ARMV7_COMMON() \
+ __PMC_EV_ALIAS("PMNC_SW_INCR", ARMV7_EVENT_00H) \
+ __PMC_EV_ALIAS("L1_ICACHE_REFILL", ARMV7_EVENT_01H) \
+ __PMC_EV_ALIAS("ITLB_REFILL", ARMV7_EVENT_02H) \
+ __PMC_EV_ALIAS("L1_DCACHE_REFILL", ARMV7_EVENT_03H) \
+ __PMC_EV_ALIAS("L1_DCACHE_ACCESS", ARMV7_EVENT_04H) \
+ __PMC_EV_ALIAS("DTLB_REFILL", ARMV7_EVENT_05H) \
+ __PMC_EV_ALIAS("MEM_READ", ARMV7_EVENT_06H) \
+ __PMC_EV_ALIAS("MEM_WRITE", ARMV7_EVENT_07H) \
+ __PMC_EV_ALIAS("INSTR_EXECUTED", ARMV7_EVENT_08H) \
+ __PMC_EV_ALIAS("EXC_TAKEN", ARMV7_EVENT_09H) \
+ __PMC_EV_ALIAS("EXC_EXECUTED", ARMV7_EVENT_0AH) \
+ __PMC_EV_ALIAS("CID_WRITE", ARMV7_EVENT_0BH) \
+ __PMC_EV_ALIAS("PC_WRITE", ARMV7_EVENT_0CH) \
+ __PMC_EV_ALIAS("PC_IMM_BRANCH", ARMV7_EVENT_0DH) \
+ __PMC_EV_ALIAS("PC_PROC_RETURN", ARMV7_EVENT_0EH) \
+ __PMC_EV_ALIAS("MEM_UNALIGNED_ACCESS", ARMV7_EVENT_0FH) \
+ __PMC_EV_ALIAS("PC_BRANCH_MIS_PRED", ARMV7_EVENT_10H) \
+ __PMC_EV_ALIAS("CLOCK_CYCLES", ARMV7_EVENT_11H) \
+ __PMC_EV_ALIAS("PC_BRANCH_PRED", ARMV7_EVENT_12H) \
+ __PMC_EV_ALIAS("MEM_ACCESS", ARMV7_EVENT_13H) \
+ __PMC_EV_ALIAS("L1_ICACHE_ACCESS", ARMV7_EVENT_14H) \
+ __PMC_EV_ALIAS("L1_DCACHE_WB", ARMV7_EVENT_15H) \
+ __PMC_EV_ALIAS("L2_CACHE_ACCESS", ARMV7_EVENT_16H) \
+ __PMC_EV_ALIAS("L2_CACHE_REFILL", ARMV7_EVENT_17H) \
+ __PMC_EV_ALIAS("L2_CACHE_WB", ARMV7_EVENT_18H) \
+ __PMC_EV_ALIAS("BUS_ACCESS", ARMV7_EVENT_19H) \
+ __PMC_EV_ALIAS("MEM_ERROR", ARMV7_EVENT_1AH) \
+ __PMC_EV_ALIAS("INSTR_SPEC", ARMV7_EVENT_1BH) \
+ __PMC_EV_ALIAS("TTBR_WRITE", ARMV7_EVENT_1CH) \
+ __PMC_EV_ALIAS("BUS_CYCLES", ARMV7_EVENT_1DH) \
+ __PMC_EV_ALIAS("CPU_CYCLES", ARMV7_EVENT_FFH)
+
+#define __PMC_EV_ALIAS_ARMV7_CORTEX_A8() \
+ __PMC_EV_ALIAS_ARMV7_COMMON()
+
+#define __PMC_EV_ALIAS_ARMV7_CORTEX_A9() \
+ __PMC_EV_ALIAS_ARMV7_COMMON() \
+ __PMC_EV_ALIAS("JAVA_BYTECODE", ARMV7_EVENT_40H) \
+ __PMC_EV_ALIAS("SOFTWARE_JAVA_BYTECODE", ARMV7_EVENT_41H) \
+ __PMC_EV_ALIAS("JAZELLE_BACKWARD_BRANCH", ARMV7_EVENT_42H) \
+ __PMC_EV_ALIAS("COHERENT_LINEFILL_MISSC", ARMV7_EVENT_50H) \
+ __PMC_EV_ALIAS("COHERENT_LINEFILL_HITC", ARMV7_EVENT_51H) \
+ __PMC_EV_ALIAS("INSTR_CACHE_DEPENDENT_STALL", ARMV7_EVENT_60H) \
+ __PMC_EV_ALIAS("DATA_CACHE_DEPENDENT_STALL", ARMV7_EVENT_61H) \
+ __PMC_EV_ALIAS("MAIN_TLB_MISS_STALL", ARMV7_EVENT_62H) \
+ __PMC_EV_ALIAS("STREX_PASSED", ARMV7_EVENT_63H) \
+ __PMC_EV_ALIAS("STREX_FAILED", ARMV7_EVENT_64H) \
+ __PMC_EV_ALIAS("DATA_EVICTION", ARMV7_EVENT_65H) \
+ __PMC_EV_ALIAS("ISSUE_DNOT_DISPATCH_ANY_INSTR", ARMV7_EVENT_66H) \
+ __PMC_EV_ALIAS("ISSUE_IS_EMPTY", ARMV7_EVENT_67H) \
+ __PMC_EV_ALIAS("MAIN_EXECUTION_UNIT_PIPE", ARMV7_EVENT_70H) \
+ __PMC_EV_ALIAS("SECOND_EXECUTION_UNIT_PIPE", ARMV7_EVENT_71H) \
+ __PMC_EV_ALIAS("LOAD_STORE_PIPE", ARMV7_EVENT_72H) \
+ __PMC_EV_ALIAS("FLOATING_POINT_INSTR_RENAMED", ARMV7_EVENT_73H) \
+ __PMC_EV_ALIAS("NEON_INSTRS_RENAMED", ARMV7_EVENT_74H) \
+ __PMC_EV_ALIAS("PLD_STALL", ARMV7_EVENT_80H) \
+ __PMC_EV_ALIAS("WRITE_STALL", ARMV7_EVENT_81H) \
+ __PMC_EV_ALIAS("INSTR_MAIN_TLB_MISS_STALL", ARMV7_EVENT_82H) \
+ __PMC_EV_ALIAS("DATA_MAIN_TLB_MISS_STALL", ARMV7_EVENT_83H) \
+ __PMC_EV_ALIAS("INSTR_MICRO_TLB_MISS_STALL", ARMV7_EVENT_84H) \
+ __PMC_EV_ALIAS("DATA_MICRO_TLB_MISS_STALL", ARMV7_EVENT_85H) \
+ __PMC_EV_ALIAS("DMB_STALL", ARMV7_EVENT_86H) \
+ __PMC_EV_ALIAS("INTEGER_CORE_CLOCK_ENABLED", ARMV7_EVENT_8AH) \
+ __PMC_EV_ALIAS("DATA_ENGINE_CLOCK_ENABLED", ARMV7_EVENT_8BH) \
+ __PMC_EV_ALIAS("ISB", ARMV7_EVENT_90H) \
+ __PMC_EV_ALIAS("DSB", ARMV7_EVENT_91H) \
+ __PMC_EV_ALIAS("DMB", ARMV7_EVENT_92H) \
+ __PMC_EV_ALIAS("EXTERNAL_INTERRUPT", ARMV7_EVENT_93H) \
+ __PMC_EV_ALIAS("PLE_CACHE_LINE_REQ_COMPLETED", ARMV7_EVENT_A0H) \
+ __PMC_EV_ALIAS("PLE_CACHE_LINE_REQ_SKIPPED", ARMV7_EVENT_A1H) \
+ __PMC_EV_ALIAS("PLE_FIFO_FLUSH", ARMV7_EVENT_A2H) \
+ __PMC_EV_ALIAS("PLE_REQUEST_COMPLETED", ARMV7_EVENT_A3H) \
+ __PMC_EV_ALIAS("PLE_FIFO_OVERFLOW", ARMV7_EVENT_A4H) \
+ __PMC_EV_ALIAS("PLE_REQUEST_PROGRAMMED", ARMV7_EVENT_A5H)
/*
* ARMv8 Events
diff --git a/sys/dev/ichsmb/ichsmb_pci.c b/sys/dev/ichsmb/ichsmb_pci.c
index ae8b179..00ba2c3 100644
--- a/sys/dev/ichsmb/ichsmb_pci.c
+++ b/sys/dev/ichsmb/ichsmb_pci.c
@@ -5,7 +5,7 @@
* Copyright (c) 2000 Whistle Communications, Inc.
* All rights reserved.
* Author: Archie Cobbs <archie@freebsd.org>
- *
+ *
* Subject to the following obligations and disclaimer of warranty, use and
* redistribution of this software, in source or object code forms, with or
* without modifications are expressly permitted by Whistle Communications;
@@ -16,7 +16,7 @@
* Communications, Inc. trademarks, including the mark "WHISTLE
* COMMUNICATIONS" on advertising, endorsements, or otherwise except as
* such appears in the above copyright notice or in the software.
- *
+ *
* THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
@@ -91,6 +91,7 @@ __FBSDID("$FreeBSD$");
#define ID_LPTLP 0x9c228086
#define ID_WCPT 0x8ca28086
#define ID_WCPTLP 0x9ca28086
+#define ID_WELLSBURG 0x8d228086
#define PCIS_SERIALBUS_SMBUS_PROGIF 0x00
@@ -212,6 +213,9 @@ ichsmb_pci_probe(device_t dev)
case ID_COLETOCRK:
device_set_desc(dev, "Intel Coleto Creek SMBus controller");
break;
+ case ID_WELLSBURG:
+ device_set_desc(dev, "Intel Wellsburg SMBus controller");
+ break;
default:
return (ENXIO);
}
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index 881f58a..46edd3e 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -2931,6 +2931,14 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
atp = isp_find_atpd(isp, tptr, ((ct_entry_t *)arg)->ct_fwhandle);
}
if (atp == NULL) {
+ /*
+ * In case of target mode disable at least ISP2532 return
+ * invalid zero ct_rxid value. Try to workaround that using
+ * tag_id from the CCB, pointed by valid ct_syshandle.
+ */
+ atp = isp_find_atpd(isp, tptr, ccb->csio.tag_id);
+ }
+ if (atp == NULL) {
rls_lun_statep(isp, tptr);
isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x after I/O", __func__, ccb->csio.tag_id);
return;
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index a04d446..f3cf2ae 100644
--- a/sys/dev/iwn/if_iwn.c
+++ b/sys/dev/iwn/if_iwn.c
@@ -232,6 +232,7 @@ static int iwn_tx_data(struct iwn_softc *, struct mbuf *,
static int iwn_tx_data_raw(struct iwn_softc *, struct mbuf *,
struct ieee80211_node *,
const struct ieee80211_bpf_params *params);
+static void iwn_xmit_task(void *arg0, int pending);
static int iwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
static void iwn_start(struct ifnet *);
@@ -682,6 +683,9 @@ iwn_attach(device_t dev)
TASK_INIT(&sc->sc_radioon_task, 0, iwn_radio_on, sc);
TASK_INIT(&sc->sc_radiooff_task, 0, iwn_radio_off, sc);
TASK_INIT(&sc->sc_panic_task, 0, iwn_panicked, sc);
+ TASK_INIT(&sc->sc_xmit_task, 0, iwn_xmit_task, sc);
+
+ mbufq_init(&sc->sc_xmit_queue, 1024);
sc->sc_tq = taskqueue_create("iwn_taskq", M_WAITOK,
taskqueue_thread_enqueue, &sc->sc_tq);
@@ -1360,6 +1364,28 @@ iwn_vap_delete(struct ieee80211vap *vap)
free(ivp, M_80211_VAP);
}
+static void
+iwn_xmit_queue_drain(struct iwn_softc *sc)
+{
+ struct mbuf *m;
+ struct ieee80211_node *ni;
+
+ IWN_LOCK_ASSERT(sc);
+ while ((m = mbufq_dequeue(&sc->sc_xmit_queue)) != NULL) {
+ ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
+ ieee80211_free_node(ni);
+ m_freem(m);
+ }
+}
+
+static int
+iwn_xmit_queue_enqueue(struct iwn_softc *sc, struct mbuf *m)
+{
+
+ IWN_LOCK_ASSERT(sc);
+ return (mbufq_enqueue(&sc->sc_xmit_queue, m));
+}
+
static int
iwn_detach(device_t dev)
{
@@ -1373,6 +1399,11 @@ iwn_detach(device_t dev)
if (ifp != NULL) {
ic = ifp->if_l2com;
+ /* Free the mbuf queue and node references */
+ IWN_LOCK(sc);
+ iwn_xmit_queue_drain(sc);
+ IWN_UNLOCK(sc);
+
ieee80211_draintask(ic, &sc->sc_reinit_task);
ieee80211_draintask(ic, &sc->sc_radioon_task);
ieee80211_draintask(ic, &sc->sc_radiooff_task);
@@ -2831,6 +2862,9 @@ iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
sc->rxon->filter &= ~htole32(IWN_FILTER_BSS);
sc->calib.state = IWN_CALIB_STATE_INIT;
+ /* Wait until we hear a beacon before we transmit */
+ sc->sc_beacon_wait = 1;
+
if ((error = iwn_auth(sc, vap)) != 0) {
device_printf(sc->sc_dev,
"%s: could not move to auth state\n", __func__);
@@ -2846,6 +2880,9 @@ iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
break;
}
+ /* Wait until we hear a beacon before we transmit */
+ sc->sc_beacon_wait = 1;
+
/*
* !RUN -> RUN requires setting the association id
* which is done with a firmware cmd. We also defer
@@ -2859,6 +2896,12 @@ iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
case IEEE80211_S_INIT:
sc->calib.state = IWN_CALIB_STATE_INIT;
+ /*
+ * Purge the xmit queue so we don't have old frames
+ * during a new association attempt.
+ */
+ sc->sc_beacon_wait = 0;
+ iwn_xmit_queue_drain(sc);
break;
default:
@@ -3066,6 +3109,32 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
}
}
+ /*
+ * If it's a beacon and we're waiting, then do the
+ * wakeup. This should unblock raw_xmit/start.
+ */
+ if (sc->sc_beacon_wait) {
+ uint8_t type, subtype;
+ /* NB: Re-assign wh */
+ wh = mtod(m, struct ieee80211_frame *);
+ type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+ subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+ /*
+ * This assumes at this point we've received our own
+ * beacon.
+ */
+ DPRINTF(sc, IWN_DEBUG_TRACE,
+ "%s: beacon_wait, type=%d, subtype=%d\n",
+ __func__, type, subtype);
+ if (type == IEEE80211_FC0_TYPE_MGT &&
+ subtype == IEEE80211_FC0_SUBTYPE_BEACON) {
+ DPRINTF(sc, IWN_DEBUG_TRACE | IWN_DEBUG_XMIT,
+ "%s: waking things up\n", __func__);
+ /* queue taskqueue to transmit! */
+ taskqueue_enqueue(sc->sc_tq, &sc->sc_xmit_task);
+ }
+ }
+
IWN_UNLOCK(sc);
/* Send the frame to the 802.11 layer. */
@@ -4802,6 +4871,51 @@ iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,
return 0;
}
+static void
+iwn_xmit_task(void *arg0, int pending)
+{
+ struct iwn_softc *sc = arg0;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211_node *ni;
+ struct mbuf *m;
+ int error;
+ struct ieee80211_bpf_params p;
+ int have_p;
+
+ DPRINTF(sc, IWN_DEBUG_XMIT, "%s: called\n", __func__);
+
+ IWN_LOCK(sc);
+ /*
+ * Dequeue frames, attempt to transmit,
+ * then disable beaconwait when we're done.
+ */
+ while ((m = mbufq_dequeue(&sc->sc_xmit_queue)) != NULL) {
+ have_p = 0;
+ ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
+
+ /* Get xmit params if appropriate */
+ if (ieee80211_get_xmit_params(m, &p) == 0)
+ have_p = 1;
+
+ DPRINTF(sc, IWN_DEBUG_XMIT, "%s: m=%p, have_p=%d\n",
+ __func__, m, have_p);
+
+ /* If we have xmit params, use them */
+ if (have_p)
+ error = iwn_tx_data_raw(sc, m, ni, &p);
+ else
+ error = iwn_tx_data(sc, m, ni);
+
+ if (error != 0) {
+ ieee80211_free_node(ni);
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ }
+ }
+
+ sc->sc_beacon_wait = 0;
+ IWN_UNLOCK(sc);
+}
+
static int
iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
@@ -4819,7 +4933,25 @@ iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return ENETDOWN;
}
+ /* XXX? net80211 doesn't set this on xmit'ed raw frames? */
+ m->m_pkthdr.rcvif = (void *) ni;
+
IWN_LOCK(sc);
+
+ /* queue frame if we have to */
+ if (sc->sc_beacon_wait) {
+ if (iwn_xmit_queue_enqueue(sc, m) != 0) {
+ m_freem(m);
+ ieee80211_free_node(ni);
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ IWN_UNLOCK(sc);
+ return (ENOBUFS);
+ }
+ /* Queued, so just return OK */
+ IWN_UNLOCK(sc);
+ return (0);
+ }
+
if (params == NULL) {
/*
* Legacy path; interpret frame contents to decide
@@ -4866,6 +4998,14 @@ iwn_start_locked(struct ifnet *ifp)
IWN_LOCK_ASSERT(sc);
+ /*
+ * If we're waiting for a beacon, we can just exit out here
+ * and wait for the taskqueue to be kicked.
+ */
+ if (sc->sc_beacon_wait) {
+ return;
+ }
+
DPRINTF(sc, IWN_DEBUG_XMIT, "%s: called\n", __func__);
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
diff --git a/sys/dev/iwn/if_iwnvar.h b/sys/dev/iwn/if_iwnvar.h
index b14158b..9366fc2 100644
--- a/sys/dev/iwn/if_iwnvar.h
+++ b/sys/dev/iwn/if_iwnvar.h
@@ -309,6 +309,7 @@ struct iwn_softc {
struct task sc_radioon_task;
struct task sc_radiooff_task;
struct task sc_panic_task;
+ struct task sc_xmit_task;
/* Taskqueue */
struct taskqueue *sc_tq;
@@ -385,6 +386,9 @@ struct iwn_softc {
/* Are we doing a scan? */
int sc_is_scanning;
+ /* Are we waiting for a beacon before xmit? */
+ int sc_beacon_wait;
+
struct ieee80211_tx_ampdu *qid2tap[IWN5000_NTXQUEUES];
int (*sc_ampdu_rx_start)(struct ieee80211_node *,
@@ -417,6 +421,13 @@ struct iwn_softc {
#define IWN_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8)
uint32_t ucode_rev;
+
+ /*
+ * Global queue for queuing xmit frames
+ * when we can't yet transmit (eg raw
+ * frames whilst waiting for beacons.)
+ */
+ struct mbufq sc_xmit_queue;
};
#define IWN_LOCK_INIT(_sc) \
diff --git a/sys/dev/ixl/if_ixl.c b/sys/dev/ixl/if_ixl.c
index 13a678c..1a36c2a 100644
--- a/sys/dev/ixl/if_ixl.c
+++ b/sys/dev/ixl/if_ixl.c
@@ -2551,7 +2551,7 @@ ixl_setup_interface(device_t dev, struct ixl_vsi *vsi)
}
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
ifp->if_mtu = ETHERMTU;
- ifp->if_baudrate = 4000000000; // ??
+ ifp->if_baudrate = IF_Gbps(40);
ifp->if_init = ixl_init;
ifp->if_softc = vsi;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
diff --git a/sys/dev/mii/mii.h b/sys/dev/mii/mii.h
index 668fb8f..fa1ec84 100644
--- a/sys/dev/mii/mii.h
+++ b/sys/dev/mii/mii.h
@@ -1,4 +1,4 @@
-/* $NetBSD: mii.h,v 1.9 2001/05/31 03:07:14 thorpej Exp $ */
+/* $NetBSD: mii.h,v 1.18 2014/06/16 14:43:22 msaitoh Exp $ */
/*-
* Copyright (c) 1997 Manuel Bouyer. All rights reserved.
@@ -87,7 +87,7 @@
/*
* Note that the EXTSTAT bit indicates that there is extended status
* info available in register 15, but 802.3 section 22.2.4.3 also
- * states that that all 1000 Mb/s capable PHYs will set this bit to 1.
+ * states that all 1000 Mb/s capable PHYs will set this bit to 1.
*/
#define BMSR_MEDIAMASK (BMSR_100T4|BMSR_100TXFDX|BMSR_100TXHDX| \
@@ -111,6 +111,7 @@
#define ANAR_NP 0x8000 /* Next page (ro) */
#define ANAR_ACK 0x4000 /* link partner abilities acknowledged (ro) */
#define ANAR_RF 0x2000 /* remote fault (ro) */
+ /* Annex 28B.2 */
#define ANAR_FC 0x0400 /* local device supports PAUSE */
#define ANAR_T4 0x0200 /* local device supports 100bT4 */
#define ANAR_TX_FD 0x0100 /* local device supports 100bTx FD */
@@ -123,6 +124,7 @@
#define ANAR_PAUSE_ASYM (2 << 10)
#define ANAR_PAUSE_TOWARDS (3 << 10)
+ /* Annex 28D */
#define ANAR_X_FD 0x0020 /* local device supports 1000BASE-X FD */
#define ANAR_X_HD 0x0040 /* local device supports 1000BASE-X HD */
#define ANAR_X_PAUSE_NONE (0 << 7)
@@ -184,12 +186,47 @@
#define GTSR_MAN_MS_FLT 0x8000 /* master/slave config fault */
#define GTSR_MS_RES 0x4000 /* result: 1 = master, 0 = slave */
#define GTSR_LRS 0x2000 /* local rx status, 1 = ok */
-#define GTSR_RRS 0x1000 /* remove rx status, 1 = ok */
+#define GTSR_RRS 0x1000 /* remote rx status, 1 = ok */
#define GTSR_LP_1000TFDX 0x0800 /* link partner 1000baseT FDX capable */
#define GTSR_LP_1000THDX 0x0400 /* link partner 1000baseT HDX capable */
#define GTSR_LP_ASM_DIR 0x0200 /* link partner asym. pause dir. capable */
#define GTSR_IDLE_ERR 0x00ff /* IDLE error count */
+#define MII_PSECR 0x0b /* PSE control register */
+#define PSECR_PACTLMASK 0x000c /* pair control mask */
+#define PSECR_PSEENMASK 0x0003 /* PSE enable mask */
+#define PSECR_PINOUTB 0x0008 /* PSE pinout Alternative B */
+#define PSECR_PINOUTA 0x0004 /* PSE pinout Alternative A */
+#define PSECR_FOPOWTST 0x0002 /* Force Power Test Mode */
+#define PSECR_PSEEN 0x0001 /* PSE Enabled */
+#define PSECR_PSEDIS 0x0000 /* PSE Disabled */
+
+#define MII_PSESR 0x0c /* PSE status register */
+#define PSESR_PWRDENIED 0x1000 /* Power Denied */
+#define PSESR_VALSIG 0x0800 /* Valid PD signature detected */
+#define PSESR_INVALSIG 0x0400 /* Invalid PD signature detected */
+#define PSESR_SHORTCIRC 0x0200 /* Short circuit condition detected */
+#define PSESR_OVERLOAD 0x0100 /* Overload condition detected */
+#define PSESR_MPSABSENT 0x0080 /* MPS absent condition detected */
+#define PSESR_PDCLMASK 0x0070 /* PD Class mask */
+#define PSESR_STATMASK 0x000e /* PSE Status mask */
+#define PSESR_PAIRCTABL 0x0001 /* PAIR Control Ability */
+#define PSESR_PDCL_4 (4 << 4) /* Class 4 */
+#define PSESR_PDCL_3 (3 << 4) /* Class 3 */
+#define PSESR_PDCL_2 (2 << 4) /* Class 2 */
+#define PSESR_PDCL_1 (1 << 4) /* Class 1 */
+#define PSESR_PDCL_0 (0 << 4) /* Class 0 */
+
+#define MII_MMDACR 0x0d /* MMD access control register */
+#define MMDACR_FUNCMASK 0xc000 /* function */
+#define MMDACR_DADDRMASK 0x001f /* device address */
+#define MMDACR_FN_ADDRESS (0 << 14) /* address */
+#define MMDACR_FN_DATANPI (1 << 14) /* data, no post increment */
+#define MMDACR_FN_DATAPIRW (2 << 14) /* data, post increment on r/w */
+#define MMDACR_FN_DATAPIW (3 << 14) /* data, post increment on wr only */
+
+#define MII_MMDAADR 0x0e /* MMD access address data register */
+
#define MII_EXTSR 0x0f /* Extended status register */
#define EXTSR_1000XFDX 0x8000 /* 1000X full-duplex capable */
#define EXTSR_1000XHDX 0x4000 /* 1000X half-duplex capable */
diff --git a/sys/dev/ofw/ofw_bus_subr.c b/sys/dev/ofw/ofw_bus_subr.c
index a9261ce..233675d 100644
--- a/sys/dev/ofw/ofw_bus_subr.c
+++ b/sys/dev/ofw/ofw_bus_subr.c
@@ -551,3 +551,44 @@ ofw_bus_find_compatible(phandle_t node, const char *onecompat)
}
return (0);
}
+
+/**
+ * @brief Return child of bus whose phandle is node
+ *
+ * A direct child of @p will be returned if it its phandle in the
+ * OFW tree is @p node. Otherwise, NULL is returned.
+ *
+ * @param bus The bus to examine
+ * @param node The phandle_t to look for.
+ */
+device_t
+ofw_bus_find_child_device_by_phandle(device_t bus, phandle_t node)
+{
+ device_t *children, retval, child;
+ int nkid, i;
+
+ /*
+ * Nothing can match the flag value for no node.
+ */
+ if (node == -1)
+ return (NULL);
+
+ /*
+ * Search the children for a match. We microoptimize
+ * a bit by not using ofw_bus_get since we already know
+ * the parent. We do not recurse.
+ */
+ if (device_get_children(bus, &children, &nkid) != 0)
+ return (NULL);
+ retval = NULL;
+ for (i = 0; i < nkid; i++) {
+ child = children[i];
+ if (OFW_BUS_GET_NODE(bus, child) == node) {
+ retval = child;
+ break;
+ }
+ }
+ free(children, M_TEMP);
+
+ return (retval);
+}
diff --git a/sys/dev/ofw/ofw_bus_subr.h b/sys/dev/ofw/ofw_bus_subr.h
index bbeda7f..c59a75d 100644
--- a/sys/dev/ofw/ofw_bus_subr.h
+++ b/sys/dev/ofw/ofw_bus_subr.h
@@ -107,4 +107,7 @@ phandle_t ofw_bus_find_compatible(phandle_t, const char *);
/* Helper to search for a child with a given name */
phandle_t ofw_bus_find_child(phandle_t, const char *);
+/* Helper routine to find a device_t child matchig a given phandle_t */
+device_t ofw_bus_find_child_device_by_phandle(device_t bus, phandle_t node);
+
#endif /* !_DEV_OFW_OFW_BUS_SUBR_H_ */
diff --git a/sys/dev/pci/pci_host_generic.c b/sys/dev/pci/pci_host_generic.c
new file mode 100644
index 0000000..04dc8d3
--- /dev/null
+++ b/sys/dev/pci/pci_host_generic.c
@@ -0,0 +1,626 @@
+/*-
+ * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
+ * Copyright (c) 2014 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under
+ * the sponsorship of 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.
+ */
+
+/* Generic ECAM PCIe driver */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/rman.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/cpuset.h>
+#include <sys/rwlock.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcib_private.h>
+#include <machine/cpu.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+#include <vm/vm_page.h>
+
+#include "pcib_if.h"
+
+/* Assembling ECAM Configuration Address */
+#define PCIE_BUS_SHIFT 20
+#define PCIE_SLOT_SHIFT 15
+#define PCIE_FUNC_SHIFT 12
+#define PCIE_BUS_MASK 0xFF
+#define PCIE_SLOT_MASK 0x1F
+#define PCIE_FUNC_MASK 0x07
+#define PCIE_REG_MASK 0xFFF
+
+#define PCIE_ADDR_OFFSET(bus, slot, func, reg) \
+ ((((bus) & PCIE_BUS_MASK) << PCIE_BUS_SHIFT) | \
+ (((slot) & PCIE_SLOT_MASK) << PCIE_SLOT_SHIFT) | \
+ (((func) & PCIE_FUNC_MASK) << PCIE_FUNC_SHIFT) | \
+ ((reg) & PCIE_REG_MASK))
+
+#define MAX_RANGES_TUPLES 5
+#define MIN_RANGES_TUPLES 2
+
+#define PCI_IO_WINDOW_OFFSET 0x1000
+#define PCI_IRQ_START 32
+#define PCI_IRQ_END (PCI_IRQ_START + 4)
+
+#define SPACE_CODE_SHIFT 24
+#define SPACE_CODE_MASK 0x3
+#define SPACE_CODE_IO_SPACE 0x1
+#define PROPS_CELL_SIZE 1
+#define PCI_ADDR_CELL_SIZE 2
+
+struct pcie_range {
+ uint64_t pci_base;
+ uint64_t phys_base;
+ uint64_t size;
+ uint64_t flags;
+#define FLAG_IO (1 << 0)
+#define FLAG_MEM (1 << 1)
+};
+
+struct generic_pcie_softc {
+ struct pcie_range ranges[MAX_RANGES_TUPLES];
+ int nranges;
+ struct rman mem_rman;
+ struct rman io_rman;
+ struct rman irq_rman;
+ struct resource *res;
+ struct resource *res1;
+ int ecam;
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ device_t dev;
+ bus_space_handle_t ioh;
+};
+
+/* Forward prototypes */
+
+static int generic_pcie_probe(device_t dev);
+static int generic_pcie_attach(device_t dev);
+static int parse_pci_mem_ranges(struct generic_pcie_softc *sc);
+static uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
+ u_int func, u_int reg, int bytes);
+static void generic_pcie_write_config(device_t dev, u_int bus, u_int slot,
+ u_int func, u_int reg, uint32_t val, int bytes);
+static int generic_pcie_maxslots(device_t dev);
+static int generic_pcie_read_ivar(device_t dev, device_t child, int index,
+ uintptr_t *result);
+static int generic_pcie_write_ivar(device_t dev, device_t child, int index,
+ uintptr_t value);
+static struct resource *generic_pcie_alloc_resource(device_t dev,
+ device_t child, int type, int *rid, u_long start, u_long end,
+ u_long count, u_int flags);
+static int generic_pcie_release_resource(device_t dev, device_t child,
+ int type, int rid, struct resource *res);
+
+static int
+generic_pcie_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (ofw_bus_is_compatible(dev, "pci-host-ecam-generic")) {
+ device_set_desc(dev, "Generic PCI host controller");
+ return (BUS_PROBE_DEFAULT);
+ }
+
+ return (ENXIO);
+}
+
+static int
+generic_pcie_attach(device_t dev)
+{
+ struct generic_pcie_softc *sc;
+ uint64_t phys_base;
+ uint64_t pci_base;
+ uint64_t size;
+ int error;
+ int tuple;
+ int rid;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ rid = 0;
+ sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+ if (sc->res == NULL) {
+ device_printf(dev, "could not map memory.\n");
+ return (ENXIO);
+ }
+
+ sc->bst = rman_get_bustag(sc->res);
+ sc->bsh = rman_get_bushandle(sc->res);
+
+ sc->mem_rman.rm_type = RMAN_ARRAY;
+ sc->mem_rman.rm_descr = "PCIe Memory";
+ sc->io_rman.rm_type = RMAN_ARRAY;
+ sc->io_rman.rm_descr = "PCIe IO window";
+
+ /* Retrieve 'ranges' property from FDT */
+ if (bootverbose)
+ device_printf(dev, "parsing FDT for ECAM%d:\n",
+ sc->ecam);
+ if (parse_pci_mem_ranges(sc))
+ return (ENXIO);
+
+ /* Initialize rman and allocate memory regions */
+ error = rman_init(&sc->mem_rman);
+ if (error) {
+ device_printf(dev, "rman_init() failed. error = %d\n", error);
+ return (error);
+ }
+
+ error = rman_init(&sc->io_rman);
+ if (error) {
+ device_printf(dev, "rman_init() failed. error = %d\n", error);
+ return (error);
+ }
+
+ for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
+ phys_base = sc->ranges[tuple].phys_base;
+ pci_base = sc->ranges[tuple].pci_base;
+ size = sc->ranges[tuple].size;
+ if (phys_base == 0 || size == 0)
+ continue; /* empty range element */
+ if (sc->ranges[tuple].flags & FLAG_MEM) {
+ error = rman_manage_region(&sc->mem_rman,
+ phys_base,
+ phys_base + size);
+ } else if (sc->ranges[tuple].flags & FLAG_IO) {
+ error = rman_manage_region(&sc->io_rman,
+ pci_base + PCI_IO_WINDOW_OFFSET,
+ pci_base + PCI_IO_WINDOW_OFFSET + size);
+ } else
+ continue;
+ if (error) {
+ device_printf(dev, "rman_manage_region() failed."
+ "error = %d\n", error);
+ rman_fini(&sc->mem_rman);
+ return (error);
+ }
+ }
+
+ /* TODO: get IRQ numbers from FDT */
+ sc->irq_rman.rm_type = RMAN_ARRAY;
+ sc->irq_rman.rm_descr = "Generic PCIe IRQs";
+ if (rman_init(&sc->irq_rman) != 0 ||
+ rman_manage_region(&sc->irq_rman, PCI_IRQ_START,
+ PCI_IRQ_END) != 0) {
+ panic("Generic PCI: failed to set up IRQ rman");
+ }
+
+ device_add_child(dev, "pci", -1);
+ return (bus_generic_attach(dev));
+}
+
+static int
+parse_pci_mem_ranges(struct generic_pcie_softc *sc)
+{
+ pcell_t pci_addr_cells, parent_addr_cells;
+ pcell_t attributes, size_cells;
+ cell_t *base_ranges;
+ int nbase_ranges;
+ phandle_t node;
+ int i, j, k;
+ int tuple;
+
+ node = ofw_bus_get_node(sc->dev);
+
+ OF_getencprop(node, "#address-cells", &pci_addr_cells,
+ sizeof(pci_addr_cells));
+ OF_getencprop(node, "#size-cells", &size_cells,
+ sizeof(size_cells));
+ OF_getencprop(OF_parent(node), "#address-cells", &parent_addr_cells,
+ sizeof(parent_addr_cells));
+
+ if (parent_addr_cells != 2 || pci_addr_cells != 3 || size_cells != 2) {
+ device_printf(sc->dev,
+ "Unexpected number of address or size cells in FDT\n");
+ return (ENXIO);
+ }
+
+ nbase_ranges = OF_getproplen(node, "ranges");
+ sc->nranges = nbase_ranges / sizeof(cell_t) /
+ (parent_addr_cells + pci_addr_cells + size_cells);
+ base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK);
+ OF_getencprop(node, "ranges", base_ranges, nbase_ranges);
+
+ for (i = 0, j = 0; i < sc->nranges; i++) {
+ attributes = (base_ranges[j++] >> SPACE_CODE_SHIFT) & \
+ SPACE_CODE_MASK;
+ if (attributes == SPACE_CODE_IO_SPACE) {
+ sc->ranges[i].flags |= FLAG_IO;
+ } else {
+ sc->ranges[i].flags |= FLAG_MEM;
+ }
+
+ sc->ranges[i].pci_base = 0;
+ for (k = 0; k < (pci_addr_cells - 1); k++) {
+ sc->ranges[i].pci_base <<= 32;
+ sc->ranges[i].pci_base |= base_ranges[j++];
+ }
+ sc->ranges[i].phys_base = 0;
+ for (k = 0; k < parent_addr_cells; k++) {
+ sc->ranges[i].phys_base <<= 32;
+ sc->ranges[i].phys_base |= base_ranges[j++];
+ }
+ sc->ranges[i].size = 0;
+ for (k = 0; k < size_cells; k++) {
+ sc->ranges[i].size <<= 32;
+ sc->ranges[i].size |= base_ranges[j++];
+ }
+ }
+
+ for (; i < MAX_RANGES_TUPLES; i++) {
+ /* zero-fill remaining tuples to mark empty elements in array */
+ sc->ranges[i].pci_base = 0;
+ sc->ranges[i].phys_base = 0;
+ sc->ranges[i].size = 0;
+ }
+
+ if (bootverbose) {
+ for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
+ device_printf(sc->dev,
+ "\tPCI addr: 0x%jx, CPU addr: 0x%jx, Size: 0x%jx\n",
+ sc->ranges[tuple].pci_base,
+ sc->ranges[tuple].phys_base,
+ sc->ranges[tuple].size);
+ }
+ }
+
+ free(base_ranges, M_DEVBUF);
+ return (0);
+}
+
+static uint32_t
+generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
+ u_int func, u_int reg, int bytes)
+{
+ struct generic_pcie_softc *sc;
+ bus_space_handle_t h;
+ bus_space_tag_t t;
+ uint64_t offset;
+ uint32_t data;
+
+ if (bus > 255 || slot > 31 || func > 7 || reg > 4095)
+ return (~0U);
+
+ sc = device_get_softc(dev);
+
+ offset = PCIE_ADDR_OFFSET(bus, slot, func, reg);
+ t = sc->bst;
+ h = sc->bsh;
+
+ switch (bytes) {
+ case 1:
+ data = bus_space_read_1(t, h, offset);
+ break;
+ case 2:
+ data = le16toh(bus_space_read_2(t, h, offset));
+ break;
+ case 4:
+ data = le32toh(bus_space_read_4(t, h, offset));
+ break;
+ default:
+ return (~0U);
+ }
+
+ if (reg == PCIR_INTLINE) {
+ data += PCI_IRQ_START;
+ }
+
+ return (data);
+}
+
+static void
+generic_pcie_write_config(device_t dev, u_int bus, u_int slot,
+ u_int func, u_int reg, uint32_t val, int bytes)
+{
+ struct generic_pcie_softc *sc;
+ bus_space_handle_t h;
+ bus_space_tag_t t;
+ uint64_t offset;
+
+ if (bus > 255 || slot > 31 || func > 7 || reg > 4095)
+ return;
+
+ sc = device_get_softc(dev);
+
+ offset = PCIE_ADDR_OFFSET(bus, slot, func, reg);
+
+ t = sc->bst;
+ h = sc->bsh;
+
+ switch (bytes) {
+ case 1:
+ bus_space_write_1(t, h, offset, val);
+ break;
+ case 2:
+ bus_space_write_2(t, h, offset, htole16(val));
+ break;
+ case 4:
+ bus_space_write_4(t, h, offset, htole32(val));
+ break;
+ default:
+ return;
+ }
+}
+
+static int
+generic_pcie_maxslots(device_t dev)
+{
+
+ return (31); /* max slots per bus acc. to standard */
+}
+
+static int
+generic_pcie_read_ivar(device_t dev, device_t child, int index,
+ uintptr_t *result)
+{
+ struct generic_pcie_softc *sc;
+ int secondary_bus;
+
+ sc = device_get_softc(dev);
+
+ if (index == PCIB_IVAR_BUS) {
+ /* this pcib adds only pci bus 0 as child */
+ secondary_bus = 0;
+ *result = secondary_bus;
+ return (0);
+
+ }
+
+ if (index == PCIB_IVAR_DOMAIN) {
+ *result = sc->ecam;
+ return (0);
+ }
+
+ device_printf(dev, "ERROR: Unknown index.\n");
+ return (ENOENT);
+}
+
+static int
+generic_pcie_write_ivar(device_t dev, device_t child, int index,
+ uintptr_t value)
+{
+
+ return (ENOENT);
+}
+
+static struct rman *
+generic_pcie_rman(struct generic_pcie_softc *sc, int type)
+{
+
+ switch (type) {
+ case SYS_RES_IOPORT:
+ return (&sc->io_rman);
+ case SYS_RES_MEMORY:
+ return (&sc->mem_rman);
+ case SYS_RES_IRQ:
+ return (&sc->irq_rman);
+ default:
+ break;
+ }
+
+ return (NULL);
+}
+
+static int
+generic_pcie_release_resource(device_t dev, device_t child, int type,
+ int rid, struct resource *res)
+{
+ struct generic_pcie_softc *sc;
+ struct rman *rm;
+
+ sc = device_get_softc(dev);
+
+ rm = generic_pcie_rman(sc, type);
+ if (rm != NULL) {
+ KASSERT(rman_is_region_manager(res, rm), ("rman mismatch"));
+ rman_release_resource(res);
+ }
+
+ return (bus_generic_release_resource(dev, child, type, rid, res));
+}
+
+static struct resource *
+generic_pcie_alloc_resource(device_t dev, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ struct generic_pcie_softc *sc;
+ struct resource *res;
+ struct rman *rm;
+
+ sc = device_get_softc(dev);
+
+ rm = generic_pcie_rman(sc, type);
+ if (rm == NULL)
+ return (BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
+ type, rid, start, end, count, flags));
+
+ if (bootverbose) {
+ device_printf(dev,
+ "rman_reserve_resource: start=%#lx, end=%#lx, count=%#lx\n",
+ start, end, count);
+ }
+
+ res = rman_reserve_resource(rm, start, end, count, flags, child);
+ if (res == NULL)
+ goto fail;
+
+ rman_set_rid(res, *rid);
+
+ if (flags & RF_ACTIVE)
+ if (bus_activate_resource(child, type, *rid, res)) {
+ rman_release_resource(res);
+ goto fail;
+ }
+
+ return (res);
+
+fail:
+ if (bootverbose) {
+ device_printf(dev, "%s FAIL: type=%d, rid=%d, "
+ "start=%016lx, end=%016lx, count=%016lx, flags=%x\n",
+ __func__, type, *rid, start, end, count, flags);
+ }
+
+ return (NULL);
+}
+
+static int
+generic_pcie_adjust_resource(device_t dev, device_t child, int type,
+ struct resource *res, u_long start, u_long end)
+{
+ struct generic_pcie_softc *sc;
+ struct rman *rm;
+
+ sc = device_get_softc(dev);
+
+ rm = generic_pcie_rman(sc, type);
+ if (rm != NULL)
+ return (rman_adjust_resource(res, start, end));
+ return (bus_generic_adjust_resource(dev, child, type, res, start, end));
+}
+
+static int
+generic_pcie_activate_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r)
+{
+ struct generic_pcie_softc *sc;
+ uint64_t phys_base;
+ uint64_t pci_base;
+ uint64_t size;
+ int found;
+ int res;
+ int i;
+
+ sc = device_get_softc(dev);
+
+ if ((res = rman_activate_resource(r)) != 0)
+ return (res);
+
+ switch(type) {
+ case SYS_RES_IOPORT:
+ found = 0;
+ for (i = 0; i < MAX_RANGES_TUPLES; i++) {
+ pci_base = sc->ranges[i].pci_base;
+ phys_base = sc->ranges[i].phys_base;
+ size = sc->ranges[i].size;
+
+ if ((rid > pci_base) && (rid < (pci_base + size))) {
+ found = 1;
+ break;
+ }
+ }
+ if (found) {
+ rman_set_start(r, rman_get_start(r) + phys_base);
+ BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child,
+ type, rid, r);
+ } else {
+ device_printf(dev, "Failed to activate IOPORT resource\n");
+ res = 0;
+ }
+ break;
+ case SYS_RES_MEMORY:
+ BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child, type, rid, r);
+ break;
+ default:
+ break;
+ }
+
+ return (res);
+}
+
+static int
+generic_pcie_deactivate_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r)
+{
+ struct generic_pcie_softc *sc;
+ vm_offset_t vaddr;
+ int res;
+
+ sc = device_get_softc(dev);
+
+ if ((res = rman_deactivate_resource(r)) != 0)
+ return (res);
+
+ switch(type) {
+ case SYS_RES_IOPORT:
+ case SYS_RES_MEMORY:
+ vaddr = (vm_offset_t)rman_get_virtual(r);
+ pmap_unmapdev(vaddr, rman_get_size(r));
+ break;
+ default:
+ break;
+ }
+
+ return (res);
+}
+
+static device_method_t generic_pcie_methods[] = {
+ DEVMETHOD(device_probe, generic_pcie_probe),
+ DEVMETHOD(device_attach, generic_pcie_attach),
+ DEVMETHOD(bus_read_ivar, generic_pcie_read_ivar),
+ DEVMETHOD(bus_write_ivar, generic_pcie_write_ivar),
+ DEVMETHOD(bus_alloc_resource, generic_pcie_alloc_resource),
+ DEVMETHOD(bus_adjust_resource, generic_pcie_adjust_resource),
+ DEVMETHOD(bus_release_resource, generic_pcie_release_resource),
+ DEVMETHOD(bus_activate_resource, generic_pcie_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, generic_pcie_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+ DEVMETHOD(pcib_maxslots, generic_pcie_maxslots),
+ DEVMETHOD(pcib_read_config, generic_pcie_read_config),
+ DEVMETHOD(pcib_write_config, generic_pcie_write_config),
+ DEVMETHOD_END
+};
+
+static driver_t generic_pcie_driver = {
+ "pcib",
+ generic_pcie_methods,
+ sizeof(struct generic_pcie_softc),
+};
+
+static devclass_t generic_pcie_devclass;
+
+DRIVER_MODULE(pcib, simplebus, generic_pcie_driver,
+generic_pcie_devclass, 0, 0);
+DRIVER_MODULE(pcib, ofwbus, generic_pcie_driver,
+generic_pcie_devclass, 0, 0);
diff --git a/sys/dev/proto/proto_bus_pci.c b/sys/dev/proto/proto_bus_pci.c
index 46ec41e..53ebb5e 100644
--- a/sys/dev/proto/proto_bus_pci.c
+++ b/sys/dev/proto/proto_bus_pci.c
@@ -82,6 +82,7 @@ proto_pci_attach(device_t dev)
{
struct proto_softc *sc;
struct resource *res;
+ uint32_t val;
int bar, rid, type;
sc = device_get_softc(dev);
@@ -91,15 +92,17 @@ proto_pci_attach(device_t dev)
for (bar = 0; bar < PCIR_MAX_BAR_0; bar++) {
rid = PCIR_BAR(bar);
- type = SYS_RES_MEMORY;
+ val = pci_read_config(dev, rid, 4);
+ type = (PCI_BAR_IO(val)) ? SYS_RES_IOPORT : SYS_RES_MEMORY;
res = bus_alloc_resource_any(dev, type, &rid, RF_ACTIVE);
- if (res == NULL) {
- type = SYS_RES_IOPORT;
- res = bus_alloc_resource_any(dev, type, &rid,
- RF_ACTIVE);
- }
- if (res != NULL)
- proto_add_resource(sc, type, rid, res);
+ if (res == NULL)
+ continue;
+ proto_add_resource(sc, type, rid, res);
+ if (type == SYS_RES_IOPORT)
+ continue;
+ /* Skip over adjacent BAR for 64-bit memory BARs. */
+ if ((val & PCIM_BAR_MEM_TYPE) == PCIM_BAR_MEM_64)
+ bar++;
}
rid = 0;
diff --git a/sys/dev/proto/proto_busdma.c b/sys/dev/proto/proto_busdma.c
index ced4eed..e01e76f 100644
--- a/sys/dev/proto/proto_busdma.c
+++ b/sys/dev/proto/proto_busdma.c
@@ -129,6 +129,16 @@ proto_busdma_tag_lookup(struct proto_busdma *busdma, u_long key)
return (NULL);
}
+static void
+proto_busdma_mem_alloc_callback(void *arg, bus_dma_segment_t *segs, int nseg,
+ int error)
+{
+ struct proto_ioc_busdma *ioc = arg;
+
+ ioc->u.mem.bus_nsegs = nseg;
+ ioc->u.mem.bus_addr = segs[0].ds_addr;
+}
+
static int
proto_busdma_mem_alloc(struct proto_busdma *busdma, struct proto_tag *tag,
struct proto_ioc_busdma *ioc)
@@ -153,10 +163,18 @@ proto_busdma_mem_alloc(struct proto_busdma *busdma, struct proto_tag *tag,
return (error);
}
md->physaddr = pmap_kextract((uintptr_t)(md->virtaddr));
+ error = bus_dmamap_load(md->bd_tag, md->bd_map, md->virtaddr,
+ tag->maxsz, proto_busdma_mem_alloc_callback, ioc, BUS_DMA_NOWAIT);
+ if (error) {
+ bus_dmamem_free(md->bd_tag, md->virtaddr, md->bd_map);
+ bus_dma_tag_destroy(md->bd_tag);
+ free(md, M_PROTO_BUSDMA);
+ return (error);
+ }
LIST_INSERT_HEAD(&tag->mds, md, peers);
LIST_INSERT_HEAD(&busdma->mds, md, mds);
- ioc->u.mem.nsegs = 1;
- ioc->u.mem.physaddr = md->physaddr;
+ ioc->u.mem.phys_nsegs = 1;
+ ioc->u.mem.phys_addr = md->physaddr;
ioc->result = (uintptr_t)(void *)md;
return (0);
}
diff --git a/sys/dev/proto/proto_dev.h b/sys/dev/proto/proto_dev.h
index 0050f0b..88a61a7 100644
--- a/sys/dev/proto/proto_dev.h
+++ b/sys/dev/proto/proto_dev.h
@@ -62,8 +62,10 @@ struct proto_ioc_busdma {
struct {
unsigned long tag;
unsigned int flags;
- unsigned int nsegs;
- unsigned long physaddr;
+ unsigned int phys_nsegs;
+ unsigned long phys_addr;
+ unsigned long bus_addr;
+ unsigned int bus_nsegs;
} mem;
} u;
unsigned long result;
diff --git a/sys/dev/uart/uart_bus_pci.c b/sys/dev/uart/uart_bus_pci.c
index b297502..7ba4dc9 100644
--- a/sys/dev/uart/uart_bus_pci.c
+++ b/sys/dev/uart/uart_bus_pci.c
@@ -69,6 +69,7 @@ struct pci_id {
const char *desc;
int rid;
int rclk;
+ int regshft;
};
static const struct pci_id pci_ns8250_ids[] = {
@@ -118,6 +119,10 @@ static const struct pci_id pci_ns8250_ids[] = {
{ 0x151f, 0x0000, 0xffff, 0, "TOPIC Semiconductor TP560 56k modem", 0x10 },
{ 0x1fd4, 0x1999, 0x1fd4, 0x0001, "Sunix SER5xxxx Serial Port", 0x10,
8 * DEFAULT_RCLK },
+{ 0x8086, 0x0f0a, 0xffff, 0, "Intel ValleyView LPIO1 HSUART#1", 0x10,
+ 24 * DEFAULT_RCLK, 2 },
+{ 0x8086, 0x0f0c, 0xffff, 0, "Intel ValleyView LPIO1 HSUART#2", 0x10,
+ 24 * DEFAULT_RCLK, 2 },
{ 0x8086, 0x1c3d, 0xffff, 0, "Intel AMT - KT Controller", 0x10 },
{ 0x8086, 0x1d3d, 0xffff, 0, "Intel C600/X79 Series Chipset KT Controller", 0x10 },
{ 0x8086, 0x2a07, 0xffff, 0, "Intel AMT - PM965/GM965 KT Controller", 0x10 },
@@ -186,7 +191,7 @@ uart_pci_probe(device_t dev)
return (ENXIO);
match:
- result = uart_bus_probe(dev, 0, id->rclk, id->rid, 0);
+ result = uart_bus_probe(dev, id->regshft, id->rclk, id->rid, 0);
/* Bail out on error. */
if (result > 0)
return (result);
diff --git a/sys/dev/usb/misc/ugold.c b/sys/dev/usb/misc/ugold.c
new file mode 100644
index 0000000..d6f8f77
--- /dev/null
+++ b/sys/dev/usb/misc/ugold.c
@@ -0,0 +1,405 @@
+/* $OpenBSD: ugold.c,v 1.7 2014/12/11 18:39:27 mpi Exp $ */
+
+/*
+ * Copyright (c) 2013 Takayoshi SASANO <sasano@openbsd.org>
+ * Copyright (c) 2013 Martin Pieuchot <mpi@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* Driver for Microdia's HID based TEMPer Temperature sensor */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/stdint.h>
+#include <sys/stddef.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/condvar.h>
+#include <sys/sysctl.h>
+#include <sys/sx.h>
+#include <sys/unistd.h>
+#include <sys/callout.h>
+#include <sys/malloc.h>
+#include <sys/priv.h>
+#include <sys/conf.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbhid.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usbdi_util.h>
+#include "usbdevs.h"
+
+#define USB_DEBUG_VAR usb_debug
+#include <dev/usb/usb_debug.h>
+
+#define UGOLD_INNER 0
+#define UGOLD_OUTER 1
+#define UGOLD_MAX_SENSORS 2
+
+#define UGOLD_CMD_DATA 0x80
+#define UGOLD_CMD_INIT 0x82
+
+enum {
+ UGOLD_INTR_DT,
+ UGOLD_N_TRANSFER,
+};
+
+/*
+ * This driver only uses two of the three known commands for the
+ * TEMPerV1.2 device.
+ *
+ * The first byte of the answer corresponds to the command and the
+ * second one seems to be the size (in bytes) of the answer.
+ *
+ * The device always sends 8 bytes and if the length of the answer
+ * is less than that, it just leaves the last bytes untouched. That
+ * is why most of the time the last n bytes of the answers are the
+ * same.
+ *
+ * The third command below seems to generate two answers with a
+ * string corresponding to the device, for example:
+ * 'TEMPer1F' and '1.1Per1F' (here Per1F is repeated).
+ */
+static uint8_t cmd_data[8] = {0x01, 0x80, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00};
+static uint8_t cmd_init[8] = {0x01, 0x82, 0x77, 0x01, 0x00, 0x00, 0x00, 0x00};
+
+#if 0
+static uint8_t cmd_type[8] = {0x01, 0x86, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00};
+
+#endif
+
+struct ugold_softc;
+struct ugold_readout_msg {
+ struct usb_proc_msg hdr;
+ struct ugold_softc *sc;
+};
+
+struct ugold_softc {
+ struct usb_device *sc_udev;
+ struct usb_xfer *sc_xfer[UGOLD_N_TRANSFER];
+
+ struct callout sc_callout;
+ struct mtx sc_mtx;
+ struct ugold_readout_msg sc_readout_msg[2];
+
+ int sc_num_sensors;
+ int sc_sensor[UGOLD_MAX_SENSORS];
+ int sc_calib[UGOLD_MAX_SENSORS];
+ int sc_valid[UGOLD_MAX_SENSORS];
+ uint8_t sc_report_id;
+ uint8_t sc_iface_index[2];
+};
+
+/* prototypes */
+
+static device_probe_t ugold_probe;
+static device_attach_t ugold_attach;
+static device_detach_t ugold_detach;
+
+static usb_proc_callback_t ugold_readout_msg;
+
+static usb_callback_t ugold_intr_callback;
+
+static devclass_t ugold_devclass;
+
+static device_method_t ugold_methods[] = {
+ DEVMETHOD(device_probe, ugold_probe),
+ DEVMETHOD(device_attach, ugold_attach),
+ DEVMETHOD(device_detach, ugold_detach),
+
+ DEVMETHOD_END
+};
+
+static driver_t ugold_driver = {
+ .name = "ugold",
+ .methods = ugold_methods,
+ .size = sizeof(struct ugold_softc),
+};
+
+DRIVER_MODULE(ugold, uhub, ugold_driver, ugold_devclass, NULL, NULL);
+MODULE_DEPEND(ugold, usb, 1, 1, 1);
+MODULE_VERSION(ugold, 1);
+
+static const struct usb_config ugold_config[UGOLD_N_TRANSFER] = {
+
+ [UGOLD_INTR_DT] = {
+ .type = UE_INTERRUPT,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_IN,
+ .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
+ .bufsize = 0, /* use wMaxPacketSize */
+ .callback = &ugold_intr_callback,
+ .if_index = 1,
+ },
+};
+
+static const STRUCT_USB_HOST_ID ugold_devs[] = {
+ {USB_VPI(USB_VENDOR_CHICONY2, USB_PRODUCT_CHICONY2_TEMPER, 0)},
+};
+
+static void
+ugold_timeout(void *arg)
+{
+ struct ugold_softc *sc = arg;
+
+ usb_proc_explore_lock(sc->sc_udev);
+ (void)usb_proc_explore_msignal(sc->sc_udev,
+ &sc->sc_readout_msg[0], &sc->sc_readout_msg[1]);
+ usb_proc_explore_unlock(sc->sc_udev);
+
+ callout_reset(&sc->sc_callout, 6 * hz, &ugold_timeout, sc);
+}
+
+static int
+ugold_probe(device_t dev)
+{
+ struct usb_attach_arg *uaa;
+
+ uaa = device_get_ivars(dev);
+ if (uaa->usb_mode != USB_MODE_HOST)
+ return (ENXIO);
+ if (uaa->info.bInterfaceClass != UICLASS_HID)
+ return (ENXIO);
+ if (uaa->info.bIfaceIndex != 0)
+ return (ENXIO);
+
+ return (usbd_lookup_id_by_uaa(ugold_devs, sizeof(ugold_devs), uaa));
+}
+
+static int
+ugold_attach(device_t dev)
+{
+ struct ugold_softc *sc = device_get_softc(dev);
+ struct usb_attach_arg *uaa = device_get_ivars(dev);
+ struct sysctl_oid *sensor_tree;
+ uint16_t d_len;
+ void *d_ptr;
+ int error;
+ int i;
+
+ sc->sc_udev = uaa->device;
+ sc->sc_readout_msg[0].hdr.pm_callback = &ugold_readout_msg;
+ sc->sc_readout_msg[0].sc = sc;
+ sc->sc_readout_msg[1].hdr.pm_callback = &ugold_readout_msg;
+ sc->sc_readout_msg[1].sc = sc;
+ sc->sc_iface_index[0] = uaa->info.bIfaceIndex;
+ sc->sc_iface_index[1] = uaa->info.bIfaceIndex + 1;
+
+ device_set_usb_desc(dev);
+ mtx_init(&sc->sc_mtx, "ugold lock", NULL, MTX_DEF | MTX_RECURSE);
+ callout_init_mtx(&sc->sc_callout, &sc->sc_mtx, 0);
+
+ /* grab all interfaces from other drivers */
+ for (i = 0;; i++) {
+ if (i == uaa->info.bIfaceIndex)
+ continue;
+ if (usbd_get_iface(uaa->device, i) == NULL)
+ break;
+
+ usbd_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex);
+ }
+
+ /* figure out report ID */
+ error = usbd_req_get_hid_desc(uaa->device, NULL,
+ &d_ptr, &d_len, M_TEMP, uaa->info.bIfaceIndex);
+
+ if (error)
+ goto detach;
+
+ (void)hid_report_size(d_ptr, d_len, hid_input, &sc->sc_report_id);
+
+ free(d_ptr, M_TEMP);
+
+ error = usbd_transfer_setup(uaa->device,
+ sc->sc_iface_index, sc->sc_xfer, ugold_config,
+ UGOLD_N_TRANSFER, sc, &sc->sc_mtx);
+ if (error)
+ goto detach;
+
+ sensor_tree = SYSCTL_ADD_NODE(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "sensors",
+ CTLFLAG_RD, NULL, "");
+
+ if (sensor_tree == NULL) {
+ error = ENOMEM;
+ goto detach;
+ }
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(sensor_tree),
+ OID_AUTO, "inner", CTLFLAG_RD, &sc->sc_sensor[UGOLD_INNER], 0,
+ "Inner temperature in microCelcius");
+
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(sensor_tree),
+ OID_AUTO, "inner_valid", CTLFLAG_RD, &sc->sc_valid[UGOLD_INNER], 0,
+ "Inner temperature is valid");
+
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(sensor_tree),
+ OID_AUTO, "inner_calib", CTLFLAG_RWTUN, &sc->sc_calib[UGOLD_INNER], 0,
+ "Inner calibration temperature in microCelcius");
+
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(sensor_tree),
+ OID_AUTO, "outer", CTLFLAG_RD, &sc->sc_sensor[UGOLD_OUTER], 0,
+ "Outer temperature in microCelcius");
+
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(sensor_tree),
+ OID_AUTO, "outer_calib", CTLFLAG_RWTUN, &sc->sc_calib[UGOLD_OUTER], 0,
+ "Outer calibration temperature in microCelcius");
+
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(sensor_tree),
+ OID_AUTO, "outer_valid", CTLFLAG_RD, &sc->sc_valid[UGOLD_OUTER], 0,
+ "Outer temperature is valid");
+
+ mtx_lock(&sc->sc_mtx);
+ usbd_transfer_start(sc->sc_xfer[UGOLD_INTR_DT]);
+ ugold_timeout(sc);
+ mtx_unlock(&sc->sc_mtx);
+
+ return (0);
+
+detach:
+ DPRINTF("error=%s\n", usbd_errstr(error));
+ ugold_detach(dev);
+ return (error);
+}
+
+static int
+ugold_detach(device_t dev)
+{
+ struct ugold_softc *sc = device_get_softc(dev);
+
+ callout_drain(&sc->sc_callout);
+
+ usb_proc_explore_lock(sc->sc_udev);
+ usb_proc_explore_mwait(sc->sc_udev,
+ &sc->sc_readout_msg[0], &sc->sc_readout_msg[1]);
+ usb_proc_explore_unlock(sc->sc_udev);
+
+ usbd_transfer_unsetup(sc->sc_xfer, UGOLD_N_TRANSFER);
+
+ mtx_destroy(&sc->sc_mtx);
+
+ return (0);
+}
+
+static int
+ugold_ds75_temp(uint8_t msb, uint8_t lsb)
+{
+ /* DS75: 12bit precision mode : 0.0625 degrees Celsius ticks */
+ /* NOTE: MSB has a sign bit for negative temperatures */
+ int32_t temp = (msb << 24) | ((lsb & 0xF0) << 16);
+ return (((int64_t)temp * (int64_t)1000000LL) >> 24);
+}
+
+
+static void
+ugold_intr_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+ struct ugold_softc *sc = usbd_xfer_softc(xfer);
+ struct usb_page_cache *pc;
+ uint8_t buf[8];
+ int temp;
+ int len;
+
+ usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
+
+ switch (USB_GET_STATE(xfer)) {
+ case USB_ST_TRANSFERRED:
+ memset(buf, 0, sizeof(buf));
+
+ pc = usbd_xfer_get_frame(xfer, 0);
+ usbd_copy_out(pc, 0, buf, MIN(len, sizeof(buf)));
+
+ switch (buf[0]) {
+ case UGOLD_CMD_INIT:
+ if (sc->sc_num_sensors)
+ break;
+
+ sc->sc_num_sensors = MIN(buf[1], UGOLD_MAX_SENSORS) /* XXX */ ;
+
+ DPRINTF("%d sensor%s type ds75/12bit (temperature)\n",
+ sc->sc_num_sensors, (sc->sc_num_sensors == 1) ? "" : "s");
+ break;
+ case UGOLD_CMD_DATA:
+ switch (buf[1]) {
+ case 4:
+ temp = ugold_ds75_temp(buf[4], buf[5]);
+ sc->sc_sensor[UGOLD_OUTER] = temp + sc->sc_calib[UGOLD_OUTER];
+ sc->sc_valid[UGOLD_OUTER] = 1;
+ /* FALLTHROUGH */
+ case 2:
+ temp = ugold_ds75_temp(buf[2], buf[3]);
+ sc->sc_sensor[UGOLD_INNER] = temp + sc->sc_calib[UGOLD_INNER];
+ sc->sc_valid[UGOLD_INNER] = 1;
+ break;
+ default:
+ DPRINTF("invalid data length (%d bytes)\n", buf[1]);
+ }
+ break;
+ default:
+ DPRINTF("unknown command 0x%02x\n", buf[0]);
+ break;
+ }
+ /* FALLTHROUGH */
+ case USB_ST_SETUP:
+tr_setup:
+ usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
+ usbd_transfer_submit(xfer);
+ break;
+ default: /* Error */
+ if (error != USB_ERR_CANCELLED) {
+ /* try clear stall first */
+ usbd_xfer_set_stall(xfer);
+ goto tr_setup;
+ }
+ break;
+ }
+}
+
+static int
+ugold_issue_cmd(struct ugold_softc *sc, uint8_t *cmd, int len)
+{
+ return (usbd_req_set_report(sc->sc_udev, &sc->sc_mtx, cmd, len,
+ sc->sc_iface_index[1], UHID_OUTPUT_REPORT, sc->sc_report_id));
+}
+
+static void
+ugold_readout_msg(struct usb_proc_msg *pm)
+{
+ struct ugold_softc *sc = ((struct ugold_readout_msg *)pm)->sc;
+
+ usb_proc_explore_unlock(sc->sc_udev);
+
+ mtx_lock(&sc->sc_mtx);
+ if (sc->sc_num_sensors == 0)
+ ugold_issue_cmd(sc, cmd_init, sizeof(cmd_init));
+
+ ugold_issue_cmd(sc, cmd_data, sizeof(cmd_data));
+ mtx_unlock(&sc->sc_mtx);
+
+ usb_proc_explore_lock(sc->sc_udev);
+}
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index b19f766..aaf1d67 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -525,7 +525,7 @@ vendor DMI 0x0c0b DMI
vendor CANYON 0x0c10 Canyon
vendor ICOM 0x0c26 Icom Inc.
vendor GNOTOMETRICS 0x0c33 GN Otometrics
-vendor CHICONY2 0x0c45 Chicony
+vendor CHICONY2 0x0c45 Chicony / Microdia / Sonix Technology Co., Ltd.
vendor REINERSCT 0x0c4b Reiner-SCT
vendor SEALEVEL 0x0c52 Sealevel System
vendor JETI 0x0c6c Jeti
@@ -3050,6 +3050,11 @@ product MGE UPS2 0xffff MGE UPS SYSTEMS PROTECTIONCENTER 2
product MEI CASHFLOW_SC 0x1100 Cashflow-SC Cash Acceptor
product MEI S2000 0x1101 Series 2000 Combo Acceptor
+/* Microdia / Sonix Techonology Co., Ltd. products */
+product CHICONY2 YUREX 0x1010 YUREX
+product CHICONY2 CAM_1 0x62c0 CAM_1
+product CHICONY2 TEMPER 0x7401 TEMPer sensor
+
/* Micro Star International products */
product MSI BT_DONGLE 0x1967 Bluetooth USB dongle
product MSI RT3070_1 0x3820 RT3070
diff --git a/sys/dev/videomode/videomode.h b/sys/dev/videomode/videomode.h
index b223da8..3e64444 100644
--- a/sys/dev/videomode/videomode.h
+++ b/sys/dev/videomode/videomode.h
@@ -43,6 +43,7 @@ struct videomode {
int vtotal;
int flags; /* Video mode flags; see below. */
const char *name;
+ int hskew;
};
/*
diff --git a/sys/dev/virtio/mmio/virtio_mmio.h b/sys/dev/virtio/mmio/virtio_mmio.h
index 30e0286..81e87b7 100644
--- a/sys/dev/virtio/mmio/virtio_mmio.h
+++ b/sys/dev/virtio/mmio/virtio_mmio.h
@@ -36,10 +36,6 @@
#define VIRTIO_MMIO_MAGIC_VALUE 0x000
#define VIRTIO_MMIO_VERSION 0x004
#define VIRTIO_MMIO_DEVICE_ID 0x008
-
-#define VIRTIO_MMIO_MAGIC_VALUE 0x000
-#define VIRTIO_MMIO_VERSION 0x004
-#define VIRTIO_MMIO_DEVICE_ID 0x008
#define VIRTIO_MMIO_VENDOR_ID 0x00c
#define VIRTIO_MMIO_HOST_FEATURES 0x010
#define VIRTIO_MMIO_HOST_FEATURES_SEL 0x014
diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c
index 704a3d9..3b6438f 100644
--- a/sys/dev/virtio/network/if_vtnet.c
+++ b/sys/dev/virtio/network/if_vtnet.c
@@ -443,7 +443,7 @@ vtnet_detach(device_t dev)
sc->vtnet_vlan_attach = NULL;
}
if (sc->vtnet_vlan_detach != NULL) {
- EVENTHANDLER_DEREGISTER(vlan_unconfg, sc->vtnet_vlan_detach);
+ EVENTHANDLER_DEREGISTER(vlan_unconfig, sc->vtnet_vlan_detach);
sc->vtnet_vlan_detach = NULL;
}
@@ -1080,8 +1080,12 @@ vtnet_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
(IFF_PROMISC | IFF_ALLMULTI)) {
if (sc->vtnet_flags & VTNET_FLAG_CTRL_RX)
vtnet_rx_filter(sc);
- else
- error = ENOTSUP;
+ else {
+ ifp->if_flags |= IFF_PROMISC;
+ if ((ifp->if_flags ^ sc->vtnet_if_flags)
+ & IFF_ALLMULTI)
+ error = ENOTSUP;
+ }
}
} else
vtnet_init_locked(sc);
diff --git a/sys/dev/xen/blkback/blkback.c b/sys/dev/xen/blkback/blkback.c
index d352242..459271e 100644
--- a/sys/dev/xen/blkback/blkback.c
+++ b/sys/dev/xen/blkback/blkback.c
@@ -85,11 +85,19 @@ __FBSDID("$FreeBSD$");
/*--------------------------- Compile-time Tunables --------------------------*/
/**
+ * The maximum number of shared memory ring pages we will allow in a
+ * negotiated block-front/back communication channel. Allow enough
+ * ring space for all requests to be XBB_MAX_REQUEST_SIZE'd.
+ */
+#define XBB_MAX_RING_PAGES 32
+
+/**
* The maximum number of outstanding request blocks (request headers plus
* additional segment blocks) we will allow in a negotiated block-front/back
* communication channel.
*/
-#define XBB_MAX_REQUESTS 256
+#define XBB_MAX_REQUESTS \
+ __CONST_RING_SIZE(blkif, PAGE_SIZE * XBB_MAX_RING_PAGES)
/**
* \brief Define to force all I/O to be performed on memory owned by the
@@ -148,14 +156,6 @@ static MALLOC_DEFINE(M_XENBLOCKBACK, "xbbd", "Xen Block Back Driver Data");
(XBB_MAX_REQUEST_SIZE / PAGE_SIZE) + 1)))
/**
- * The maximum number of shared memory ring pages we will allow in a
- * negotiated block-front/back communication channel. Allow enough
- * ring space for all requests to be XBB_MAX_REQUEST_SIZE'd.
- */
-#define XBB_MAX_RING_PAGES \
- BLKIF_RING_PAGES(BLKIF_SEGS_TO_BLOCKS(XBB_MAX_SEGMENTS_PER_REQUEST) \
- * XBB_MAX_REQUESTS)
-/**
* The maximum number of ring pages that we can allow per request list.
* We limit this to the maximum number of segments per request, because
* that is already a reasonable number of segments to aggregate. This
@@ -1328,7 +1328,7 @@ xbb_queue_response(struct xbb_softc *xbb, struct xbb_xen_req *req, int status)
if (status != BLKIF_RSP_OKAY)
xbb->reqs_completed_with_error++;
- xbb->rings.common.rsp_prod_pvt += BLKIF_SEGS_TO_BLOCKS(req->nr_pages);
+ xbb->rings.common.rsp_prod_pvt++;
xbb->reqs_queued_for_completion++;
@@ -1666,87 +1666,49 @@ xbb_dispatch_io(struct xbb_softc *xbb, struct xbb_xen_reqlist *reqlist)
goto send_response;
}
- block_segs = MIN(nreq->nr_pages,
- BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK);
+ block_segs = nseg;
sg = ring_req->seg;
last_block_sg = sg + block_segs;
- while (1) {
-
- while (sg < last_block_sg) {
- KASSERT(seg_idx <
- XBB_MAX_SEGMENTS_PER_REQLIST,
- ("seg_idx %d is too large, max "
- "segs %d\n", seg_idx,
- XBB_MAX_SEGMENTS_PER_REQLIST));
-
- xbb_sg->first_sect = sg->first_sect;
- xbb_sg->last_sect = sg->last_sect;
- xbb_sg->nsect =
- (int8_t)(sg->last_sect -
- sg->first_sect + 1);
-
- if ((sg->last_sect >= (PAGE_SIZE >> 9))
- || (xbb_sg->nsect <= 0)) {
- reqlist->status = BLKIF_RSP_ERROR;
- goto send_response;
- }
-
- nr_sects += xbb_sg->nsect;
- map->host_addr = xbb_get_gntaddr(reqlist,
- seg_idx, /*sector*/0);
- KASSERT(map->host_addr + PAGE_SIZE <=
- xbb->ring_config.gnt_addr,
- ("Host address %#jx len %d overlaps "
- "ring address %#jx\n",
- (uintmax_t)map->host_addr, PAGE_SIZE,
- (uintmax_t)xbb->ring_config.gnt_addr));
-
- map->flags = GNTMAP_host_map;
- map->ref = sg->gref;
- map->dom = xbb->otherend_id;
- if (operation == BIO_WRITE)
- map->flags |= GNTMAP_readonly;
- sg++;
- map++;
- xbb_sg++;
- seg_idx++;
- req_seg_idx++;
- }
- block_segs = MIN(nseg - req_seg_idx,
- BLKIF_MAX_SEGMENTS_PER_SEGMENT_BLOCK);
- if (block_segs == 0)
- break;
-
- /*
- * Fetch the next request block full of SG elements.
- * For now, only the spacing between entries is
- * different in the different ABIs, not the sg entry
- * layout.
- */
- req_ring_idx++;
- switch (xbb->abi) {
- case BLKIF_PROTOCOL_NATIVE:
- sg = BLKRING_GET_SEG_BLOCK(&xbb->rings.native,
- req_ring_idx);
- break;
- case BLKIF_PROTOCOL_X86_32:
- {
- sg = BLKRING_GET_SEG_BLOCK(&xbb->rings.x86_32,
- req_ring_idx);
- break;
- }
- case BLKIF_PROTOCOL_X86_64:
- {
- sg = BLKRING_GET_SEG_BLOCK(&xbb->rings.x86_64,
- req_ring_idx);
- break;
+ while (sg < last_block_sg) {
+ KASSERT(seg_idx <
+ XBB_MAX_SEGMENTS_PER_REQLIST,
+ ("seg_idx %d is too large, max "
+ "segs %d\n", seg_idx,
+ XBB_MAX_SEGMENTS_PER_REQLIST));
+
+ xbb_sg->first_sect = sg->first_sect;
+ xbb_sg->last_sect = sg->last_sect;
+ xbb_sg->nsect =
+ (int8_t)(sg->last_sect -
+ sg->first_sect + 1);
+
+ if ((sg->last_sect >= (PAGE_SIZE >> 9))
+ || (xbb_sg->nsect <= 0)) {
+ reqlist->status = BLKIF_RSP_ERROR;
+ goto send_response;
}
- default:
- panic("Unexpected blkif protocol ABI.");
- /* NOTREACHED */
- }
- last_block_sg = sg + block_segs;
+
+ nr_sects += xbb_sg->nsect;
+ map->host_addr = xbb_get_gntaddr(reqlist,
+ seg_idx, /*sector*/0);
+ KASSERT(map->host_addr + PAGE_SIZE <=
+ xbb->ring_config.gnt_addr,
+ ("Host address %#jx len %d overlaps "
+ "ring address %#jx\n",
+ (uintmax_t)map->host_addr, PAGE_SIZE,
+ (uintmax_t)xbb->ring_config.gnt_addr));
+
+ map->flags = GNTMAP_host_map;
+ map->ref = sg->gref;
+ map->dom = xbb->otherend_id;
+ if (operation == BIO_WRITE)
+ map->flags |= GNTMAP_readonly;
+ sg++;
+ map++;
+ xbb_sg++;
+ seg_idx++;
+ req_seg_idx++;
}
/* Convert to the disk's sector size */
@@ -2000,8 +1962,7 @@ xbb_run_queue(void *context, int pending)
* response be generated before we make room in
* the queue for that response.
*/
- xbb->rings.common.req_cons +=
- BLKIF_SEGS_TO_BLOCKS(ring_req->nr_segments);
+ xbb->rings.common.req_cons++;
xbb->reqs_received++;
cur_size = xbb_count_sects(ring_req);
@@ -3091,7 +3052,7 @@ xbb_collect_frontend_info(struct xbb_softc *xbb)
* Protocol defaults valid even if all negotiation fails.
*/
xbb->ring_config.ring_pages = 1;
- xbb->max_request_segments = BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK;
+ xbb->max_request_segments = BLKIF_MAX_SEGMENTS_PER_REQUEST;
xbb->max_request_size = xbb->max_request_segments * PAGE_SIZE;
/*
@@ -3122,60 +3083,23 @@ xbb_collect_frontend_info(struct xbb_softc *xbb)
* fields.
*/
ring_page_order = 0;
+ xbb->max_requests = 32;
+
(void)xs_scanf(XST_NIL, otherend_path,
"ring-page-order", NULL, "%u",
&ring_page_order);
xbb->ring_config.ring_pages = 1 << ring_page_order;
- (void)xs_scanf(XST_NIL, otherend_path,
- "num-ring-pages", NULL, "%u",
- &xbb->ring_config.ring_pages);
ring_size = PAGE_SIZE * xbb->ring_config.ring_pages;
xbb->max_requests = BLKIF_MAX_RING_REQUESTS(ring_size);
- (void)xs_scanf(XST_NIL, otherend_path,
- "max-requests", NULL, "%u",
- &xbb->max_requests);
-
- (void)xs_scanf(XST_NIL, otherend_path,
- "max-request-segments", NULL, "%u",
- &xbb->max_request_segments);
-
- (void)xs_scanf(XST_NIL, otherend_path,
- "max-request-size", NULL, "%u",
- &xbb->max_request_size);
-
if (xbb->ring_config.ring_pages > XBB_MAX_RING_PAGES) {
xenbus_dev_fatal(xbb->dev, EINVAL,
"Front-end specified ring-pages of %u "
- "exceeds backend limit of %zu. "
+ "exceeds backend limit of %u. "
"Unable to connect.",
xbb->ring_config.ring_pages,
XBB_MAX_RING_PAGES);
return (EINVAL);
- } else if (xbb->max_requests > XBB_MAX_REQUESTS) {
- xenbus_dev_fatal(xbb->dev, EINVAL,
- "Front-end specified max_requests of %u "
- "exceeds backend limit of %u. "
- "Unable to connect.",
- xbb->max_requests,
- XBB_MAX_REQUESTS);
- return (EINVAL);
- } else if (xbb->max_request_segments > XBB_MAX_SEGMENTS_PER_REQUEST) {
- xenbus_dev_fatal(xbb->dev, EINVAL,
- "Front-end specified max_requests_segments "
- "of %u exceeds backend limit of %u. "
- "Unable to connect.",
- xbb->max_request_segments,
- XBB_MAX_SEGMENTS_PER_REQUEST);
- return (EINVAL);
- } else if (xbb->max_request_size > XBB_MAX_REQUEST_SIZE) {
- xenbus_dev_fatal(xbb->dev, EINVAL,
- "Front-end specified max_request_size "
- "of %u exceeds backend limit of %u. "
- "Unable to connect.",
- xbb->max_request_size,
- XBB_MAX_REQUEST_SIZE);
- return (EINVAL);
}
if (xbb->ring_config.ring_pages == 1) {
@@ -3723,18 +3647,6 @@ xbb_attach(device_t dev)
return (error);
}
- /*
- * Amazon EC2 client compatility. They refer to max-ring-pages
- * instead of to max-ring-page-order.
- */
- error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev),
- "max-ring-pages", "%zu", XBB_MAX_RING_PAGES);
- if (error) {
- xbb_attach_failed(xbb, error, "writing %s/max-ring-pages",
- xenbus_get_node(xbb->dev));
- return (error);
- }
-
max_ring_page_order = flsl(XBB_MAX_RING_PAGES) - 1;
error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev),
"max-ring-page-order", "%u", max_ring_page_order);
@@ -3744,32 +3656,6 @@ xbb_attach(device_t dev)
return (error);
}
- error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev),
- "max-requests", "%u", XBB_MAX_REQUESTS);
- if (error) {
- xbb_attach_failed(xbb, error, "writing %s/max-requests",
- xenbus_get_node(xbb->dev));
- return (error);
- }
-
- error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev),
- "max-request-segments", "%u",
- XBB_MAX_SEGMENTS_PER_REQUEST);
- if (error) {
- xbb_attach_failed(xbb, error, "writing %s/max-request-segments",
- xenbus_get_node(xbb->dev));
- return (error);
- }
-
- error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev),
- "max-request-size", "%u",
- XBB_MAX_REQUEST_SIZE);
- if (error) {
- xbb_attach_failed(xbb, error, "writing %s/max-request-size",
- xenbus_get_node(xbb->dev));
- return (error);
- }
-
/* Collect physical device information. */
error = xs_gather(XST_NIL, xenbus_get_otherend_path(xbb->dev),
"device-type", NULL, &xbb->dev_type,
diff --git a/sys/dev/xen/blkfront/blkfront.c b/sys/dev/xen/blkfront/blkfront.c
index 92b5f35..3991f96 100644
--- a/sys/dev/xen/blkfront/blkfront.c
+++ b/sys/dev/xen/blkfront/blkfront.c
@@ -156,31 +156,71 @@ xbd_free_command(struct xbd_command *cm)
}
static void
+mksegarray(bus_dma_segment_t *segs, int nsegs,
+ grant_ref_t * gref_head, int otherend_id, int readonly,
+ grant_ref_t * sg_ref, blkif_request_segment_t * sg)
+{
+ struct blkif_request_segment *last_block_sg = sg + nsegs;
+ vm_paddr_t buffer_ma;
+ uint64_t fsect, lsect;
+ int ref;
+
+ while (sg < last_block_sg) {
+ buffer_ma = segs->ds_addr;
+ fsect = (buffer_ma & PAGE_MASK) >> XBD_SECTOR_SHFT;
+ lsect = fsect + (segs->ds_len >> XBD_SECTOR_SHFT) - 1;
+
+ KASSERT(lsect <= 7, ("XEN disk driver data cannot "
+ "cross a page boundary"));
+
+ /* install a grant reference. */
+ ref = gnttab_claim_grant_reference(gref_head);
+
+ /*
+ * GNTTAB_LIST_END == 0xffffffff, but it is private
+ * to gnttab.c.
+ */
+ KASSERT(ref != ~0, ("grant_reference failed"));
+
+ gnttab_grant_foreign_access_ref(
+ ref,
+ otherend_id,
+ buffer_ma >> PAGE_SHIFT,
+ readonly);
+
+ *sg_ref = ref;
+ *sg = (struct blkif_request_segment) {
+ .gref = ref,
+ .first_sect = fsect,
+ .last_sect = lsect
+ };
+ sg++;
+ sg_ref++;
+ segs++;
+ }
+}
+
+static void
xbd_queue_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
{
struct xbd_softc *sc;
struct xbd_command *cm;
blkif_request_t *ring_req;
- struct blkif_request_segment *sg;
- struct blkif_request_segment *last_block_sg;
- grant_ref_t *sg_ref;
- vm_paddr_t buffer_ma;
- uint64_t fsect, lsect;
- int ref;
int op;
- int block_segs;
cm = arg;
sc = cm->cm_sc;
if (error) {
- printf("error %d in xbd_queue_cb\n", error);
cm->cm_bp->bio_error = EIO;
biodone(cm->cm_bp);
xbd_free_command(cm);
return;
}
+ KASSERT(nsegs <= BLKIF_MAX_SEGMENTS_PER_REQUEST,
+ ("Too many segments in a blkfront I/O"));
+
/* Fill out a communications ring structure. */
ring_req = RING_GET_REQUEST(&sc->xbd_ring, sc->xbd_ring.req_prod_pvt);
sc->xbd_ring.req_prod_pvt++;
@@ -190,57 +230,10 @@ xbd_queue_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
ring_req->handle = (blkif_vdev_t)(uintptr_t)sc->xbd_disk;
ring_req->nr_segments = nsegs;
cm->cm_nseg = nsegs;
-
- block_segs = MIN(nsegs, BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK);
- sg = ring_req->seg;
- last_block_sg = sg + block_segs;
- sg_ref = cm->cm_sg_refs;
-
- while (1) {
-
- while (sg < last_block_sg) {
- buffer_ma = segs->ds_addr;
- fsect = (buffer_ma & PAGE_MASK) >> XBD_SECTOR_SHFT;
- lsect = fsect + (segs->ds_len >> XBD_SECTOR_SHFT) - 1;
-
- KASSERT(lsect <= 7, ("XEN disk driver data cannot "
- "cross a page boundary"));
-
- /* install a grant reference. */
- ref = gnttab_claim_grant_reference(&cm->cm_gref_head);
-
- /*
- * GNTTAB_LIST_END == 0xffffffff, but it is private
- * to gnttab.c.
- */
- KASSERT(ref != ~0, ("grant_reference failed"));
-
- gnttab_grant_foreign_access_ref(
- ref,
- xenbus_get_otherend_id(sc->xbd_dev),
- buffer_ma >> PAGE_SHIFT,
- ring_req->operation == BLKIF_OP_WRITE);
-
- *sg_ref = ref;
- *sg = (struct blkif_request_segment) {
- .gref = ref,
- .first_sect = fsect,
- .last_sect = lsect
- };
- sg++;
- sg_ref++;
- segs++;
- nsegs--;
- }
- block_segs = MIN(nsegs, BLKIF_MAX_SEGMENTS_PER_SEGMENT_BLOCK);
- if (block_segs == 0)
- break;
-
- sg = BLKRING_GET_SEG_BLOCK(&sc->xbd_ring,
- sc->xbd_ring.req_prod_pvt);
- sc->xbd_ring.req_prod_pvt++;
- last_block_sg = sg + block_segs;
- }
+ mksegarray(segs, nsegs, &cm->cm_gref_head,
+ xenbus_get_otherend_id(sc->xbd_dev),
+ cm->cm_operation == BLKIF_OP_WRITE,
+ cm->cm_sg_refs, ring_req->seg);
if (cm->cm_operation == BLKIF_OP_READ)
op = BUS_DMASYNC_PREREAD;
@@ -396,8 +389,8 @@ xbd_startio(struct xbd_softc *sc)
if (sc->xbd_state != XBD_STATE_CONNECTED)
return;
- while (RING_FREE_REQUESTS(&sc->xbd_ring) >=
- sc->xbd_max_request_blocks) {
+ while (!RING_FULL(&sc->xbd_ring)) {
+
if (sc->xbd_qfrozen_cnt != 0)
break;
@@ -450,13 +443,6 @@ xbd_bio_complete(struct xbd_softc *sc, struct xbd_command *cm)
biodone(bp);
}
-static int
-xbd_completion(struct xbd_command *cm)
-{
- gnttab_end_foreign_access_references(cm->cm_nseg, cm->cm_sg_refs);
- return (BLKIF_SEGS_TO_BLOCKS(cm->cm_nseg));
-}
-
static void
xbd_int(void *xsc)
{
@@ -482,7 +468,9 @@ xbd_int(void *xsc)
cm = &sc->xbd_shadow[bret->id];
xbd_remove_cm(cm, XBD_Q_BUSY);
- i += xbd_completion(cm);
+ gnttab_end_foreign_access_references(cm->cm_nseg,
+ cm->cm_sg_refs);
+ i++;
if (cm->cm_operation == BLKIF_OP_READ)
op = BUS_DMASYNC_POSTREAD;
@@ -1064,11 +1052,9 @@ xbd_initialize(struct xbd_softc *sc)
*/
max_ring_page_order = 0;
sc->xbd_ring_pages = 1;
- sc->xbd_max_request_segments = BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK;
+ sc->xbd_max_request_segments = BLKIF_MAX_SEGMENTS_PER_REQUEST;
sc->xbd_max_request_size =
XBD_SEGS_TO_SIZE(sc->xbd_max_request_segments);
- sc->xbd_max_request_blocks =
- BLKIF_SEGS_TO_BLOCKS(sc->xbd_max_request_segments);
/*
* Protocol negotiation.
@@ -1095,24 +1081,10 @@ xbd_initialize(struct xbd_softc *sc)
if (sc->xbd_ring_pages < 1)
sc->xbd_ring_pages = 1;
- sc->xbd_max_requests =
- BLKIF_MAX_RING_REQUESTS(sc->xbd_ring_pages * PAGE_SIZE);
- (void)xs_scanf(XST_NIL, otherend_path,
- "max-requests", NULL, "%" PRIu32,
- &sc->xbd_max_requests);
-
- (void)xs_scanf(XST_NIL, otherend_path,
- "max-request-segments", NULL, "%" PRIu32,
- &sc->xbd_max_request_segments);
-
- (void)xs_scanf(XST_NIL, otherend_path,
- "max-request-size", NULL, "%" PRIu32,
- &sc->xbd_max_request_size);
-
if (sc->xbd_ring_pages > XBD_MAX_RING_PAGES) {
device_printf(sc->xbd_dev,
"Back-end specified ring-pages of %u "
- "limited to front-end limit of %zu.\n",
+ "limited to front-end limit of %u.\n",
sc->xbd_ring_pages, XBD_MAX_RING_PAGES);
sc->xbd_ring_pages = XBD_MAX_RING_PAGES;
}
@@ -1128,46 +1100,16 @@ xbd_initialize(struct xbd_softc *sc)
sc->xbd_ring_pages = new_page_limit;
}
+ sc->xbd_max_requests =
+ BLKIF_MAX_RING_REQUESTS(sc->xbd_ring_pages * PAGE_SIZE);
if (sc->xbd_max_requests > XBD_MAX_REQUESTS) {
device_printf(sc->xbd_dev,
"Back-end specified max_requests of %u "
- "limited to front-end limit of %u.\n",
+ "limited to front-end limit of %zu.\n",
sc->xbd_max_requests, XBD_MAX_REQUESTS);
sc->xbd_max_requests = XBD_MAX_REQUESTS;
}
- if (sc->xbd_max_request_segments > XBD_MAX_SEGMENTS_PER_REQUEST) {
- device_printf(sc->xbd_dev,
- "Back-end specified max_request_segments of %u "
- "limited to front-end limit of %u.\n",
- sc->xbd_max_request_segments,
- XBD_MAX_SEGMENTS_PER_REQUEST);
- sc->xbd_max_request_segments = XBD_MAX_SEGMENTS_PER_REQUEST;
- }
-
- if (sc->xbd_max_request_size > XBD_MAX_REQUEST_SIZE) {
- device_printf(sc->xbd_dev,
- "Back-end specified max_request_size of %u "
- "limited to front-end limit of %u.\n",
- sc->xbd_max_request_size,
- XBD_MAX_REQUEST_SIZE);
- sc->xbd_max_request_size = XBD_MAX_REQUEST_SIZE;
- }
-
- if (sc->xbd_max_request_size >
- XBD_SEGS_TO_SIZE(sc->xbd_max_request_segments)) {
- device_printf(sc->xbd_dev,
- "Back-end specified max_request_size of %u "
- "limited to front-end limit of %u. (Too few segments.)\n",
- sc->xbd_max_request_size,
- XBD_SEGS_TO_SIZE(sc->xbd_max_request_segments));
- sc->xbd_max_request_size =
- XBD_SEGS_TO_SIZE(sc->xbd_max_request_segments);
- }
-
- sc->xbd_max_request_blocks =
- BLKIF_SEGS_TO_BLOCKS(sc->xbd_max_request_segments);
-
/* Allocate datastructures based on negotiated values. */
error = bus_dma_tag_create(
bus_get_dma_tag(sc->xbd_dev), /* parent */
@@ -1241,36 +1183,6 @@ xbd_initialize(struct xbd_softc *sc)
}
}
- error = xs_printf(XST_NIL, node_path,
- "max-requests","%u",
- sc->xbd_max_requests);
- if (error) {
- xenbus_dev_fatal(sc->xbd_dev, error,
- "writing %s/max-requests",
- node_path);
- return;
- }
-
- error = xs_printf(XST_NIL, node_path,
- "max-request-segments","%u",
- sc->xbd_max_request_segments);
- if (error) {
- xenbus_dev_fatal(sc->xbd_dev, error,
- "writing %s/max-request-segments",
- node_path);
- return;
- }
-
- error = xs_printf(XST_NIL, node_path,
- "max-request-size","%u",
- sc->xbd_max_request_size);
- if (error) {
- xenbus_dev_fatal(sc->xbd_dev, error,
- "writing %s/max-request-size",
- node_path);
- return;
- }
-
error = xs_printf(XST_NIL, node_path, "event-channel",
"%u", xen_intr_port(sc->xen_intr_handle));
if (error) {
diff --git a/sys/dev/xen/blkfront/block.h b/sys/dev/xen/blkfront/block.h
index 9c803bc..3007118 100644
--- a/sys/dev/xen/blkfront/block.h
+++ b/sys/dev/xen/blkfront/block.h
@@ -61,11 +61,19 @@
((size / PAGE_SIZE) + 1)
/**
+ * The maximum number of shared memory ring pages we will allow in a
+ * negotiated block-front/back communication channel. Allow enough
+ * ring space for all requests to be XBD_MAX_REQUEST_SIZE'd.
+ */
+#define XBD_MAX_RING_PAGES 32
+
+/**
* The maximum number of outstanding requests blocks (request headers plus
* additional segment blocks) we will allow in a negotiated block-front/back
* communication channel.
*/
-#define XBD_MAX_REQUESTS 256
+#define XBD_MAX_REQUESTS \
+ __CONST_RING_SIZE(blkif, PAGE_SIZE * XBD_MAX_RING_PAGES)
/**
* The maximum mapped region size per request we will allow in a negotiated
@@ -83,15 +91,6 @@
(MIN(BLKIF_MAX_SEGMENTS_PER_REQUEST, \
XBD_SIZE_TO_SEGS(XBD_MAX_REQUEST_SIZE)))
-/**
- * The maximum number of shared memory ring pages we will allow in a
- * negotiated block-front/back communication channel. Allow enough
- * ring space for all requests to be XBD_MAX_REQUEST_SIZE'd.
- */
-#define XBD_MAX_RING_PAGES \
- BLKIF_RING_PAGES(BLKIF_SEGS_TO_BLOCKS(XBD_MAX_SEGMENTS_PER_REQUEST) \
- * XBD_MAX_REQUESTS)
-
typedef enum {
XBDCF_Q_MASK = 0xFF,
/* This command has contributed to xbd_qfrozen_cnt. */
@@ -175,7 +174,6 @@ struct xbd_softc {
u_int xbd_ring_pages;
uint32_t xbd_max_requests;
uint32_t xbd_max_request_segments;
- uint32_t xbd_max_request_blocks;
uint32_t xbd_max_request_size;
grant_ref_t xbd_ring_ref[XBD_MAX_RING_PAGES];
blkif_front_ring_t xbd_ring;
diff --git a/sys/fs/fdescfs/fdesc_vfsops.c b/sys/fs/fdescfs/fdesc_vfsops.c
index d3d8ce0..f379c5a 100644
--- a/sys/fs/fdescfs/fdesc_vfsops.c
+++ b/sys/fs/fdescfs/fdesc_vfsops.c
@@ -199,9 +199,7 @@ fdesc_statfs(mp, sbp)
* limit is ever reduced below the current number
* of open files... ]
*/
- PROC_LOCK(td->td_proc);
- lim = lim_cur(td->td_proc, RLIMIT_NOFILE);
- PROC_UNLOCK(td->td_proc);
+ lim = lim_cur(td, RLIMIT_NOFILE);
fdp = td->td_proc->p_fd;
FILEDESC_SLOCK(fdp);
limit = racct_get_limit(td->td_proc, RACCT_NOFILE);
diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c
index 9c98832..15f3bd4 100644
--- a/sys/fs/fdescfs/fdesc_vnops.c
+++ b/sys/fs/fdescfs/fdesc_vnops.c
@@ -482,7 +482,7 @@ fdesc_setattr(ap)
/*
* Allow setattr where there is an underlying vnode.
*/
- error = getvnode(td->td_proc->p_fd, fd,
+ error = getvnode(td, fd,
cap_rights_init(&rights, CAP_EXTATTR_SET), &fp);
if (error) {
/*
diff --git a/sys/fs/nfsclient/nfs_clbio.c b/sys/fs/nfsclient/nfs_clbio.c
index e8de4a5..53ba7ef 100644
--- a/sys/fs/nfsclient/nfs_clbio.c
+++ b/sys/fs/nfsclient/nfs_clbio.c
@@ -129,12 +129,6 @@ ncl_getpages(struct vop_getpages_args *ap)
npages = btoc(count);
/*
- * Since the caller has busied the requested page, that page's valid
- * field will not be changed by other threads.
- */
- vm_page_assert_xbusied(pages[ap->a_reqpage]);
-
- /*
* If the requested page is partially valid, just return it and
* allow the pager to zero-out the blanks. Partially valid pages
* can only occur at the file EOF.
diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
index 2e35582..6114608 100644
--- a/sys/fs/tmpfs/tmpfs_subr.c
+++ b/sys/fs/tmpfs/tmpfs_subr.c
@@ -1031,6 +1031,7 @@ tmpfs_dir_detach(struct vnode *vp, struct tmpfs_dirent *de)
tmpfs_free_dirent(tmp, xde);
}
}
+ de->td_cookie = de->td_hash;
} else
RB_REMOVE(tmpfs_dir, head, de);
@@ -1320,7 +1321,7 @@ tmpfs_reg_resize(struct vnode *vp, off_t newsize, boolean_t ignerr)
struct tmpfs_mount *tmp;
struct tmpfs_node *node;
vm_object_t uobj;
- vm_page_t m, ma[1];
+ vm_page_t m;
vm_pindex_t idx, newpages, oldpages;
off_t oldsize;
int base, rv;
@@ -1367,11 +1368,9 @@ retry:
VM_WAIT;
VM_OBJECT_WLOCK(uobj);
goto retry;
- } else if (m->valid != VM_PAGE_BITS_ALL) {
- ma[0] = m;
- rv = vm_pager_get_pages(uobj, ma, 1, 0);
- m = vm_page_lookup(uobj, idx);
- } else
+ } else if (m->valid != VM_PAGE_BITS_ALL)
+ rv = vm_pager_get_pages(uobj, &m, 1, 0);
+ else
/* A cached page was reactivated. */
rv = VM_PAGER_OK;
vm_page_lock(m);
diff --git a/sys/geom/label/g_label.c b/sys/geom/label/g_label.c
index 36498e1..b4a1365 100644
--- a/sys/geom/label/g_label.c
+++ b/sys/geom/label/g_label.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/libkern.h>
#include <sys/sbuf.h>
+#include <sys/stddef.h>
#include <sys/sysctl.h>
#include <geom/geom.h>
#include <geom/geom_slice.h>
@@ -96,6 +97,20 @@ const struct g_label_desc *g_labels[] = {
NULL
};
+void
+g_label_rtrim(char *label, size_t size)
+{
+ ptrdiff_t i;
+
+ for (i = size - 1; i >= 0; i--) {
+ if (label[i] == '\0')
+ continue;
+ else if (label[i] == ' ')
+ label[i] = '\0';
+ else
+ break;
+ }
+}
static int
g_label_destroy_geom(struct gctl_req *req __unused, struct g_class *mp,
diff --git a/sys/geom/label/g_label.h b/sys/geom/label/g_label.h
index 66b762c..9092d98 100644
--- a/sys/geom/label/g_label.h
+++ b/sys/geom/label/g_label.h
@@ -86,6 +86,8 @@ extern struct g_label_desc g_label_ntfs;
extern struct g_label_desc g_label_gpt;
extern struct g_label_desc g_label_gpt_uuid;
extern struct g_label_desc g_label_disk_ident;
+
+extern void g_label_rtrim(char *label, size_t size);
#endif /* _KERNEL */
struct g_label_metadata {
diff --git a/sys/geom/label/g_label_iso9660.c b/sys/geom/label/g_label_iso9660.c
index 154cefc..c3c49b0 100644
--- a/sys/geom/label/g_label_iso9660.c
+++ b/sys/geom/label/g_label_iso9660.c
@@ -47,7 +47,6 @@ g_label_iso9660_taste(struct g_consumer *cp, char *label, size_t size)
{
struct g_provider *pp;
char *sector, *volume;
- int i;
g_topology_assert_not();
pp = cp->provider;
@@ -68,14 +67,7 @@ g_label_iso9660_taste(struct g_consumer *cp, char *label, size_t size)
bzero(label, size);
strlcpy(label, volume, MIN(size, VOLUME_LEN));
g_free(sector);
- for (i = size - 1; i > 0; i--) {
- if (label[i] == '\0')
- continue;
- else if (label[i] == ' ')
- label[i] = '\0';
- else
- break;
- }
+ g_label_rtrim(label, size);
}
struct g_label_desc g_label_iso9660 = {
diff --git a/sys/geom/label/g_label_msdosfs.c b/sys/geom/label/g_label_msdosfs.c
index 5f65a72..918fabc 100644
--- a/sys/geom/label/g_label_msdosfs.c
+++ b/sys/geom/label/g_label_msdosfs.c
@@ -48,7 +48,6 @@ g_label_msdosfs_taste(struct g_consumer *cp, char *label, size_t size)
FAT32_BSBPB *pfat32_bsbpb;
FAT_DES *pfat_entry;
uint8_t *sector0, *sector;
- uint32_t i;
g_topology_assert_not();
pp = cp->provider;
@@ -200,14 +199,7 @@ g_label_msdosfs_taste(struct g_consumer *cp, char *label, size_t size)
}
endofchecks:
- for (i = size - 1; i > 0; i--) {
- if (label[i] == '\0')
- continue;
- else if (label[i] == ' ')
- label[i] = '\0';
- else
- break;
- }
+ g_label_rtrim(label, size);
error:
if (sector0 != NULL)
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index e5710bf..1bf8163 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -17,6 +17,23 @@ profile 2
#
options KDTRACE_HOOKS
+# DTrace core
+# NOTE: introduces CDDL-licensed components into the kernel
+#device dtrace
+
+# DTrace modules
+#device dtrace_lockstat
+#device dtrace_profile
+#device dtrace_sdt
+#device dtrace_fbt
+#device dtrace_systrace
+#device dtrace_prototype
+#device dtnfscl
+#device dtmalloc
+
+# Alternatively include all the DTrace modules
+#device dtraceall
+
#####################################################################
# SMP OPTIONS:
diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s
index 39a8828..70c6d9d 100644
--- a/sys/i386/i386/exception.s
+++ b/sys/i386/i386/exception.s
@@ -157,9 +157,12 @@ IDTVEC(xmm)
.type alltraps,@function
alltraps:
pushal
- pushl %ds
- pushl %es
- pushl %fs
+ pushl $0
+ movl %ds,(%esp)
+ pushl $0
+ movl %es,(%esp)
+ pushl $0
+ movl %fs,(%esp)
alltraps_with_regs_pushed:
SET_KERNEL_SREGS
cld
@@ -233,9 +236,12 @@ IDTVEC(lcall_syscall)
pushl $7 /* sizeof "lcall 7,0" */
subl $4,%esp /* skip over tf_trapno */
pushal
- pushl %ds
- pushl %es
- pushl %fs
+ pushl $0
+ movl %ds,(%esp)
+ pushl $0
+ movl %es,(%esp)
+ pushl $0
+ movl %fs,(%esp)
SET_KERNEL_SREGS
cld
FAKE_MCOUNT(TF_EIP(%esp))
@@ -259,9 +265,12 @@ IDTVEC(int0x80_syscall)
pushl $2 /* sizeof "int 0x80" */
subl $4,%esp /* skip over tf_trapno */
pushal
- pushl %ds
- pushl %es
- pushl %fs
+ pushl $0
+ movl %ds,(%esp)
+ pushl $0
+ movl %es,(%esp)
+ pushl $0
+ movl %fs,(%esp)
SET_KERNEL_SREGS
cld
FAKE_MCOUNT(TF_EIP(%esp))
@@ -416,13 +425,16 @@ doreti_iret:
doreti_iret_fault:
subl $8,%esp
pushal
- pushl %ds
+ pushl $0
+ movl %ds,(%esp)
.globl doreti_popl_ds_fault
doreti_popl_ds_fault:
- pushl %es
+ pushl $0
+ movl %es,(%esp)
.globl doreti_popl_es_fault
doreti_popl_es_fault:
- pushl %fs
+ pushl $0
+ movl %fs,(%esp)
.globl doreti_popl_fs_fault
doreti_popl_fs_fault:
sti
diff --git a/sys/i386/i386/gdb_machdep.c b/sys/i386/i386/gdb_machdep.c
index a42b2b6..06809ad 100644
--- a/sys/i386/i386/gdb_machdep.c
+++ b/sys/i386/i386/gdb_machdep.c
@@ -45,14 +45,22 @@ __FBSDID("$FreeBSD$");
void *
gdb_cpu_getreg(int regnum, size_t *regsz)
{
+ static uint32_t _kcodesel = GSEL(GCODE_SEL, SEL_KPL);
+ static uint32_t _kdatasel = GSEL(GDATA_SEL, SEL_KPL);
+ static uint32_t _kprivsel = GSEL(GPRIV_SEL, SEL_KPL);
*regsz = gdb_cpu_regsz(regnum);
- if (kdb_thread == curthread) {
+ if (kdb_thread == curthread) {
switch (regnum) {
case 0: return (&kdb_frame->tf_eax);
case 1: return (&kdb_frame->tf_ecx);
case 2: return (&kdb_frame->tf_edx);
+ case 9: return (&kdb_frame->tf_eflags);
+ case 10: return (&kdb_frame->tf_cs);
+ case 12: return (&kdb_frame->tf_ds);
+ case 13: return (&kdb_frame->tf_es);
+ case 14: return (&kdb_frame->tf_fs);
}
}
switch (regnum) {
@@ -62,6 +70,12 @@ gdb_cpu_getreg(int regnum, size_t *regsz)
case 6: return (&kdb_thrctx->pcb_esi);
case 7: return (&kdb_thrctx->pcb_edi);
case 8: return (&kdb_thrctx->pcb_eip);
+ case 10: return (&_kcodesel);
+ case 11: return (&_kdatasel);
+ case 12: return (&_kdatasel);
+ case 13: return (&_kdatasel);
+ case 14: return (&_kprivsel);
+ case 15: return (&kdb_thrctx->pcb_gs);
}
return (NULL);
}
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 2763ef7..0373b6f 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -2867,6 +2867,7 @@ makectx(struct trapframe *tf, struct pcb *pcb)
pcb->pcb_ebx = tf->tf_ebx;
pcb->pcb_eip = tf->tf_eip;
pcb->pcb_esp = (ISPL(tf->tf_cs)) ? tf->tf_esp : (int)(tf + 1) - 8;
+ pcb->pcb_gs = rgs();
}
int
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index 1ca406b..1e417bf 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -306,8 +306,8 @@ trap(struct trapframe *frame)
td->td_pticks = 0;
td->td_frame = frame;
addr = frame->tf_eip;
- if (td->td_ucred != p->p_ucred)
- cred_update_thread(td);
+ if (td->td_cowgen != p->p_cowgen)
+ thread_cow_update(td);
switch (type) {
case T_PRIVINFLT: /* privileged instruction fault */
diff --git a/sys/i386/ibcs2/ibcs2_misc.c b/sys/i386/ibcs2/ibcs2_misc.c
index 2c2cae4..ccf5190 100644
--- a/sys/i386/ibcs2/ibcs2_misc.c
+++ b/sys/i386/ibcs2/ibcs2_misc.c
@@ -98,40 +98,30 @@ ibcs2_ulimit(td, uap)
struct ibcs2_ulimit_args *uap;
{
struct rlimit rl;
- struct proc *p;
int error;
#define IBCS2_GETFSIZE 1
#define IBCS2_SETFSIZE 2
#define IBCS2_GETPSIZE 3
#define IBCS2_GETDTABLESIZE 4
- p = td->td_proc;
switch (uap->cmd) {
case IBCS2_GETFSIZE:
- PROC_LOCK(p);
- td->td_retval[0] = lim_cur(p, RLIMIT_FSIZE);
- PROC_UNLOCK(p);
+ td->td_retval[0] = lim_cur(td, RLIMIT_FSIZE);
if (td->td_retval[0] == -1)
td->td_retval[0] = 0x7fffffff;
return 0;
case IBCS2_SETFSIZE:
- PROC_LOCK(p);
- rl.rlim_max = lim_max(p, RLIMIT_FSIZE);
- PROC_UNLOCK(p);
+ rl.rlim_max = lim_max(td, RLIMIT_FSIZE);
rl.rlim_cur = uap->newlimit;
error = kern_setrlimit(td, RLIMIT_FSIZE, &rl);
if (!error) {
- PROC_LOCK(p);
- td->td_retval[0] = lim_cur(p, RLIMIT_FSIZE);
- PROC_UNLOCK(p);
+ td->td_retval[0] = lim_cur(td, RLIMIT_FSIZE);
} else {
DPRINTF(("failed "));
}
return error;
case IBCS2_GETPSIZE:
- PROC_LOCK(p);
- td->td_retval[0] = lim_cur(p, RLIMIT_RSS); /* XXX */
- PROC_UNLOCK(p);
+ td->td_retval[0] = lim_cur(td, RLIMIT_RSS); /* XXX */
return 0;
case IBCS2_GETDTABLESIZE:
uap->cmd = IBCS2_SC_OPEN_MAX;
@@ -352,8 +342,7 @@ ibcs2_getdents(td, uap)
#define BSD_DIRENT(cp) ((struct dirent *)(cp))
#define IBCS2_RECLEN(reclen) (reclen + sizeof(u_short))
- error = getvnode(td->td_proc->p_fd, uap->fd,
- cap_rights_init(&rights, CAP_READ), &fp);
+ error = getvnode(td, uap->fd, cap_rights_init(&rights, CAP_READ), &fp);
if (error != 0)
return (error);
if ((fp->f_flag & FREAD) == 0) {
@@ -508,8 +497,7 @@ ibcs2_read(td, uap)
u_long *cookies = NULL, *cookiep;
int ncookies;
- error = getvnode(td->td_proc->p_fd, uap->fd,
- cap_rights_init(&rights, CAP_READ), &fp);
+ error = getvnode(td, uap->fd, cap_rights_init(&rights, CAP_READ), &fp);
if (error != 0) {
if (error == EINVAL)
return sys_read(td, (struct read_args *)uap);
@@ -801,18 +789,14 @@ ibcs2_sysconf(td, uap)
struct ibcs2_sysconf_args *uap;
{
int mib[2], value, len, error;
- struct proc *p;
- p = td->td_proc;
switch(uap->name) {
case IBCS2_SC_ARG_MAX:
mib[1] = KERN_ARGMAX;
break;
case IBCS2_SC_CHILD_MAX:
- PROC_LOCK(p);
- td->td_retval[0] = lim_cur(td->td_proc, RLIMIT_NPROC);
- PROC_UNLOCK(p);
+ td->td_retval[0] = lim_cur(td, RLIMIT_NPROC);
return 0;
case IBCS2_SC_CLK_TCK:
@@ -824,9 +808,7 @@ ibcs2_sysconf(td, uap)
break;
case IBCS2_SC_OPEN_MAX:
- PROC_LOCK(p);
- td->td_retval[0] = lim_cur(td->td_proc, RLIMIT_NOFILE);
- PROC_UNLOCK(p);
+ td->td_retval[0] = lim_cur(td, RLIMIT_NOFILE);
return 0;
case IBCS2_SC_JOB_CONTROL:
diff --git a/sys/i386/include/asmacros.h b/sys/i386/include/asmacros.h
index 716915c..91c25f7 100644
--- a/sys/i386/include/asmacros.h
+++ b/sys/i386/include/asmacros.h
@@ -146,9 +146,12 @@
pushl $0 ; /* dummy error code */ \
pushl $0 ; /* dummy trap type */ \
pushal ; /* 8 ints */ \
- pushl %ds ; /* save data and extra segments ... */ \
- pushl %es ; \
- pushl %fs
+ pushl $0 ; /* save data and extra segments ... */ \
+ mov %ds,(%esp) ; \
+ pushl $0 ; \
+ mov %es,(%esp) ; \
+ pushl $0 ; \
+ mov %fs,(%esp)
#define POP_FRAME \
popl %fs ; \
diff --git a/sys/i386/include/gdb_machdep.h b/sys/i386/include/gdb_machdep.h
index 95af8d4..a60ba18 100644
--- a/sys/i386/include/gdb_machdep.h
+++ b/sys/i386/include/gdb_machdep.h
@@ -30,7 +30,7 @@
#define _MACHINE_GDB_MACHDEP_H_
#define GDB_BUFSZ 400
-#define GDB_NREGS 14
+#define GDB_NREGS 16
#define GDB_REG_PC 8
static __inline size_t
diff --git a/sys/i386/linux/imgact_linux.c b/sys/i386/linux/imgact_linux.c
index 0a4114b..9363b47 100644
--- a/sys/i386/linux/imgact_linux.c
+++ b/sys/i386/linux/imgact_linux.c
@@ -108,7 +108,7 @@ exec_linux_imgact(struct image_params *imgp)
*/
PROC_LOCK(imgp->proc);
if (a_out->a_text > maxtsiz ||
- a_out->a_data + bss_size > lim_cur(imgp->proc, RLIMIT_DATA) ||
+ a_out->a_data + bss_size > lim_cur_proc(imgp->proc, RLIMIT_DATA) ||
racct_set(imgp->proc, RACCT_DATA, a_out->a_data + bss_size) != 0) {
PROC_UNLOCK(imgp->proc);
return (ENOMEM);
diff --git a/sys/i386/linux/linux_machdep.c b/sys/i386/linux/linux_machdep.c
index c9f969b..4fb5785 100644
--- a/sys/i386/linux/linux_machdep.c
+++ b/sys/i386/linux/linux_machdep.c
@@ -509,7 +509,7 @@ linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot,
*/
PROC_LOCK(p);
p->p_vmspace->vm_maxsaddr = (char *)USRSTACK -
- lim_cur(p, RLIMIT_STACK);
+ lim_cur_proc(p, RLIMIT_STACK);
PROC_UNLOCK(p);
}
diff --git a/sys/kern/imgact_aout.c b/sys/kern/imgact_aout.c
index edd5f5f..3165ac0 100644
--- a/sys/kern/imgact_aout.c
+++ b/sys/kern/imgact_aout.c
@@ -248,7 +248,7 @@ exec_aout_imgact(struct image_params *imgp)
a_out->a_text > maxtsiz ||
/* data + bss can't exceed rlimit */
- a_out->a_data + bss_size > lim_cur(imgp->proc, RLIMIT_DATA) ||
+ a_out->a_data + bss_size > lim_cur_proc(imgp->proc, RLIMIT_DATA) ||
racct_set(imgp->proc, RACCT_DATA, a_out->a_data + bss_size) != 0) {
PROC_UNLOCK(imgp->proc);
return (ENOMEM);
diff --git a/sys/kern/imgact_binmisc.c b/sys/kern/imgact_binmisc.c
index 5f324d3..5ee9bb8 100644
--- a/sys/kern/imgact_binmisc.c
+++ b/sys/kern/imgact_binmisc.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2013, Stacey D. Son
+ * Copyright (c) 2013-15, Stacey D. Son
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,9 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/sysctl.h>
+#include <sys/sx.h>
+
+#include <machine/atomic.h>
/**
* Miscellaneous binary interpreter image activator.
@@ -96,7 +99,7 @@ static SLIST_HEAD(, imgact_binmisc_entry) interpreter_list =
static int interp_list_entry_count = 0;
-static struct mtx interp_list_mtx;
+static struct sx interp_list_sx;
int imgact_binmisc_exec(struct image_params *imgp);
@@ -111,7 +114,7 @@ imgact_binmisc_populate_interp(char *str, imgact_binmisc_entry_t *ibe)
char t[IBE_INTERP_LEN_MAX];
char *sp, *tp;
- bzero(t, sizeof(t));
+ memset(t, 0, sizeof(t));
/*
* Normalize interpreter string. Replace white space between args with
@@ -152,8 +155,6 @@ imgact_binmisc_new_entry(ximgact_binmisc_entry_t *xbe)
imgact_binmisc_entry_t *ibe = NULL;
size_t namesz = min(strlen(xbe->xbe_name) + 1, IBE_NAME_MAX);
- mtx_assert(&interp_list_mtx, MA_NOTOWNED);
-
ibe = malloc(sizeof(*ibe), M_BINMISC, M_WAITOK|M_ZERO);
ibe->ibe_name = malloc(namesz, M_BINMISC, M_WAITOK|M_ZERO);
@@ -203,7 +204,7 @@ imgact_binmisc_find_entry(char *name)
{
imgact_binmisc_entry_t *ibe;
- mtx_assert(&interp_list_mtx, MA_OWNED);
+ sx_assert(&interp_list_sx, SA_LOCKED);
SLIST_FOREACH(ibe, &interpreter_list, link) {
if (strncmp(name, ibe->ibe_name, IBE_NAME_MAX) == 0)
@@ -260,21 +261,20 @@ imgact_binmisc_add_entry(ximgact_binmisc_entry_t *xbe)
}
}
- mtx_lock(&interp_list_mtx);
+ sx_xlock(&interp_list_sx);
if (imgact_binmisc_find_entry(xbe->xbe_name) != NULL) {
- mtx_unlock(&interp_list_mtx);
+ sx_xunlock(&interp_list_sx);
return (EEXIST);
}
- mtx_unlock(&interp_list_mtx);
+ /* Preallocate a new entry. */
ibe = imgact_binmisc_new_entry(xbe);
if (!ibe)
return (ENOMEM);
- mtx_lock(&interp_list_mtx);
SLIST_INSERT_HEAD(&interpreter_list, ibe, link);
interp_list_entry_count++;
- mtx_unlock(&interp_list_mtx);
+ sx_xunlock(&interp_list_sx);
return (0);
}
@@ -288,14 +288,14 @@ imgact_binmisc_remove_entry(char *name)
{
imgact_binmisc_entry_t *ibe;
- mtx_lock(&interp_list_mtx);
+ sx_xlock(&interp_list_sx);
if ((ibe = imgact_binmisc_find_entry(name)) == NULL) {
- mtx_unlock(&interp_list_mtx);
+ sx_xunlock(&interp_list_sx);
return (ENOENT);
}
SLIST_REMOVE(&interpreter_list, ibe, imgact_binmisc_entry, link);
interp_list_entry_count--;
- mtx_unlock(&interp_list_mtx);
+ sx_xunlock(&interp_list_sx);
imgact_binmisc_destroy_entry(ibe);
@@ -311,14 +311,14 @@ imgact_binmisc_disable_entry(char *name)
{
imgact_binmisc_entry_t *ibe;
- mtx_lock(&interp_list_mtx);
+ sx_slock(&interp_list_sx);
if ((ibe = imgact_binmisc_find_entry(name)) == NULL) {
- mtx_unlock(&interp_list_mtx);
+ sx_sunlock(&interp_list_sx);
return (ENOENT);
}
- ibe->ibe_flags &= ~IBF_ENABLED;
- mtx_unlock(&interp_list_mtx);
+ atomic_clear_32(&ibe->ibe_flags, IBF_ENABLED);
+ sx_sunlock(&interp_list_sx);
return (0);
}
@@ -332,14 +332,14 @@ imgact_binmisc_enable_entry(char *name)
{
imgact_binmisc_entry_t *ibe;
- mtx_lock(&interp_list_mtx);
+ sx_slock(&interp_list_sx);
if ((ibe = imgact_binmisc_find_entry(name)) == NULL) {
- mtx_unlock(&interp_list_mtx);
+ sx_sunlock(&interp_list_sx);
return (ENOENT);
}
- ibe->ibe_flags |= IBF_ENABLED;
- mtx_unlock(&interp_list_mtx);
+ atomic_set_32(&ibe->ibe_flags, IBF_ENABLED);
+ sx_sunlock(&interp_list_sx);
return (0);
}
@@ -350,9 +350,9 @@ imgact_binmisc_populate_xbe(ximgact_binmisc_entry_t *xbe,
{
uint32_t i;
- mtx_assert(&interp_list_mtx, MA_OWNED);
+ sx_assert(&interp_list_sx, SA_LOCKED);
- bzero(xbe, sizeof(*xbe));
+ memset(xbe, 0, sizeof(*xbe));
strlcpy(xbe->xbe_name, ibe->ibe_name, IBE_NAME_MAX);
/* Copy interpreter string. Replace NULL breaks with space. */
@@ -382,14 +382,14 @@ imgact_binmisc_lookup_entry(char *name, ximgact_binmisc_entry_t *xbe)
imgact_binmisc_entry_t *ibe;
int error = 0;
- mtx_lock(&interp_list_mtx);
+ sx_slock(&interp_list_sx);
if ((ibe = imgact_binmisc_find_entry(name)) == NULL) {
- mtx_unlock(&interp_list_mtx);
+ sx_sunlock(&interp_list_sx);
return (ENOENT);
}
error = imgact_binmisc_populate_xbe(xbe, ibe);
- mtx_unlock(&interp_list_mtx);
+ sx_sunlock(&interp_list_sx);
return (error);
}
@@ -404,14 +404,9 @@ imgact_binmisc_get_all_entries(struct sysctl_req *req)
imgact_binmisc_entry_t *ibe;
int error = 0, count;
- mtx_lock(&interp_list_mtx);
+ sx_slock(&interp_list_sx);
count = interp_list_entry_count;
- /* Don't block in malloc() while holding lock. */
- xbe = malloc(sizeof(*xbe) * count, M_BINMISC, M_NOWAIT|M_ZERO);
- if (!xbe) {
- mtx_unlock(&interp_list_mtx);
- return (ENOMEM);
- }
+ xbe = malloc(sizeof(*xbe) * count, M_BINMISC, M_WAITOK|M_ZERO);
xbep = xbe;
SLIST_FOREACH(ibe, &interpreter_list, link) {
@@ -419,7 +414,7 @@ imgact_binmisc_get_all_entries(struct sysctl_req *req)
if (error)
break;
}
- mtx_unlock(&interp_list_mtx);
+ sx_sunlock(&interp_list_sx);
if (!error)
error = SYSCTL_OUT(req, xbe, sizeof(*xbe) * count);
@@ -556,7 +551,7 @@ imgact_binmisc_find_interpreter(const char *image_header)
int i;
size_t sz;
- mtx_assert(&interp_list_mtx, MA_OWNED);
+ sx_assert(&interp_list_sx, SA_LOCKED);
SLIST_FOREACH(ibe, &interpreter_list, link) {
if (!(IBF_ENABLED & ibe->ibe_flags))
@@ -593,15 +588,15 @@ imgact_binmisc_exec(struct image_params *imgp)
char *s, *d;
/* Do we have an interpreter for the given image header? */
- mtx_lock(&interp_list_mtx);
+ sx_slock(&interp_list_sx);
if ((ibe = imgact_binmisc_find_interpreter(image_header)) == NULL) {
- mtx_unlock(&interp_list_mtx);
+ sx_sunlock(&interp_list_sx);
return (-1);
}
/* No interpreter nesting allowed. */
if (imgp->interpreted & IMGACT_BINMISC) {
- mtx_unlock(&interp_list_mtx);
+ sx_sunlock(&interp_list_sx);
return (ENOEXEC);
}
@@ -649,7 +644,7 @@ imgact_binmisc_exec(struct image_params *imgp)
default:
/* Hmm... This shouldn't happen. */
- mtx_unlock(&interp_list_mtx);
+ sx_sunlock(&interp_list_sx);
printf("%s: Unknown macro #%c sequence in "
"interpreter string\n", KMOD_NAME, *(s + 1));
error = EINVAL;
@@ -660,7 +655,7 @@ imgact_binmisc_exec(struct image_params *imgp)
/* Check to make sure we won't overrun the stringspace. */
if (offset > imgp->args->stringspace) {
- mtx_unlock(&interp_list_mtx);
+ sx_sunlock(&interp_list_sx);
error = E2BIG;
goto done;
}
@@ -720,7 +715,7 @@ imgact_binmisc_exec(struct image_params *imgp)
s++;
}
*d = '\0';
- mtx_unlock(&interp_list_mtx);
+ sx_sunlock(&interp_list_sx);
if (!error)
imgp->interpreter_name = imgp->args->begin_argv;
@@ -736,7 +731,7 @@ static void
imgact_binmisc_init(void *arg)
{
- mtx_init(&interp_list_mtx, KMOD_NAME, NULL, MTX_DEF);
+ sx_init(&interp_list_sx, KMOD_NAME);
}
static void
@@ -745,15 +740,15 @@ imgact_binmisc_fini(void *arg)
imgact_binmisc_entry_t *ibe, *ibe_tmp;
/* Free all the interpreters. */
- mtx_lock(&interp_list_mtx);
+ sx_xlock(&interp_list_sx);
SLIST_FOREACH_SAFE(ibe, &interpreter_list, link, ibe_tmp) {
SLIST_REMOVE(&interpreter_list, ibe, imgact_binmisc_entry,
link);
imgact_binmisc_destroy_entry(ibe);
}
- mtx_unlock(&interp_list_mtx);
+ sx_xunlock(&interp_list_sx);
- mtx_destroy(&interp_list_mtx);
+ sx_destroy(&interp_list_sx);
}
SYSINIT(imgact_binmisc, SI_SUB_EXEC, SI_ORDER_MIDDLE, imgact_binmisc_init, 0);
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index c3953fe..0675128 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -908,11 +908,11 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
* not actually fault in all the segments pages.
*/
PROC_LOCK(imgp->proc);
- if (data_size > lim_cur(imgp->proc, RLIMIT_DATA))
+ if (data_size > lim_cur_proc(imgp->proc, RLIMIT_DATA))
err_str = "Data segment size exceeds process limit";
else if (text_size > maxtsiz)
err_str = "Text segment size exceeds system limit";
- else if (total_size > lim_cur(imgp->proc, RLIMIT_VMEM))
+ else if (total_size > lim_cur_proc(imgp->proc, RLIMIT_VMEM))
err_str = "Total segment size exceeds process limit";
else if (racct_set(imgp->proc, RACCT_DATA, data_size) != 0)
err_str = "Data segment size exceeds resource limit";
@@ -936,7 +936,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
* calculation is that it leaves room for the heap to grow to
* its maximum allowed size.
*/
- addr = round_page((vm_offset_t)vmspace->vm_daddr + lim_max(imgp->proc,
+ addr = round_page((vm_offset_t)vmspace->vm_daddr + lim_max(curthread,
RLIMIT_DATA));
PROC_UNLOCK(imgp->proc);
@@ -1983,7 +1983,7 @@ note_procstat_rlimit(void *arg, struct sbuf *sb, size_t *sizep)
sbuf_bcat(sb, &structsize, sizeof(structsize));
PROC_LOCK(p);
for (i = 0; i < RLIM_NLIMITS; i++)
- lim_rlimit(p, i, &rlim[i]);
+ lim_rlimit_proc(p, i, &rlim[i]);
PROC_UNLOCK(p);
sbuf_bcat(sb, rlim, sizeof(rlim));
}
diff --git a/sys/kern/imgact_gzip.c b/sys/kern/imgact_gzip.c
index ab77a88..47b7280 100644
--- a/sys/kern/imgact_gzip.c
+++ b/sys/kern/imgact_gzip.c
@@ -212,7 +212,7 @@ do_aout_hdr(struct imgact_gzip * gz)
/* data + bss can't exceed rlimit */
gz->a_out.a_data + gz->bss_size >
- lim_cur(gz->ip->proc, RLIMIT_DATA) ||
+ lim_cur_proc(gz->ip->proc, RLIMIT_DATA) ||
racct_set(gz->ip->proc, RACCT_DATA,
gz->a_out.a_data + gz->bss_size) != 0) {
PROC_UNLOCK(gz->ip->proc);
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index cf4eed1..37539c4 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -523,8 +523,6 @@ proc0_init(void *dummy __unused)
#ifdef MAC
mac_cred_create_swapper(newcred);
#endif
- td->td_ucred = crhold(newcred);
-
/* Create sigacts. */
p->p_sigacts = sigacts_alloc();
@@ -556,6 +554,10 @@ proc0_init(void *dummy __unused)
p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_max = pageablemem;
p->p_cpulimit = RLIM_INFINITY;
+ PROC_LOCK(p);
+ thread_cow_get_proc(td, p);
+ PROC_UNLOCK(p);
+
/* Initialize resource accounting structures. */
racct_create(&p->p_racct);
@@ -843,10 +845,10 @@ create_init(const void *udata __unused)
audit_cred_proc1(newcred);
#endif
proc_set_cred(initproc, newcred);
+ cred_update_thread(FIRST_THREAD_IN_PROC(initproc));
PROC_UNLOCK(initproc);
sx_xunlock(&proctree_lock);
crfree(oldcred);
- cred_update_thread(FIRST_THREAD_IN_PROC(initproc));
cpu_set_fork_handler(FIRST_THREAD_IN_PROC(initproc), start_init, NULL);
}
SYSINIT(init, SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL);
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 7848396..8220786 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -109,7 +109,7 @@ static void fdgrowtable(struct filedesc *fdp, int nfd);
static void fdgrowtable_exp(struct filedesc *fdp, int nfd);
static void fdunused(struct filedesc *fdp, int fd);
static void fdused(struct filedesc *fdp, int fd);
-static int getmaxfd(struct proc *p);
+static int getmaxfd(struct thread *td);
/* Flags for do_dup() */
#define DUP_FIXED 0x1 /* Force fixed allocation. */
@@ -178,9 +178,6 @@ volatile int openfiles; /* actual number of open files */
struct mtx sigio_lock; /* mtx to protect pointers to sigio */
void (*mq_fdclose)(struct thread *td, int fd, struct file *fp);
-/* A mutex to protect the association between a proc and filedesc. */
-static struct mtx fdesc_mtx;
-
/*
* If low >= size, just return low. Otherwise find the first zero bit in the
* given bitmap, starting at low and not exceeding size - 1. Return size if
@@ -312,7 +309,7 @@ fdfree(struct filedesc *fdp, int fd)
seq_write_begin(&fde->fde_seq);
#endif
fdefree_last(fde);
- bzero(fde, fde_change_size);
+ fde->fde_file = NULL;
fdunused(fdp, fd);
#ifdef CAPABILITIES
seq_write_end(&fde->fde_seq);
@@ -331,16 +328,19 @@ struct getdtablesize_args {
int
sys_getdtablesize(struct thread *td, struct getdtablesize_args *uap)
{
- struct proc *p = td->td_proc;
+#ifdef RACCT
uint64_t lim;
+#endif
- PROC_LOCK(p);
td->td_retval[0] =
- min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc);
+ min((int)lim_cur(td, RLIMIT_NOFILE), maxfilesperproc);
+#ifdef RACCT
+ PROC_LOCK(td->td_proc);
lim = racct_get_limit(td->td_proc, RACCT_NOFILE);
- PROC_UNLOCK(p);
+ PROC_UNLOCK(td->td_proc);
if (lim < td->td_retval[0])
td->td_retval[0] = lim;
+#endif
return (0);
}
@@ -746,7 +746,8 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
arg = arg ? 128 * 1024: 0;
/* FALLTHROUGH */
case F_READAHEAD:
- error = fget_unlocked(fdp, fd, NULL, &fp, NULL);
+ error = fget_unlocked(fdp, fd,
+ cap_rights_init(&rights), &fp, NULL);
if (error != 0)
break;
if (fp->f_type != DTYPE_VNODE) {
@@ -783,15 +784,10 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
}
static int
-getmaxfd(struct proc *p)
+getmaxfd(struct thread *td)
{
- int maxfd;
- PROC_LOCK(p);
- maxfd = min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc);
- PROC_UNLOCK(p);
-
- return (maxfd);
+ return (min((int)lim_cur(td, RLIMIT_NOFILE), maxfilesperproc));
}
/*
@@ -819,7 +815,7 @@ do_dup(struct thread *td, int flags, int old, int new)
return (EBADF);
if (new < 0)
return (flags & DUP_FCNTL ? EINVAL : EBADF);
- maxfd = getmaxfd(p);
+ maxfd = getmaxfd(td);
if (new >= maxfd)
return (flags & DUP_FCNTL ? EINVAL : EBADF);
@@ -1619,7 +1615,7 @@ fdalloc(struct thread *td, int minfd, int *result)
if (fdp->fd_freefile > minfd)
minfd = fdp->fd_freefile;
- maxfd = getmaxfd(p);
+ maxfd = getmaxfd(td);
/*
* Search the bitmap for a free descriptor starting at minfd.
@@ -1656,7 +1652,6 @@ fdalloc(struct thread *td, int minfd, int *result)
("fd_first_free() returned non-free descriptor"));
KASSERT(fdp->fd_ofiles[fd].fde_file == NULL,
("file descriptor isn't free"));
- KASSERT(fdp->fd_ofiles[fd].fde_flags == 0, ("file flags are set"));
fdused(fdp, fd);
*result = fd;
return (0);
@@ -1755,32 +1750,23 @@ falloc_noinstall(struct thread *td, struct file **resultfp)
/*
* Install a file in a file descriptor table.
*/
-int
-finstall(struct thread *td, struct file *fp, int *fd, int flags,
+void
+_finstall(struct filedesc *fdp, struct file *fp, int fd, int flags,
struct filecaps *fcaps)
{
- struct filedesc *fdp = td->td_proc->p_fd;
struct filedescent *fde;
- int error;
- KASSERT(fd != NULL, ("%s: fd == NULL", __func__));
- KASSERT(fp != NULL, ("%s: fp == NULL", __func__));
+ MPASS(fp != NULL);
if (fcaps != NULL)
filecaps_validate(fcaps, __func__);
+ FILEDESC_XLOCK_ASSERT(fdp);
- FILEDESC_XLOCK(fdp);
- if ((error = fdalloc(td, 0, fd))) {
- FILEDESC_XUNLOCK(fdp);
- return (error);
- }
- fhold(fp);
- fde = &fdp->fd_ofiles[*fd];
+ fde = &fdp->fd_ofiles[fd];
#ifdef CAPABILITIES
seq_write_begin(&fde->fde_seq);
#endif
fde->fde_file = fp;
- if ((flags & O_CLOEXEC) != 0)
- fde->fde_flags |= UF_EXCLOSE;
+ fde->fde_flags = (flags & O_CLOEXEC) != 0 ? UF_EXCLOSE : 0;
if (fcaps != NULL)
filecaps_move(fcaps, &fde->fde_caps);
else
@@ -1788,6 +1774,24 @@ finstall(struct thread *td, struct file *fp, int *fd, int flags,
#ifdef CAPABILITIES
seq_write_end(&fde->fde_seq);
#endif
+}
+
+int
+finstall(struct thread *td, struct file *fp, int *fd, int flags,
+ struct filecaps *fcaps)
+{
+ struct filedesc *fdp = td->td_proc->p_fd;
+ int error;
+
+ MPASS(fd != NULL);
+
+ FILEDESC_XLOCK(fdp);
+ if ((error = fdalloc(td, 0, fd))) {
+ FILEDESC_XUNLOCK(fdp);
+ return (error);
+ }
+ fhold(fp);
+ _finstall(fdp, fp, *fd, flags, fcaps);
FILEDESC_XUNLOCK(fdp);
return (0);
}
@@ -1809,8 +1813,8 @@ fdinit(struct filedesc *fdp, bool prepfiles)
/* Create the file descriptor table. */
FILEDESC_LOCK_INIT(newfdp);
- newfdp->fd_refcnt = 1;
- newfdp->fd_holdcnt = 1;
+ refcount_init(&newfdp->fd_refcnt, 1);
+ refcount_init(&newfdp->fd_holdcnt, 1);
newfdp->fd_cmask = CMASK;
newfdp->fd_map = newfdp0->fd_dmap;
newfdp->fd_lastfile = -1;
@@ -1852,24 +1856,19 @@ fdhold(struct proc *p)
{
struct filedesc *fdp;
- mtx_lock(&fdesc_mtx);
+ PROC_LOCK_ASSERT(p, MA_OWNED);
fdp = p->p_fd;
if (fdp != NULL)
- fdp->fd_holdcnt++;
- mtx_unlock(&fdesc_mtx);
+ refcount_acquire(&fdp->fd_holdcnt);
return (fdp);
}
static void
fddrop(struct filedesc *fdp)
{
- int i;
if (fdp->fd_holdcnt > 1) {
- mtx_lock(&fdesc_mtx);
- i = --fdp->fd_holdcnt;
- mtx_unlock(&fdesc_mtx);
- if (i > 0)
+ if (refcount_release(&fdp->fd_holdcnt) == 0)
return;
}
@@ -1884,9 +1883,7 @@ struct filedesc *
fdshare(struct filedesc *fdp)
{
- FILEDESC_XLOCK(fdp);
- fdp->fd_refcnt++;
- FILEDESC_XUNLOCK(fdp);
+ refcount_acquire(&fdp->fd_refcnt);
return (fdp);
}
@@ -2032,6 +2029,7 @@ retry:
void
fdescfree(struct thread *td)
{
+ struct proc *p;
struct filedesc0 *fdp0;
struct filedesc *fdp;
struct freetable *ft, *tft;
@@ -2040,31 +2038,29 @@ fdescfree(struct thread *td)
struct vnode *cdir, *jdir, *rdir;
int i;
- fdp = td->td_proc->p_fd;
+ p = td->td_proc;
+ fdp = p->p_fd;
MPASS(fdp != NULL);
#ifdef RACCT
if (racct_enable) {
- PROC_LOCK(td->td_proc);
- racct_set(td->td_proc, RACCT_NOFILE, 0);
- PROC_UNLOCK(td->td_proc);
+ PROC_LOCK(p);
+ racct_set(p, RACCT_NOFILE, 0);
+ PROC_UNLOCK(p);
}
#endif
if (td->td_proc->p_fdtol != NULL)
fdclearlocks(td);
- mtx_lock(&fdesc_mtx);
- td->td_proc->p_fd = NULL;
- mtx_unlock(&fdesc_mtx);
+ PROC_LOCK(p);
+ p->p_fd = NULL;
+ PROC_UNLOCK(p);
- FILEDESC_XLOCK(fdp);
- i = --fdp->fd_refcnt;
- if (i > 0) {
- FILEDESC_XUNLOCK(fdp);
+ if (refcount_release(&fdp->fd_refcnt) == 0)
return;
- }
+ FILEDESC_XLOCK(fdp);
cdir = fdp->fd_cdir;
fdp->fd_cdir = NULL;
rdir = fdp->fd_rdir;
@@ -2373,11 +2369,9 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
if (fp == NULL)
return (EBADF);
#ifdef CAPABILITIES
- if (needrightsp != NULL) {
- error = cap_check(&haverights, needrightsp);
- if (error != 0)
- return (error);
- }
+ error = cap_check(&haverights, needrightsp);
+ if (error != 0)
+ return (error);
#endif
retry:
count = fp->f_count;
@@ -2438,11 +2432,9 @@ _fget(struct thread *td, int fd, struct file **fpp, int flags,
*fpp = NULL;
fdp = td->td_proc->p_fd;
- if (needrightsp != NULL)
- needrights = *needrightsp;
- else
- cap_rights_init(&needrights);
- error = fget_unlocked(fdp, fd, &needrights, &fp, seqp);
+ if (needrightsp == NULL)
+ needrightsp = cap_rights_init(&needrights);
+ error = fget_unlocked(fdp, fd, needrightsp, &fp, seqp);
if (error != 0)
return (error);
if (fp->f_ops == &badfileops) {
@@ -2855,7 +2847,7 @@ dupfdopen(struct thread *td, struct filedesc *fdp, int dfd, int mode,
seq_write_begin(&newfde->fde_seq);
#endif
memcpy(newfde, oldfde, fde_change_size);
- bzero(oldfde, fde_change_size);
+ oldfde->fde_file = NULL;
fdunused(fdp, dfd);
#ifdef CAPABILITIES
seq_write_end(&newfde->fde_seq);
@@ -2884,7 +2876,9 @@ mountcheckdirs(struct vnode *olddp, struct vnode *newdp)
nrele = 0;
sx_slock(&allproc_lock);
FOREACH_PROC_IN_SYSTEM(p) {
+ PROC_LOCK(p);
fdp = fdhold(p);
+ PROC_UNLOCK(p);
if (fdp == NULL)
continue;
FILEDESC_XLOCK(fdp);
@@ -2979,9 +2973,13 @@ sysctl_kern_file(SYSCTL_HANDLER_ARGS)
n = 0;
sx_slock(&allproc_lock);
FOREACH_PROC_IN_SYSTEM(p) {
- if (p->p_state == PRS_NEW)
+ PROC_LOCK(p);
+ if (p->p_state == PRS_NEW) {
+ PROC_UNLOCK(p);
continue;
+ }
fdp = fdhold(p);
+ PROC_UNLOCK(p);
if (fdp == NULL)
continue;
/* overestimates sparse tables. */
@@ -3008,8 +3006,8 @@ sysctl_kern_file(SYSCTL_HANDLER_ARGS)
}
xf.xf_pid = p->p_pid;
xf.xf_uid = p->p_ucred->cr_uid;
- PROC_UNLOCK(p);
fdp = fdhold(p);
+ PROC_UNLOCK(p);
if (fdp == NULL)
continue;
FILEDESC_SLOCK(fdp);
@@ -3644,7 +3642,6 @@ filelistinit(void *dummy)
filedesc0_zone = uma_zcreate("filedesc0", sizeof(struct filedesc0),
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
mtx_init(&sigio_lock, "sigio lock", NULL, MTX_DEF);
- mtx_init(&fdesc_mtx, "fdesc", NULL, MTX_DEF);
}
SYSINIT(select, SI_SUB_LOCK, SI_ORDER_FIRST, filelistinit, NULL);
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 9000add..ff17fe9 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -754,14 +754,10 @@ kern_kqueue(struct thread *td, int flags)
p = td->td_proc;
cred = td->td_ucred;
crhold(cred);
- PROC_LOCK(p);
- if (!chgkqcnt(cred->cr_ruidinfo, 1, lim_cur(td->td_proc,
- RLIMIT_KQUEUES))) {
- PROC_UNLOCK(p);
+ if (!chgkqcnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_KQUEUES))) {
crfree(cred);
return (ENOMEM);
}
- PROC_UNLOCK(p);
fdp = p->p_fd;
error = falloc(td, &fp, &fd, flags);
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index 8668f0d..375e644 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -966,13 +966,10 @@ exec_map_first_page(imgp)
}
initial_pagein = i;
rv = vm_pager_get_pages(object, ma, initial_pagein, 0);
- ma[0] = vm_page_lookup(object, 0);
- if ((rv != VM_PAGER_OK) || (ma[0] == NULL)) {
- if (ma[0] != NULL) {
- vm_page_lock(ma[0]);
- vm_page_free(ma[0]);
- vm_page_unlock(ma[0]);
- }
+ if (rv != VM_PAGER_OK) {
+ vm_page_lock(ma[0]);
+ vm_page_free(ma[0]);
+ vm_page_unlock(ma[0]);
VM_OBJECT_WUNLOCK(object);
return (EIO);
}
@@ -1073,7 +1070,7 @@ exec_new_vmspace(imgp, sv)
if (imgp->stack_sz != 0) {
ssiz = trunc_page(imgp->stack_sz);
PROC_LOCK(p);
- lim_rlimit(p, RLIMIT_STACK, &rlim_stack);
+ lim_rlimit_proc(p, RLIMIT_STACK, &rlim_stack);
PROC_UNLOCK(p);
if (ssiz > rlim_stack.rlim_max)
ssiz = rlim_stack.rlim_max;
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index a3fde18..3fd4f09 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -496,7 +496,6 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
p2->p_swtick = ticks;
if (p1->p_flag & P_PROFIL)
startprofclock(p2);
- td2->td_ucred = crhold(p2->p_ucred);
if (flags & RFSIGSHARE) {
p2->p_sigacts = sigacts_hold(p1->p_sigacts);
@@ -526,6 +525,8 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
*/
lim_fork(p1, p2);
+ thread_cow_get_proc(td2, p2);
+
pstats_fork(p1->p_stats, p2->p_stats);
PROC_UNLOCK(p1);
@@ -911,10 +912,8 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp,
if (error == 0)
ok = chgproccnt(td->td_ucred->cr_ruidinfo, 1, 0);
else {
- PROC_LOCK(p1);
ok = chgproccnt(td->td_ucred->cr_ruidinfo, 1,
- lim_cur(p1, RLIMIT_NPROC));
- PROC_UNLOCK(p1);
+ lim_cur(td, RLIMIT_NPROC));
}
if (ok) {
do_fork(td, flags, newproc, td2, vm2, pdflags);
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index c87c4e2..c118d74 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -1331,7 +1331,7 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
pr->pr_securelevel = ppr->pr_securelevel;
pr->pr_allow = JAIL_DEFAULT_ALLOW & ppr->pr_allow;
- pr->pr_enforce_statfs = JAIL_DEFAULT_ENFORCE_STATFS;
+ pr->pr_enforce_statfs = jail_default_enforce_statfs;
pr->pr_devfs_rsnum = ppr->pr_devfs_rsnum;
pr->pr_osreldate = osreldt ? osreldt : ppr->pr_osreldate;
diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c
index ee94de0..863bbc6 100644
--- a/sys/kern/kern_kthread.c
+++ b/sys/kern/kern_kthread.c
@@ -289,7 +289,7 @@ kthread_add(void (*func)(void *), void *arg, struct proc *p,
cpu_set_fork_handler(newtd, func, arg);
newtd->td_pflags |= TDP_KTHREAD;
- newtd->td_ucred = crhold(p->p_ucred);
+ thread_cow_get_proc(newtd, p);
/* this code almost the same as create_thread() in kern_thr.c */
p->p_flag |= P_HADTHREADS;
diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c
index ea6f7a6..72fc434 100644
--- a/sys/kern/kern_mutex.c
+++ b/sys/kern/kern_mutex.c
@@ -384,6 +384,7 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t tid, int opts,
uint64_t spin_cnt = 0;
uint64_t sleep_cnt = 0;
int64_t sleep_time = 0;
+ int64_t all_time = 0;
#endif
if (SCHEDULER_STOPPED())
@@ -414,6 +415,9 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t tid, int opts,
CTR4(KTR_LOCK,
"_mtx_lock_sleep: %s contested (lock=%p) at %s:%d",
m->lock_object.lo_name, (void *)m->mtx_lock, file, line);
+#ifdef KDTRACE_HOOKS
+ all_time -= lockstat_nsecs();
+#endif
while (!_mtx_obtain_lock(m, tid)) {
#ifdef KDTRACE_HOOKS
@@ -517,6 +521,9 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t tid, int opts,
sleep_cnt++;
#endif
}
+#ifdef KDTRACE_HOOKS
+ all_time += lockstat_nsecs();
+#endif
#ifdef KTR
if (cont_logged) {
CTR4(KTR_CONTENTION,
@@ -534,7 +541,7 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t tid, int opts,
* Only record the loops spinning and not sleeping.
*/
if (spin_cnt > sleep_cnt)
- LOCKSTAT_RECORD1(LS_MTX_LOCK_SPIN, m, (spin_cnt - sleep_cnt));
+ LOCKSTAT_RECORD1(LS_MTX_LOCK_SPIN, m, (all_time - sleep_time));
#endif
}
@@ -574,6 +581,9 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t tid, int opts,
int contested = 0;
uint64_t waittime = 0;
#endif
+#ifdef KDTRACE_HOOKS
+ int64_t spin_time = 0;
+#endif
if (SCHEDULER_STOPPED())
return;
@@ -589,6 +599,9 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t tid, int opts,
PMC_SOFT_CALL( , , lock, failed);
#endif
lock_profile_obtain_lock_failed(&m->lock_object, &contested, &waittime);
+#ifdef KDTRACE_HOOKS
+ spin_time -= lockstat_nsecs();
+#endif
while (!_mtx_obtain_lock(m, tid)) {
/* Give interrupts a chance while we spin. */
@@ -606,6 +619,9 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t tid, int opts,
}
spinlock_enter();
}
+#ifdef KDTRACE_HOOKS
+ spin_time += lockstat_nsecs();
+#endif
if (LOCK_LOG_TEST(&m->lock_object, opts))
CTR1(KTR_LOCK, "_mtx_lock_spin: %p spin done", m);
@@ -614,7 +630,7 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t tid, int opts,
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_MTX_SPIN_LOCK_ACQUIRE, m,
contested, waittime, (file), (line));
- LOCKSTAT_RECORD1(LS_MTX_SPIN_LOCK_SPIN, m, i);
+ LOCKSTAT_RECORD1(LS_MTX_SPIN_LOCK_SPIN, m, spin_time);
}
#endif /* SMP */
@@ -629,7 +645,7 @@ thread_lock_flags_(struct thread *td, int opts, const char *file, int line)
uint64_t waittime = 0;
#endif
#ifdef KDTRACE_HOOKS
- uint64_t spin_cnt = 0;
+ int64_t spin_time = 0;
#endif
i = 0;
@@ -638,6 +654,9 @@ thread_lock_flags_(struct thread *td, int opts, const char *file, int line)
if (SCHEDULER_STOPPED())
return;
+#ifdef KDTRACE_HOOKS
+ spin_time -= lockstat_nsecs();
+#endif
for (;;) {
retry:
spinlock_enter();
@@ -654,9 +673,6 @@ retry:
WITNESS_CHECKORDER(&m->lock_object,
opts | LOP_NEWORDER | LOP_EXCLUSIVE, file, line, NULL);
while (!_mtx_obtain_lock(m, tid)) {
-#ifdef KDTRACE_HOOKS
- spin_cnt++;
-#endif
if (m->mtx_lock == tid) {
m->mtx_recurse++;
break;
@@ -685,17 +701,17 @@ retry:
if (m == td->td_lock)
break;
__mtx_unlock_spin(m); /* does spinlock_exit() */
+ }
#ifdef KDTRACE_HOOKS
- spin_cnt++;
+ spin_time += lockstat_nsecs();
#endif
- }
if (m->mtx_recurse == 0)
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_MTX_SPIN_LOCK_ACQUIRE,
m, contested, waittime, (file), (line));
LOCK_LOG_LOCK("LOCK", &m->lock_object, opts, m->mtx_recurse, file,
line);
WITNESS_LOCK(&m->lock_object, opts | LOP_EXCLUSIVE, file, line);
- LOCKSTAT_RECORD1(LS_THREAD_LOCK_SPIN, m, spin_cnt);
+ LOCKSTAT_RECORD1(LS_THREAD_LOCK_SPIN, m, spin_time);
}
struct mtx *
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index fc33feb..27c6f40 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -2615,7 +2615,7 @@ sysctl_kern_proc_rlimit(SYSCTL_HANDLER_ARGS)
*/
if (req->oldptr != NULL) {
PROC_LOCK(p);
- lim_rlimit(p, which, &rlim);
+ lim_rlimit_proc(p, which, &rlim);
PROC_UNLOCK(p);
}
error = SYSCTL_OUT(req, &rlim, sizeof(rlim));
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index 9c49f71..b531763 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1946,9 +1946,8 @@ cred_update_thread(struct thread *td)
p = td->td_proc;
cred = td->td_ucred;
- PROC_LOCK(p);
+ PROC_LOCK_ASSERT(p, MA_OWNED);
td->td_ucred = crhold(p->p_ucred);
- PROC_UNLOCK(p);
if (cred != NULL)
crfree(cred);
}
@@ -1987,6 +1986,8 @@ proc_set_cred(struct proc *p, struct ucred *newcred)
oldcred = p->p_ucred;
p->p_ucred = newcred;
+ if (newcred != NULL)
+ PROC_UPDATE_COW(p);
return (oldcred);
}
diff --git a/sys/kern/kern_racct.c b/sys/kern/kern_racct.c
index e8ae9fe..2a10790 100644
--- a/sys/kern/kern_racct.c
+++ b/sys/kern/kern_racct.c
@@ -500,7 +500,7 @@ racct_destroy(struct racct **racct)
* may be less than zero.
*/
static void
-racct_alloc_resource(struct racct *racct, int resource,
+racct_adjust_resource(struct racct *racct, int resource,
uint64_t amount)
{
@@ -553,7 +553,7 @@ racct_add_locked(struct proc *p, int resource, uint64_t amount)
return (error);
}
#endif
- racct_alloc_resource(p->p_racct, resource, amount);
+ racct_adjust_resource(p->p_racct, resource, amount);
racct_add_cred_locked(p->p_ucred, resource, amount);
return (0);
@@ -587,11 +587,11 @@ racct_add_cred_locked(struct ucred *cred, int resource, uint64_t amount)
SDT_PROBE(racct, kernel, rusage, add__cred, cred, resource, amount,
0, 0);
- racct_alloc_resource(cred->cr_ruidinfo->ui_racct, resource, amount);
+ racct_adjust_resource(cred->cr_ruidinfo->ui_racct, resource, amount);
for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent)
- racct_alloc_resource(pr->pr_prison_racct->prr_racct, resource,
+ racct_adjust_resource(pr->pr_prison_racct->prr_racct, resource,
amount);
- racct_alloc_resource(cred->cr_loginclass->lc_racct, resource, amount);
+ racct_adjust_resource(cred->cr_loginclass->lc_racct, resource, amount);
}
/*
@@ -631,7 +631,7 @@ racct_add_force(struct proc *p, int resource, uint64_t amount)
PROC_LOCK_ASSERT(p, MA_OWNED);
mtx_lock(&racct_lock);
- racct_alloc_resource(p->p_racct, resource, amount);
+ racct_adjust_resource(p->p_racct, resource, amount);
mtx_unlock(&racct_lock);
racct_add_cred(p->p_ucred, resource, amount);
}
@@ -685,7 +685,7 @@ racct_set_locked(struct proc *p, int resource, uint64_t amount)
}
}
#endif
- racct_alloc_resource(p->p_racct, resource, diff_proc);
+ racct_adjust_resource(p->p_racct, resource, diff_proc);
if (diff_cred > 0)
racct_add_cred_locked(p->p_ucred, resource, diff_cred);
else if (diff_cred < 0)
@@ -747,7 +747,7 @@ racct_set_force_locked(struct proc *p, int resource, uint64_t amount)
} else
diff_cred = diff_proc;
- racct_alloc_resource(p->p_racct, resource, diff_proc);
+ racct_adjust_resource(p->p_racct, resource, diff_proc);
if (diff_cred > 0)
racct_add_cred_locked(p->p_ucred, resource, diff_cred);
else if (diff_cred < 0)
@@ -849,7 +849,7 @@ racct_sub(struct proc *p, int resource, uint64_t amount)
"than allocated %jd for %s (pid %d)", __func__, amount, resource,
(intmax_t)p->p_racct->r_resources[resource], p->p_comm, p->p_pid));
- racct_alloc_resource(p->p_racct, resource, -amount);
+ racct_adjust_resource(p->p_racct, resource, -amount);
racct_sub_cred_locked(p->p_ucred, resource, amount);
mtx_unlock(&racct_lock);
}
@@ -870,11 +870,11 @@ racct_sub_cred_locked(struct ucred *cred, int resource, uint64_t amount)
resource));
#endif
- racct_alloc_resource(cred->cr_ruidinfo->ui_racct, resource, -amount);
+ racct_adjust_resource(cred->cr_ruidinfo->ui_racct, resource, -amount);
for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent)
- racct_alloc_resource(pr->pr_prison_racct->prr_racct, resource,
+ racct_adjust_resource(pr->pr_prison_racct->prr_racct, resource,
-amount);
- racct_alloc_resource(cred->cr_loginclass->lc_racct, resource, -amount);
+ racct_adjust_resource(cred->cr_loginclass->lc_racct, resource, -amount);
}
/*
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index dac49cd..546f3b2 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -560,15 +560,11 @@ ogetrlimit(struct thread *td, register struct ogetrlimit_args *uap)
{
struct orlimit olim;
struct rlimit rl;
- struct proc *p;
int error;
if (uap->which >= RLIM_NLIMITS)
return (EINVAL);
- p = td->td_proc;
- PROC_LOCK(p);
- lim_rlimit(p, uap->which, &rl);
- PROC_UNLOCK(p);
+ lim_rlimit(td, uap->which, &rl);
/*
* XXX would be more correct to convert only RLIM_INFINITY to the
@@ -625,7 +621,7 @@ lim_cb(void *arg)
}
PROC_STATUNLOCK(p);
if (p->p_rux.rux_runtime > p->p_cpulimit * cpu_tickrate()) {
- lim_rlimit(p, RLIMIT_CPU, &rlim);
+ lim_rlimit_proc(p, RLIMIT_CPU, &rlim);
if (p->p_rux.rux_runtime >= rlim.rlim_max * cpu_tickrate()) {
killproc(p, "exceeded maximum CPU limit");
} else {
@@ -667,29 +663,21 @@ kern_proc_setrlimit(struct thread *td, struct proc *p, u_int which,
limp->rlim_max = RLIM_INFINITY;
oldssiz.rlim_cur = 0;
- newlim = NULL;
+ newlim = lim_alloc();
PROC_LOCK(p);
- if (lim_shared(p->p_limit)) {
- PROC_UNLOCK(p);
- newlim = lim_alloc();
- PROC_LOCK(p);
- }
oldlim = p->p_limit;
alimp = &oldlim->pl_rlimit[which];
if (limp->rlim_cur > alimp->rlim_max ||
limp->rlim_max > alimp->rlim_max)
if ((error = priv_check(td, PRIV_PROC_SETRLIMIT))) {
PROC_UNLOCK(p);
- if (newlim != NULL)
- lim_free(newlim);
+ lim_free(newlim);
return (error);
}
if (limp->rlim_cur > limp->rlim_max)
limp->rlim_cur = limp->rlim_max;
- if (newlim != NULL) {
- lim_copy(newlim, oldlim);
- alimp = &newlim->pl_rlimit[which];
- }
+ lim_copy(newlim, oldlim);
+ alimp = &newlim->pl_rlimit[which];
switch (which) {
@@ -739,11 +727,10 @@ kern_proc_setrlimit(struct thread *td, struct proc *p, u_int which,
if (p->p_sysent->sv_fixlimit != NULL)
p->p_sysent->sv_fixlimit(limp, which);
*alimp = *limp;
- if (newlim != NULL)
- p->p_limit = newlim;
+ p->p_limit = newlim;
+ PROC_UPDATE_COW(p);
PROC_UNLOCK(p);
- if (newlim != NULL)
- lim_free(oldlim);
+ lim_free(oldlim);
if (which == RLIMIT_STACK &&
/*
@@ -793,15 +780,11 @@ int
sys_getrlimit(struct thread *td, register struct __getrlimit_args *uap)
{
struct rlimit rlim;
- struct proc *p;
int error;
if (uap->which >= RLIM_NLIMITS)
return (EINVAL);
- p = td->td_proc;
- PROC_LOCK(p);
- lim_rlimit(p, uap->which, &rlim);
- PROC_UNLOCK(p);
+ lim_rlimit(td, uap->which, &rlim);
error = copyout(&rlim, uap->rlp, sizeof(struct rlimit));
return (error);
}
@@ -1172,11 +1155,20 @@ lim_copy(struct plimit *dst, struct plimit *src)
* which parameter specifies the index into the rlimit array.
*/
rlim_t
-lim_max(struct proc *p, int which)
+lim_max(struct thread *td, int which)
{
struct rlimit rl;
- lim_rlimit(p, which, &rl);
+ lim_rlimit(td, which, &rl);
+ return (rl.rlim_max);
+}
+
+rlim_t
+lim_max_proc(struct proc *p, int which)
+{
+ struct rlimit rl;
+
+ lim_rlimit_proc(p, which, &rl);
return (rl.rlim_max);
}
@@ -1185,11 +1177,20 @@ lim_max(struct proc *p, int which)
* The which parameter which specifies the index into the rlimit array
*/
rlim_t
-lim_cur(struct proc *p, int which)
+lim_cur(struct thread *td, int which)
{
struct rlimit rl;
- lim_rlimit(p, which, &rl);
+ lim_rlimit(td, which, &rl);
+ return (rl.rlim_cur);
+}
+
+rlim_t
+lim_cur_proc(struct proc *p, int which)
+{
+ struct rlimit rl;
+
+ lim_rlimit_proc(p, which, &rl);
return (rl.rlim_cur);
}
@@ -1198,7 +1199,20 @@ lim_cur(struct proc *p, int which)
* specified by 'which' in the rlimit structure pointed to by 'rlp'.
*/
void
-lim_rlimit(struct proc *p, int which, struct rlimit *rlp)
+lim_rlimit(struct thread *td, int which, struct rlimit *rlp)
+{
+ struct proc *p = td->td_proc;
+
+ MPASS(td == curthread);
+ KASSERT(which >= 0 && which < RLIM_NLIMITS,
+ ("request for invalid resource limit"));
+ *rlp = td->td_limit->pl_rlimit[which];
+ if (p->p_sysent->sv_fixlimit != NULL)
+ p->p_sysent->sv_fixlimit(rlp, which);
+}
+
+void
+lim_rlimit_proc(struct proc *p, int which, struct rlimit *rlp)
{
PROC_LOCK_ASSERT(p, MA_OWNED);
@@ -1441,3 +1455,17 @@ chgkqcnt(struct uidinfo *uip, int diff, rlim_t max)
}
return (1);
}
+
+void
+lim_update_thread(struct thread *td)
+{
+ struct proc *p;
+ struct plimit *lim;
+
+ p = td->td_proc;
+ lim = td->td_limit;
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ td->td_limit = lim_hold(p->p_limit);
+ if (lim != NULL)
+ lim_free(lim);
+}
diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c
index d3cfbdd..f75912b 100644
--- a/sys/kern/kern_rwlock.c
+++ b/sys/kern/kern_rwlock.c
@@ -300,6 +300,9 @@ __rw_try_wlock(volatile uintptr_t *c, const char *file, int line)
if (rval) {
WITNESS_LOCK(&rw->lock_object, LOP_EXCLUSIVE | LOP_TRYLOCK,
file, line);
+ if (!rw_recursed(rw))
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_RW_WLOCK_ACQUIRE,
+ rw, 0, 0, file, line);
curthread->td_locks++;
}
return (rval);
@@ -352,9 +355,11 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line)
#endif
uintptr_t v;
#ifdef KDTRACE_HOOKS
+ uintptr_t state;
uint64_t spin_cnt = 0;
uint64_t sleep_cnt = 0;
int64_t sleep_time = 0;
+ int64_t all_time = 0;
#endif
if (SCHEDULER_STOPPED())
@@ -372,6 +377,10 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line)
rw->lock_object.lo_name, file, line));
WITNESS_CHECKORDER(&rw->lock_object, LOP_NEWORDER, file, line, NULL);
+#ifdef KDTRACE_HOOKS
+ all_time -= lockstat_nsecs();
+ state = rw->rw_lock;
+#endif
for (;;) {
#ifdef KDTRACE_HOOKS
spin_cnt++;
@@ -534,7 +543,19 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line)
CTR2(KTR_LOCK, "%s: %p resuming from turnstile",
__func__, rw);
}
+#ifdef KDTRACE_HOOKS
+ all_time += lockstat_nsecs();
+ if (sleep_time)
+ LOCKSTAT_RECORD4(LS_RW_RLOCK_BLOCK, rw, sleep_time,
+ LOCKSTAT_READER, (state & RW_LOCK_READ) == 0,
+ (state & RW_LOCK_READ) == 0 ? 0 : RW_READERS(state));
+ /* Record only the loops spinning and not sleeping. */
+ if (spin_cnt > sleep_cnt)
+ LOCKSTAT_RECORD4(LS_RW_RLOCK_SPIN, rw, all_time - sleep_time,
+ LOCKSTAT_READER, (state & RW_LOCK_READ) == 0,
+ (state & RW_LOCK_READ) == 0 ? 0 : RW_READERS(state));
+#endif
/*
* TODO: acquire "owner of record" here. Here be turnstile dragons
* however. turnstiles don't like owners changing between calls to
@@ -546,16 +567,6 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line)
WITNESS_LOCK(&rw->lock_object, 0, file, line);
curthread->td_locks++;
curthread->td_rw_rlocks++;
-#ifdef KDTRACE_HOOKS
- if (sleep_time)
- LOCKSTAT_RECORD1(LS_RW_RLOCK_BLOCK, rw, sleep_time);
-
- /*
- * Record only the loops spinning and not sleeping.
- */
- if (spin_cnt > sleep_cnt)
- LOCKSTAT_RECORD1(LS_RW_RLOCK_SPIN, rw, (spin_cnt - sleep_cnt));
-#endif
}
int
@@ -583,6 +594,8 @@ __rw_try_rlock(volatile uintptr_t *c, const char *file, int line)
LOCK_LOG_TRY("RLOCK", &rw->lock_object, 0, 1, file,
line);
WITNESS_LOCK(&rw->lock_object, LOP_TRYLOCK, file, line);
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_RW_RLOCK_ACQUIRE,
+ rw, 0, 0, file, line);
curthread->td_locks++;
curthread->td_rw_rlocks++;
return (1);
@@ -727,9 +740,11 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
int contested = 0;
#endif
#ifdef KDTRACE_HOOKS
+ uintptr_t state;
uint64_t spin_cnt = 0;
uint64_t sleep_cnt = 0;
int64_t sleep_time = 0;
+ int64_t all_time = 0;
#endif
if (SCHEDULER_STOPPED())
@@ -751,6 +766,10 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
CTR5(KTR_LOCK, "%s: %s contested (lock=%p) at %s:%d", __func__,
rw->lock_object.lo_name, (void *)rw->rw_lock, file, line);
+#ifdef KDTRACE_HOOKS
+ all_time -= lockstat_nsecs();
+ state = rw->rw_lock;
+#endif
while (!_rw_write_lock(rw, tid)) {
#ifdef KDTRACE_HOOKS
spin_cnt++;
@@ -888,18 +907,21 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
spintries = 0;
#endif
}
- LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_RW_WLOCK_ACQUIRE, rw, contested,
- waittime, file, line);
#ifdef KDTRACE_HOOKS
+ all_time += lockstat_nsecs();
if (sleep_time)
- LOCKSTAT_RECORD1(LS_RW_WLOCK_BLOCK, rw, sleep_time);
+ LOCKSTAT_RECORD4(LS_RW_WLOCK_BLOCK, rw, sleep_time,
+ LOCKSTAT_WRITER, (state & RW_LOCK_READ) == 0,
+ (state & RW_LOCK_READ) == 0 ? 0 : RW_READERS(state));
- /*
- * Record only the loops spinning and not sleeping.
- */
+ /* Record only the loops spinning and not sleeping. */
if (spin_cnt > sleep_cnt)
- LOCKSTAT_RECORD1(LS_RW_WLOCK_SPIN, rw, (spin_cnt - sleep_cnt));
+ LOCKSTAT_RECORD4(LS_RW_WLOCK_SPIN, rw, all_time - sleep_time,
+ LOCKSTAT_READER, (state & RW_LOCK_READ) == 0,
+ (state & RW_LOCK_READ) == 0 ? 0 : RW_READERS(state));
#endif
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_RW_WLOCK_ACQUIRE, rw, contested,
+ waittime, file, line);
}
/*
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 5d48060..b70da5b 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -3309,7 +3309,7 @@ coredump(struct thread *td)
* a corefile is truncated instead of not being created,
* if it is larger than the limit.
*/
- limit = (off_t)lim_cur(p, RLIMIT_CORE);
+ limit = (off_t)lim_cur(td, RLIMIT_CORE);
if (limit == 0 || racct_get_available(p, RACCT_CORE) == 0) {
PROC_UNLOCK(p);
return (EFBIG);
diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c
index a986590..91e8c60 100644
--- a/sys/kern/kern_sx.c
+++ b/sys/kern/kern_sx.c
@@ -288,6 +288,8 @@ sx_try_slock_(struct sx *sx, const char *file, int line)
if (atomic_cmpset_acq_ptr(&sx->sx_lock, x, x + SX_ONE_SHARER)) {
LOCK_LOG_TRY("SLOCK", &sx->lock_object, 0, 1, file, line);
WITNESS_LOCK(&sx->lock_object, LOP_TRYLOCK, file, line);
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_SX_SLOCK_ACQUIRE,
+ sx, 0, 0, file, line);
curthread->td_locks++;
return (1);
}
@@ -348,6 +350,9 @@ sx_try_xlock_(struct sx *sx, const char *file, int line)
if (rval) {
WITNESS_LOCK(&sx->lock_object, LOP_EXCLUSIVE | LOP_TRYLOCK,
file, line);
+ if (!sx_recursed(sx))
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_SX_XLOCK_ACQUIRE,
+ sx, 0, 0, file, line);
curthread->td_locks++;
}
@@ -509,9 +514,11 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
#endif
int error = 0;
#ifdef KDTRACE_HOOKS
+ uintptr_t state;
uint64_t spin_cnt = 0;
uint64_t sleep_cnt = 0;
int64_t sleep_time = 0;
+ int64_t all_time = 0;
#endif
if (SCHEDULER_STOPPED())
@@ -533,6 +540,10 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
CTR5(KTR_LOCK, "%s: %s contested (lock=%p) at %s:%d", __func__,
sx->lock_object.lo_name, (void *)sx->sx_lock, file, line);
+#ifdef KDTRACE_HOOKS
+ all_time -= lockstat_nsecs();
+ state = sx->sx_lock;
+#endif
while (!atomic_cmpset_acq_ptr(&sx->sx_lock, SX_LOCK_UNLOCKED, tid)) {
#ifdef KDTRACE_HOOKS
spin_cnt++;
@@ -705,17 +716,21 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
CTR2(KTR_LOCK, "%s: %p resuming from sleep queue",
__func__, sx);
}
-
- GIANT_RESTORE();
- if (!error)
- LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_SX_XLOCK_ACQUIRE, sx,
- contested, waittime, file, line);
#ifdef KDTRACE_HOOKS
+ all_time += lockstat_nsecs();
if (sleep_time)
- LOCKSTAT_RECORD1(LS_SX_XLOCK_BLOCK, sx, sleep_time);
+ LOCKSTAT_RECORD4(LS_SX_XLOCK_BLOCK, sx, sleep_time,
+ LOCKSTAT_WRITER, (state & SX_LOCK_SHARED) == 0,
+ (state & SX_LOCK_SHARED) == 0 ? 0 : SX_SHARERS(state));
if (spin_cnt > sleep_cnt)
- LOCKSTAT_RECORD1(LS_SX_XLOCK_SPIN, sx, (spin_cnt - sleep_cnt));
+ LOCKSTAT_RECORD4(LS_SX_XLOCK_SPIN, sx, all_time - sleep_time,
+ LOCKSTAT_WRITER, (state & SX_LOCK_SHARED) == 0,
+ (state & SX_LOCK_SHARED) == 0 ? 0 : SX_SHARERS(state));
#endif
+ if (!error)
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_SX_XLOCK_ACQUIRE, sx,
+ contested, waittime, file, line);
+ GIANT_RESTORE();
return (error);
}
@@ -801,14 +816,21 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line)
uintptr_t x;
int error = 0;
#ifdef KDTRACE_HOOKS
+ uintptr_t state;
uint64_t spin_cnt = 0;
uint64_t sleep_cnt = 0;
int64_t sleep_time = 0;
+ int64_t all_time = 0;
#endif
if (SCHEDULER_STOPPED())
return (0);
+#ifdef KDTRACE_HOOKS
+ state = sx->sx_lock;
+ all_time -= lockstat_nsecs();
+#endif
+
/*
* As with rwlocks, we don't make any attempt to try to block
* shared locks once there is an exclusive waiter.
@@ -958,15 +980,20 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line)
CTR2(KTR_LOCK, "%s: %p resuming from sleep queue",
__func__, sx);
}
- if (error == 0)
- LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_SX_SLOCK_ACQUIRE, sx,
- contested, waittime, file, line);
#ifdef KDTRACE_HOOKS
+ all_time += lockstat_nsecs();
if (sleep_time)
- LOCKSTAT_RECORD1(LS_SX_XLOCK_BLOCK, sx, sleep_time);
+ LOCKSTAT_RECORD4(LS_SX_SLOCK_BLOCK, sx, sleep_time,
+ LOCKSTAT_READER, (state & SX_LOCK_SHARED) == 0,
+ (state & SX_LOCK_SHARED) == 0 ? 0 : SX_SHARERS(state));
if (spin_cnt > sleep_cnt)
- LOCKSTAT_RECORD1(LS_SX_XLOCK_SPIN, sx, (spin_cnt - sleep_cnt));
+ LOCKSTAT_RECORD4(LS_SX_SLOCK_SPIN, sx, all_time - sleep_time,
+ LOCKSTAT_READER, (state & SX_LOCK_SHARED) == 0,
+ (state & SX_LOCK_SHARED) == 0 ? 0 : SX_SHARERS(state));
#endif
+ if (error == 0)
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_SX_SLOCK_ACQUIRE, sx,
+ contested, waittime, file, line);
GIANT_RESTORE();
return (error);
}
diff --git a/sys/kern/kern_syscalls.c b/sys/kern/kern_syscalls.c
index dada746..15574be 100644
--- a/sys/kern/kern_syscalls.c
+++ b/sys/kern/kern_syscalls.c
@@ -31,6 +31,9 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/resourcevar.h>
#include <sys/sx.h>
#include <sys/syscall.h>
#include <sys/sysent.h>
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c
index 01c61bd..eba0b60 100644
--- a/sys/kern/kern_tc.c
+++ b/sys/kern/kern_tc.c
@@ -34,7 +34,6 @@ __FBSDID("$FreeBSD$");
#include <sys/timetc.h>
#include <sys/timex.h>
#include <sys/vdso.h>
-#include <machine/atomic.h>
/*
* A large step happens on boot. This constant detects such steps.
@@ -190,7 +189,7 @@ tc_delta(struct timehands *th)
tc->tc_counter_mask);
}
-static u_int
+static inline u_int
tc_getgen(struct timehands *th)
{
@@ -205,7 +204,7 @@ tc_getgen(struct timehands *th)
#endif
}
-static void
+static inline void
tc_setgen(struct timehands *th, u_int newgen)
{
diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c
index 6cd215e..e6b0a59 100644
--- a/sys/kern/kern_thr.c
+++ b/sys/kern/kern_thr.c
@@ -220,13 +220,13 @@ create_thread(struct thread *td, mcontext_t *ctx,
bcopy(&td->td_startcopy, &newtd->td_startcopy,
__rangeof(struct thread, td_startcopy, td_endcopy));
newtd->td_proc = td->td_proc;
- newtd->td_ucred = crhold(td->td_ucred);
+ thread_cow_get(newtd, td);
if (ctx != NULL) { /* old way to set user context */
error = set_mcontext(newtd, ctx);
if (error != 0) {
+ thread_cow_free(newtd);
thread_free(newtd);
- crfree(td->td_ucred);
goto fail;
}
} else {
@@ -238,8 +238,8 @@ create_thread(struct thread *td, mcontext_t *ctx,
/* Setup user TLS address and TLS pointer register. */
error = cpu_set_user_tls(newtd, tls_base);
if (error != 0) {
+ thread_cow_free(newtd);
thread_free(newtd);
- crfree(td->td_ucred);
goto fail;
}
}
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index dce760c..4343b64 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -327,8 +327,7 @@ thread_reap(void)
mtx_unlock_spin(&zombie_lock);
while (td_first) {
td_next = TAILQ_NEXT(td_first, td_slpq);
- if (td_first->td_ucred)
- crfree(td_first->td_ucred);
+ thread_cow_free(td_first);
thread_free(td_first);
td_first = td_next;
}
@@ -384,6 +383,50 @@ thread_free(struct thread *td)
uma_zfree(thread_zone, td);
}
+void
+thread_cow_get_proc(struct thread *newtd, struct proc *p)
+{
+
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ newtd->td_ucred = crhold(p->p_ucred);
+ newtd->td_limit = lim_hold(p->p_limit);
+ newtd->td_cowgen = p->p_cowgen;
+}
+
+void
+thread_cow_get(struct thread *newtd, struct thread *td)
+{
+
+ newtd->td_ucred = crhold(td->td_ucred);
+ newtd->td_limit = lim_hold(td->td_limit);
+ newtd->td_cowgen = td->td_cowgen;
+}
+
+void
+thread_cow_free(struct thread *td)
+{
+
+ if (td->td_ucred)
+ crfree(td->td_ucred);
+ if (td->td_limit)
+ lim_free(td->td_limit);
+}
+
+void
+thread_cow_update(struct thread *td)
+{
+ struct proc *p;
+
+ p = td->td_proc;
+ PROC_LOCK(p);
+ if (td->td_ucred != p->p_ucred)
+ cred_update_thread(td);
+ if (td->td_limit != p->p_limit)
+ lim_update_thread(td);
+ td->td_cowgen = p->p_cowgen;
+ PROC_UNLOCK(p);
+}
+
/*
* Discard the current thread and exit from its context.
* Always called with scheduler locked.
@@ -521,7 +564,7 @@ thread_wait(struct proc *p)
cpuset_rel(td->td_cpuset);
td->td_cpuset = NULL;
cpu_thread_clean(td);
- crfree(td->td_ucred);
+ thread_cow_free(td);
thread_reap(); /* check for zombie threads etc. */
}
diff --git a/sys/kern/stack_protector.c b/sys/kern/stack_protector.c
index b5f9973..77be64f 100644
--- a/sys/kern/stack_protector.c
+++ b/sys/kern/stack_protector.c
@@ -17,15 +17,14 @@ __stack_chk_fail(void)
panic("stack overflow detected; backtrace may be corrupted");
}
-#define __arraycount(__x) (sizeof(__x) / sizeof(__x[0]))
static void
__stack_chk_init(void *dummy __unused)
{
size_t i;
- long guard[__arraycount(__stack_chk_guard)];
+ long guard[nitems(__stack_chk_guard)];
arc4rand(guard, sizeof(guard), 0);
- for (i = 0; i < __arraycount(guard); i++)
+ for (i = 0; i < nitems(guard); i++)
__stack_chk_guard[i] = guard[i];
}
SYSINIT(stack_chk, SI_SUB_RANDOM, SI_ORDER_ANY, __stack_chk_init, NULL);
diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c
index 6509522..4f35838 100644
--- a/sys/kern/subr_prf.c
+++ b/sys/kern/subr_prf.c
@@ -37,10 +37,13 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#ifdef _KERNEL
#include "opt_ddb.h"
#include "opt_printf.h"
+#endif /* _KERNEL */
#include <sys/param.h>
+#ifdef _KERNEL
#include <sys/systm.h>
#include <sys/lock.h>
#include <sys/kdb.h>
@@ -57,7 +60,9 @@ __FBSDID("$FreeBSD$");
#include <sys/syslog.h>
#include <sys/cons.h>
#include <sys/uio.h>
+#endif
#include <sys/ctype.h>
+#include <sys/sbuf.h>
#ifdef DDB
#include <ddb/ddb.h>
@@ -69,6 +74,8 @@ __FBSDID("$FreeBSD$");
*/
#include <machine/stdarg.h>
+#ifdef _KERNEL
+
#define TOCONS 0x01
#define TOTTY 0x02
#define TOLOG 0x04
@@ -1119,3 +1126,59 @@ hexdump(const void *ptr, int length, const char *hdr, int flags)
printf("\n");
}
}
+#endif /* _KERNEL */
+
+void
+sbuf_hexdump(struct sbuf *sb, const void *ptr, int length, const char *hdr,
+ int flags)
+{
+ int i, j, k;
+ int cols;
+ const unsigned char *cp;
+ char delim;
+
+ if ((flags & HD_DELIM_MASK) != 0)
+ delim = (flags & HD_DELIM_MASK) >> 8;
+ else
+ delim = ' ';
+
+ if ((flags & HD_COLUMN_MASK) != 0)
+ cols = flags & HD_COLUMN_MASK;
+ else
+ cols = 16;
+
+ cp = ptr;
+ for (i = 0; i < length; i+= cols) {
+ if (hdr != NULL)
+ sbuf_printf(sb, "%s", hdr);
+
+ if ((flags & HD_OMIT_COUNT) == 0)
+ sbuf_printf(sb, "%04x ", i);
+
+ if ((flags & HD_OMIT_HEX) == 0) {
+ for (j = 0; j < cols; j++) {
+ k = i + j;
+ if (k < length)
+ sbuf_printf(sb, "%c%02x", delim, cp[k]);
+ else
+ sbuf_printf(sb, " ");
+ }
+ }
+
+ if ((flags & HD_OMIT_CHARS) == 0) {
+ sbuf_printf(sb, " |");
+ for (j = 0; j < cols; j++) {
+ k = i + j;
+ if (k >= length)
+ sbuf_printf(sb, " ");
+ else if (cp[k] >= ' ' && cp[k] <= '~')
+ sbuf_printf(sb, "%c", cp[k]);
+ else
+ sbuf_printf(sb, ".");
+ }
+ sbuf_printf(sb, "|");
+ }
+ sbuf_printf(sb, "\n");
+ }
+}
+
diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c
index 1bf78b8..070ba28 100644
--- a/sys/kern/subr_syscall.c
+++ b/sys/kern/subr_syscall.c
@@ -61,8 +61,8 @@ syscallenter(struct thread *td, struct syscall_args *sa)
p = td->td_proc;
td->td_pticks = 0;
- if (td->td_ucred != p->p_ucred)
- cred_update_thread(td);
+ if (td->td_cowgen != p->p_cowgen)
+ thread_cow_update(td);
if (p->p_flag & P_TRACED) {
traced = 1;
PROC_LOCK(p);
diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c
index 82387c2..375bb32 100644
--- a/sys/kern/subr_trap.c
+++ b/sys/kern/subr_trap.c
@@ -220,8 +220,8 @@ ast(struct trapframe *framep)
thread_unlock(td);
PCPU_INC(cnt.v_trap);
- if (td->td_ucred != p->p_ucred)
- cred_update_thread(td);
+ if (td->td_cowgen != p->p_cowgen)
+ thread_cow_update(td);
if (td->td_pflags & TDP_OWEUPC && p->p_flag & P_PROFIL) {
addupc_task(td, td->td_profil_addr, td->td_profil_ticks);
td->td_profil_ticks = 0;
diff --git a/sys/kern/subr_uio.c b/sys/kern/subr_uio.c
index 410085e..aac6eb6 100644
--- a/sys/kern/subr_uio.c
+++ b/sys/kern/subr_uio.c
@@ -409,10 +409,8 @@ copyout_map(struct thread *td, vm_offset_t *addr, size_t sz)
/*
* Map somewhere after heap in process memory.
*/
- PROC_LOCK(td->td_proc);
*addr = round_page((vm_offset_t)vms->vm_daddr +
- lim_max(td->td_proc, RLIMIT_DATA));
- PROC_UNLOCK(td->td_proc);
+ lim_max(td, RLIMIT_DATA));
/* round size up to page boundry */
size = (vm_size_t)round_page(sz);
diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c
index 3240a5f..3eb126b 100644
--- a/sys/kern/sysv_shm.c
+++ b/sys/kern/sysv_shm.c
@@ -382,7 +382,7 @@ kern_shmat_locked(struct thread *td, int shmid, const void *shmaddr,
*/
PROC_LOCK(p);
attach_va = round_page((vm_offset_t)p->p_vmspace->vm_daddr +
- lim_max(p, RLIMIT_DATA));
+ lim_max_proc(p, RLIMIT_DATA));
PROC_UNLOCK(p);
}
diff --git a/sys/kern/tty_pts.c b/sys/kern/tty_pts.c
index 2d1e8fe..fcc9c47 100644
--- a/sys/kern/tty_pts.c
+++ b/sys/kern/tty_pts.c
@@ -741,7 +741,7 @@ pts_alloc(int fflags, struct thread *td, struct file *fp)
PROC_UNLOCK(p);
return (EAGAIN);
}
- ok = chgptscnt(cred->cr_ruidinfo, 1, lim_cur(p, RLIMIT_NPTS));
+ ok = chgptscnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_NPTS));
if (!ok) {
racct_sub(p, RACCT_NPTS, 1);
PROC_UNLOCK(p);
@@ -795,7 +795,7 @@ pts_alloc_external(int fflags, struct thread *td, struct file *fp,
PROC_UNLOCK(p);
return (EAGAIN);
}
- ok = chgptscnt(cred->cr_ruidinfo, 1, lim_cur(p, RLIMIT_NPTS));
+ ok = chgptscnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_NPTS));
if (!ok) {
racct_sub(p, RACCT_NPTS, 1);
PROC_UNLOCK(p);
diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c
index 3419c51..fb84330 100644
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -189,14 +189,6 @@ uiomove_object_page(vm_object_t obj, size_t len, struct uio *uio)
if (m->valid != VM_PAGE_BITS_ALL) {
if (vm_pager_has_page(obj, idx, NULL, NULL)) {
rv = vm_pager_get_pages(obj, &m, 1, 0);
- m = vm_page_lookup(obj, idx);
- if (m == NULL) {
- printf(
- "uiomove_object: vm_obj %p idx %jd null lookup rv %d\n",
- obj, idx, rv);
- VM_OBJECT_WUNLOCK(obj);
- return (EIO);
- }
if (rv != VM_PAGER_OK) {
printf(
"uiomove_object: vm_obj %p idx %jd valid %x pager error %d\n",
@@ -423,7 +415,7 @@ static int
shm_dotruncate(struct shmfd *shmfd, off_t length)
{
vm_object_t object;
- vm_page_t m, ma[1];
+ vm_page_t m;
vm_pindex_t idx, nobjsize;
vm_ooffset_t delta;
int base, rv;
@@ -465,12 +457,10 @@ retry:
VM_WAIT;
VM_OBJECT_WLOCK(object);
goto retry;
- } else if (m->valid != VM_PAGE_BITS_ALL) {
- ma[0] = m;
- rv = vm_pager_get_pages(object, ma, 1,
+ } else if (m->valid != VM_PAGE_BITS_ALL)
+ rv = vm_pager_get_pages(object, &m, 1,
0);
- m = vm_page_lookup(object, idx);
- } else
+ else
/* A cached page was reactivated. */
rv = VM_PAGER_OK;
vm_page_lock(m);
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index 88952ed..243450d 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -420,9 +420,7 @@ sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so,
if (cc > sb_max_adj)
return (0);
if (td != NULL) {
- PROC_LOCK(td->td_proc);
- sbsize_limit = lim_cur(td->td_proc, RLIMIT_SBSIZE);
- PROC_UNLOCK(td->td_proc);
+ sbsize_limit = lim_cur(td, RLIMIT_SBSIZE);
} else
sbsize_limit = RLIM_INFINITY;
if (!chgsbsize(so->so_cred->cr_uidinfo, &sb->sb_hiwat, cc,
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 1efe3da..e3557ba 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -2026,10 +2026,7 @@ sendfile_readpage(vm_object_t obj, struct vnode *vp, int nd,
if (vm_pager_has_page(obj, pindex, NULL, NULL)) {
rv = vm_pager_get_pages(obj, &m, 1, 0);
SFSTAT_INC(sf_iocnt);
- m = vm_page_lookup(obj, pindex);
- if (m == NULL)
- error = EIO;
- else if (rv != VM_PAGER_OK) {
+ if (rv != VM_PAGER_OK) {
vm_page_lock(m);
vm_page_free(m);
vm_page_unlock(m);
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index ef0b83c..acf9fe9 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -1736,7 +1736,7 @@ unp_externalize(struct mbuf *control, struct mbuf **controlp, int flags)
int i;
int *fdp;
struct filedesc *fdesc = td->td_proc->p_fd;
- struct filedescent *fde, **fdep;
+ struct filedescent **fdep;
void *data;
socklen_t clen = control->m_len, datalen;
int error, newfds;
@@ -1787,7 +1787,7 @@ unp_externalize(struct mbuf *control, struct mbuf **controlp, int flags)
fdp = (int *)
CMSG_DATA(mtod(*controlp, struct cmsghdr *));
if (fdallocn(td, 0, fdp, newfds) != 0) {
- FILEDESC_XUNLOCK(td->td_proc->p_fd);
+ FILEDESC_XUNLOCK(fdesc);
error = EMSGSIZE;
unp_freerights(fdep, newfds);
m_freem(*controlp);
@@ -1795,13 +1795,10 @@ unp_externalize(struct mbuf *control, struct mbuf **controlp, int flags)
goto next;
}
for (i = 0; i < newfds; i++, fdp++) {
- fde = &fdesc->fd_ofiles[*fdp];
- fde->fde_file = fdep[i]->fde_file;
- filecaps_move(&fdep[i]->fde_caps,
- &fde->fde_caps);
- if ((flags & MSG_CMSG_CLOEXEC) != 0)
- fde->fde_flags |= UF_EXCLOSE;
- unp_externalize_fp(fde->fde_file);
+ _finstall(fdesc, fdep[i]->fde_file, *fdp,
+ (flags & MSG_CMSG_CLOEXEC) != 0 ? UF_EXCLOSE : 0,
+ &fdep[i]->fde_caps);
+ unp_externalize_fp(fdep[i]->fde_file);
}
FILEDESC_XUNLOCK(fdesc);
free(fdep[0], M_FILECAPS);
diff --git a/sys/kern/vfs_acl.c b/sys/kern/vfs_acl.c
index e9361e5..56cc6c9 100644
--- a/sys/kern/vfs_acl.c
+++ b/sys/kern/vfs_acl.c
@@ -406,7 +406,7 @@ sys___acl_get_fd(struct thread *td, struct __acl_get_fd_args *uap)
cap_rights_t rights;
int error;
- error = getvnode(td->td_proc->p_fd, uap->filedes,
+ error = getvnode(td, uap->filedes,
cap_rights_init(&rights, CAP_ACL_GET), &fp);
if (error == 0) {
error = vacl_get_acl(td, fp->f_vnode, uap->type, uap->aclp);
@@ -425,7 +425,7 @@ sys___acl_set_fd(struct thread *td, struct __acl_set_fd_args *uap)
cap_rights_t rights;
int error;
- error = getvnode(td->td_proc->p_fd, uap->filedes,
+ error = getvnode(td, uap->filedes,
cap_rights_init(&rights, CAP_ACL_SET), &fp);
if (error == 0) {
error = vacl_set_acl(td, fp->f_vnode, uap->type, uap->aclp);
@@ -480,7 +480,7 @@ sys___acl_delete_fd(struct thread *td, struct __acl_delete_fd_args *uap)
cap_rights_t rights;
int error;
- error = getvnode(td->td_proc->p_fd, uap->filedes,
+ error = getvnode(td, uap->filedes,
cap_rights_init(&rights, CAP_ACL_DELETE), &fp);
if (error == 0) {
error = vacl_delete(td, fp->f_vnode, uap->type);
@@ -535,7 +535,7 @@ sys___acl_aclcheck_fd(struct thread *td, struct __acl_aclcheck_fd_args *uap)
cap_rights_t rights;
int error;
- error = getvnode(td->td_proc->p_fd, uap->filedes,
+ error = getvnode(td, uap->filedes,
cap_rights_init(&rights, CAP_ACL_CHECK), &fp);
if (error == 0) {
error = vacl_aclcheck(td, fp->f_vnode, uap->type, uap->aclp);
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index 24935ce..0f82c2b 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -226,7 +226,7 @@ sys_extattr_set_fd(td, uap)
return (error);
AUDIT_ARG_TEXT(attrname);
- error = getvnode(td->td_proc->p_fd, uap->fd,
+ error = getvnode(td, uap->fd,
cap_rights_init(&rights, CAP_EXTATTR_SET), &fp);
if (error)
return (error);
@@ -401,7 +401,7 @@ sys_extattr_get_fd(td, uap)
return (error);
AUDIT_ARG_TEXT(attrname);
- error = getvnode(td->td_proc->p_fd, uap->fd,
+ error = getvnode(td, uap->fd,
cap_rights_init(&rights, CAP_EXTATTR_GET), &fp);
if (error)
return (error);
@@ -545,7 +545,7 @@ sys_extattr_delete_fd(td, uap)
return (error);
AUDIT_ARG_TEXT(attrname);
- error = getvnode(td->td_proc->p_fd, uap->fd,
+ error = getvnode(td, uap->fd,
cap_rights_init(&rights, CAP_EXTATTR_DELETE), &fp);
if (error)
return (error);
@@ -697,7 +697,7 @@ sys_extattr_list_fd(td, uap)
AUDIT_ARG_FD(uap->fd);
AUDIT_ARG_VALUE(uap->attrnamespace);
- error = getvnode(td->td_proc->p_fd, uap->fd,
+ error = getvnode(td, uap->fd,
cap_rights_init(&rights, CAP_EXTATTR_LIST), &fp);
if (error)
return (error);
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 625d193..ce194f9 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -173,6 +173,11 @@ static int reassignbufcalls;
SYSCTL_INT(_vfs, OID_AUTO, reassignbufcalls, CTLFLAG_RW, &reassignbufcalls, 0,
"Number of calls to reassignbuf");
+static u_long free_owe_inact;
+SYSCTL_ULONG(_vfs, OID_AUTO, free_owe_inact, CTLFLAG_RD, &free_owe_inact, 0,
+ "Number of times free vnodes kept on active list due to VFS "
+ "owing inactivation");
+
/*
* Cache for the mount type id assigned to NFS. This is used for
* special checks in nfs/nfs_nqlease.c and vm/vnode_pager.c.
@@ -2368,11 +2373,8 @@ vholdl(struct vnode *vp)
CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
#ifdef INVARIANTS
/* getnewvnode() calls v_incr_usecount() without holding interlock. */
- if (vp->v_type != VNON || vp->v_data != NULL) {
+ if (vp->v_type != VNON || vp->v_data != NULL)
ASSERT_VI_LOCKED(vp, "vholdl");
- VNASSERT(vp->v_holdcnt > 0 || (vp->v_iflag & VI_FREE) != 0,
- vp, ("vholdl: free vnode is held"));
- }
#endif
vp->v_holdcnt++;
if ((vp->v_iflag & VI_FREE) == 0)
@@ -2443,23 +2445,29 @@ vdropl(struct vnode *vp)
VNASSERT(vp->v_holdcnt == 0, vp,
("vdropl: freeing when we shouldn't"));
active = vp->v_iflag & VI_ACTIVE;
- vp->v_iflag &= ~VI_ACTIVE;
- mp = vp->v_mount;
- mtx_lock(&vnode_free_list_mtx);
- if (active) {
- TAILQ_REMOVE(&mp->mnt_activevnodelist, vp,
- v_actfreelist);
- mp->mnt_activevnodelistsize--;
- }
- if (vp->v_iflag & VI_AGE) {
- TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_actfreelist);
+ if ((vp->v_iflag & VI_OWEINACT) == 0) {
+ vp->v_iflag &= ~VI_ACTIVE;
+ mp = vp->v_mount;
+ mtx_lock(&vnode_free_list_mtx);
+ if (active) {
+ TAILQ_REMOVE(&mp->mnt_activevnodelist, vp,
+ v_actfreelist);
+ mp->mnt_activevnodelistsize--;
+ }
+ if (vp->v_iflag & VI_AGE) {
+ TAILQ_INSERT_HEAD(&vnode_free_list, vp,
+ v_actfreelist);
+ } else {
+ TAILQ_INSERT_TAIL(&vnode_free_list, vp,
+ v_actfreelist);
+ }
+ freevnodes++;
+ vp->v_iflag &= ~VI_AGE;
+ vp->v_iflag |= VI_FREE;
+ mtx_unlock(&vnode_free_list_mtx);
} else {
- TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_actfreelist);
+ atomic_add_long(&free_owe_inact, 1);
}
- freevnodes++;
- vp->v_iflag &= ~VI_AGE;
- vp->v_iflag |= VI_FREE;
- mtx_unlock(&vnode_free_list_mtx);
VI_UNLOCK(vp);
return;
}
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index d2f0df1..9088017 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -365,8 +365,7 @@ kern_fstatfs(struct thread *td, int fd, struct statfs *buf)
int error;
AUDIT_ARG_FD(fd);
- error = getvnode(td->td_proc->p_fd, fd,
- cap_rights_init(&rights, CAP_FSTATFS), &fp);
+ error = getvnode(td, fd, cap_rights_init(&rights, CAP_FSTATFS), &fp);
if (error != 0)
return (error);
vp = fp->f_vnode;
@@ -737,7 +736,7 @@ sys_fchdir(td, uap)
int error;
AUDIT_ARG_FD(uap->fd);
- error = getvnode(fdp, uap->fd, cap_rights_init(&rights, CAP_FCHDIR),
+ error = getvnode(td, uap->fd, cap_rights_init(&rights, CAP_FCHDIR),
&fp);
if (error != 0)
return (error);
@@ -2671,8 +2670,8 @@ sys_fchflags(td, uap)
AUDIT_ARG_FD(uap->fd);
AUDIT_ARG_FFLAGS(uap->flags);
- error = getvnode(td->td_proc->p_fd, uap->fd,
- cap_rights_init(&rights, CAP_FCHFLAGS), &fp);
+ error = getvnode(td, uap->fd, cap_rights_init(&rights, CAP_FCHFLAGS),
+ &fp);
if (error != 0)
return (error);
#ifdef AUDIT
@@ -3239,8 +3238,7 @@ kern_futimes(struct thread *td, int fd, struct timeval *tptr,
error = getutimes(tptr, tptrseg, ts);
if (error != 0)
return (error);
- error = getvnode(td->td_proc->p_fd, fd,
- cap_rights_init(&rights, CAP_FUTIMES), &fp);
+ error = getvnode(td, fd, cap_rights_init(&rights, CAP_FUTIMES), &fp);
if (error != 0)
return (error);
#ifdef AUDIT
@@ -3275,8 +3273,7 @@ kern_futimens(struct thread *td, int fd, struct timespec *tptr,
return (error);
if (flags & UTIMENS_EXIT)
return (0);
- error = getvnode(td->td_proc->p_fd, fd,
- cap_rights_init(&rights, CAP_FUTIMES), &fp);
+ error = getvnode(td, fd, cap_rights_init(&rights, CAP_FUTIMES), &fp);
if (error != 0)
return (error);
#ifdef AUDIT
@@ -3470,8 +3467,7 @@ sys_fsync(td, uap)
int error, lock_flags;
AUDIT_ARG_FD(uap->fd);
- error = getvnode(td->td_proc->p_fd, uap->fd,
- cap_rights_init(&rights, CAP_FSYNC), &fp);
+ error = getvnode(td, uap->fd, cap_rights_init(&rights, CAP_FSYNC), &fp);
if (error != 0)
return (error);
vp = fp->f_vnode;
@@ -3894,8 +3890,7 @@ kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap,
/* XXX arbitrary sanity limit on `count'. */
if (uap->count > 64 * 1024)
return (EINVAL);
- error = getvnode(td->td_proc->p_fd, uap->fd,
- cap_rights_init(&rights, CAP_READ), &fp);
+ error = getvnode(td, uap->fd, cap_rights_init(&rights, CAP_READ), &fp);
if (error != 0)
return (error);
if ((fp->f_flag & FREAD) == 0) {
@@ -4058,8 +4053,7 @@ kern_getdirentries(struct thread *td, int fd, char *buf, u_int count,
if (count > IOSIZE_MAX)
return (EINVAL);
auio.uio_resid = count;
- error = getvnode(td->td_proc->p_fd, fd,
- cap_rights_init(&rights, CAP_READ), &fp);
+ error = getvnode(td, fd, cap_rights_init(&rights, CAP_READ), &fp);
if (error != 0)
return (error);
if ((fp->f_flag & FREAD) == 0) {
@@ -4225,12 +4219,12 @@ out:
* entry is held upon returning.
*/
int
-getvnode(struct filedesc *fdp, int fd, cap_rights_t *rightsp, struct file **fpp)
+getvnode(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp)
{
struct file *fp;
int error;
- error = fget_unlocked(fdp, fd, rightsp, &fp, NULL);
+ error = fget_unlocked(td->td_proc->p_fd, fd, rightsp, &fp, NULL);
if (error != 0)
return (error);
@@ -4247,7 +4241,7 @@ getvnode(struct filedesc *fdp, int fd, cap_rights_t *rightsp, struct file **fpp)
* checking f_ops.
*/
if (fp->f_vnode == NULL || fp->f_ops == &badfileops) {
- fdrop(fp, curthread);
+ fdrop(fp, td);
return (EINVAL);
}
*fpp = fp;
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 573d009..0b073b9 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -2106,19 +2106,18 @@ vn_vget_ino_gen(struct vnode *vp, vn_get_ino_t alloc, void *alloc_arg,
int
vn_rlimit_fsize(const struct vnode *vp, const struct uio *uio,
- const struct thread *td)
+ struct thread *td)
{
if (vp->v_type != VREG || td == NULL)
return (0);
- PROC_LOCK(td->td_proc);
if ((uoff_t)uio->uio_offset + uio->uio_resid >
- lim_cur(td->td_proc, RLIMIT_FSIZE)) {
+ lim_cur(td, RLIMIT_FSIZE)) {
+ PROC_LOCK(td->td_proc);
kern_psignal(td->td_proc, SIGXFSZ);
PROC_UNLOCK(td->td_proc);
return (EFBIG);
}
- PROC_UNLOCK(td->td_proc);
return (0);
}
diff --git a/sys/mips/conf/AR934X_BASE b/sys/mips/conf/AR934X_BASE
index 7a62633..50af5f2 100644
--- a/sys/mips/conf/AR934X_BASE
+++ b/sys/mips/conf/AR934X_BASE
@@ -20,7 +20,7 @@ files "../atheros/files.ar71xx"
hints "AR934X_BASE.hints"
makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
-makeoptions MODULES_OVERRIDE="random gpio ar71xx if_gif if_gre if_bridge bridgestp usb wlan wlan_xauth wlan_acl wlan_wep wlan_tkip wlan_ccmp wlan_rssadapt wlan_amrr ath ath_ahb hwpmc"
+makeoptions MODULES_OVERRIDE="random gpio ar71xx if_gif if_gre if_vlan if_bridge bridgestp usb wlan wlan_xauth wlan_acl wlan_wep wlan_tkip wlan_ccmp wlan_rssadapt wlan_amrr ath ath_ahb hwpmc ipfw ipfw_nat libalias"
# makeoptions MODULES_OVERRIDE=""
options DDB
diff --git a/sys/modules/usb/Makefile b/sys/modules/usb/Makefile
index 84d5ef2..da3d776 100644
--- a/sys/modules/usb/Makefile
+++ b/sys/modules/usb/Makefile
@@ -53,7 +53,7 @@ SUBDIR += ${_dwc_otg} ehci ${_musb} ohci uhci xhci ${_uss820dci} ${_at91dci} \
${_atmegadci} ${_avr32dci} ${_rsu} ${_rsufw} ${_saf1761otg}
SUBDIR += ${_rum} ${_run} ${_runfw} ${_uath} upgt usie ural ${_zyd} ${_urtw}
SUBDIR += ${_urtwn} ${_urtwnfw}
-SUBDIR += atp uhid ukbd ums udbp ufm uep wsp uled
+SUBDIR += atp uhid ukbd ums udbp ufm uep wsp ugold uled
SUBDIR += ucom u3g uark ubsa ubser uchcom ucycom ufoma uftdi ugensa uipaq ulpt \
umct umcs umodem umoscom uplcom uslcom uvisor uvscom
SUBDIR += udl
diff --git a/sys/modules/usb/ugold/Makefile b/sys/modules/usb/ugold/Makefile
new file mode 100644
index 0000000..48af6ef
--- /dev/null
+++ b/sys/modules/usb/ugold/Makefile
@@ -0,0 +1,13 @@
+#
+# $FreeBSD$
+#
+
+S= ${.CURDIR}/../../..
+
+.PATH: $S/dev/usb/misc
+
+KMOD= ugold
+SRCS= opt_bus.h opt_usb.h device_if.h bus_if.h usb_if.h vnode_if.h \
+ usbdevs.h ugold.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index faa7681..c6bcfdf 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1033,9 +1033,12 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
case IFT_ETHER:
case IFT_L2VLAN:
/*
- * Take the interface out of promiscuous mode.
+ * Take the interface out of promiscuous mode, but only
+ * if it was promiscuous in the first place. It might
+ * not be if we're in the bridge_ioctl_add() error path.
*/
- (void) ifpromisc(ifs, 0);
+ if (ifs->if_flags & IFF_PROMISC)
+ (void) ifpromisc(ifs, 0);
break;
case IFT_GIF:
@@ -1203,10 +1206,8 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
break;
}
- if (error) {
+ if (error)
bridge_delete_member(sc, bif, 0);
- free(bif, M_DEVBUF);
- }
return (error);
}
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index fec6aa0..aa370d6 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -364,6 +364,7 @@ retry:
if ((la->la_flags & LLE_VALID) &&
((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime)) {
bcopy(&la->ll_addr, desten, ifp->if_addrlen);
+ renew = 0;
/*
* If entry has an expiry time and it is approaching,
* see if we need to send an ARP request within this
@@ -371,14 +372,22 @@ retry:
*/
if (!(la->la_flags & LLE_STATIC) &&
time_uptime + la->la_preempt > la->la_expire) {
- arprequest(ifp, NULL, &SIN(dst)->sin_addr, NULL);
+ renew = 1;
la->la_preempt--;
}
if (pflags != NULL)
*pflags = la->la_flags;
- error = 0;
- goto done;
+
+ if (flags & LLE_EXCLUSIVE)
+ LLE_WUNLOCK(la);
+ else
+ LLE_RUNLOCK(la);
+
+ if (renew == 1)
+ arprequest(ifp, NULL, &SIN(dst)->sin_addr, NULL);
+
+ return (0);
}
if (la->la_flags & LLE_STATIC) { /* should not happen! */
diff --git a/sys/netinet/ip_encap.c b/sys/netinet/ip_encap.c
index fcd048a..d3d0116 100644
--- a/sys/netinet/ip_encap.c
+++ b/sys/netinet/ip_encap.c
@@ -95,14 +95,14 @@ static MALLOC_DEFINE(M_NETADDR, "encap_export_host", "Export host address struct
static void encap_add(struct encaptab *);
static int mask_match(const struct encaptab *, const struct sockaddr *,
const struct sockaddr *);
-static void encap_fillarg(struct mbuf *, const struct encaptab *);
+static void encap_fillarg(struct mbuf *, void *);
/*
* All global variables in ip_encap.c are locked using encapmtx.
*/
static struct mtx encapmtx;
MTX_SYSINIT(encapmtx, &encapmtx, "encapmtx", MTX_DEF);
-LIST_HEAD(, encaptab) encaptab = LIST_HEAD_INITIALIZER(encaptab);
+static LIST_HEAD(, encaptab) encaptab = LIST_HEAD_INITIALIZER(encaptab);
/*
* We currently keey encap_init() for source code compatibility reasons --
@@ -122,12 +122,12 @@ encap4_input(struct mbuf **mp, int *offp, int proto)
struct sockaddr_in s, d;
const struct protosw *psw;
struct encaptab *ep, *match;
+ void *arg;
int matchprio, off, prio;
m = *mp;
off = *offp;
ip = mtod(m, struct ip *);
- *mp = NULL;
bzero(&s, sizeof(s));
s.sin_family = AF_INET;
@@ -138,6 +138,8 @@ encap4_input(struct mbuf **mp, int *offp, int proto)
d.sin_len = sizeof(struct sockaddr_in);
d.sin_addr = ip->ip_dst;
+ arg = NULL;
+ psw = NULL;
match = NULL;
matchprio = 0;
mtx_lock(&encapmtx);
@@ -182,14 +184,16 @@ encap4_input(struct mbuf **mp, int *offp, int proto)
match = ep;
}
}
+ if (match != NULL) {
+ psw = match->psw;
+ arg = match->arg;
+ }
mtx_unlock(&encapmtx);
- if (match) {
+ if (match != NULL) {
/* found a match, "match" has the best one */
- psw = match->psw;
- if (psw && psw->pr_input) {
- encap_fillarg(m, match);
- *mp = m;
+ if (psw != NULL && psw->pr_input != NULL) {
+ encap_fillarg(m, arg);
(*psw->pr_input)(mp, offp, proto);
} else
m_freem(m);
@@ -197,7 +201,6 @@ encap4_input(struct mbuf **mp, int *offp, int proto)
}
/* last resort: inject to raw socket */
- *mp = m;
return (rip_input(mp, offp, proto));
}
#endif
@@ -211,6 +214,7 @@ encap6_input(struct mbuf **mp, int *offp, int proto)
struct sockaddr_in6 s, d;
const struct protosw *psw;
struct encaptab *ep, *match;
+ void *arg;
int prio, matchprio;
ip6 = mtod(m, struct ip6_hdr *);
@@ -224,6 +228,8 @@ encap6_input(struct mbuf **mp, int *offp, int proto)
d.sin6_len = sizeof(struct sockaddr_in6);
d.sin6_addr = ip6->ip6_dst;
+ arg = NULL;
+ psw = NULL;
match = NULL;
matchprio = 0;
mtx_lock(&encapmtx);
@@ -251,17 +257,20 @@ encap6_input(struct mbuf **mp, int *offp, int proto)
match = ep;
}
}
+ if (match != NULL) {
+ psw = match->psw;
+ arg = match->arg;
+ }
mtx_unlock(&encapmtx);
- if (match) {
+ if (match != NULL) {
/* found a match */
- psw = match->psw;
- if (psw && psw->pr_input) {
- encap_fillarg(m, match);
+ if (psw != NULL && psw->pr_input != NULL) {
+ encap_fillarg(m, arg);
return (*psw->pr_input)(mp, offp, proto);
} else {
m_freem(m);
- return IPPROTO_DONE;
+ return (IPPROTO_DONE);
}
}
@@ -440,14 +449,16 @@ mask_match(const struct encaptab *ep, const struct sockaddr *sp,
}
static void
-encap_fillarg(struct mbuf *m, const struct encaptab *ep)
+encap_fillarg(struct mbuf *m, void *arg)
{
struct m_tag *tag;
- tag = m_tag_get(PACKET_TAG_ENCAP, sizeof (void*), M_NOWAIT);
- if (tag) {
- *(void**)(tag+1) = ep->arg;
- m_tag_prepend(m, tag);
+ if (arg != NULL) {
+ tag = m_tag_get(PACKET_TAG_ENCAP, sizeof(void *), M_NOWAIT);
+ if (tag != NULL) {
+ *(void**)(tag+1) = arg;
+ m_tag_prepend(m, tag);
+ }
}
}
diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c
index 21add43..a64e7f9 100644
--- a/sys/netinet/sctp_asconf.c
+++ b/sys/netinet/sctp_asconf.c
@@ -1109,7 +1109,8 @@ sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
* not be changed.
*/
SCTP_RTALLOC((sctp_route_t *) & net->ro,
- stcb->sctp_ep->def_vrf_id);
+ stcb->sctp_ep->def_vrf_id,
+ stcb->sctp_ep->fibnum);
if (net->ro.ro_rt == NULL)
continue;
@@ -1328,6 +1329,7 @@ sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
{
uint32_t status;
int pending_delete_queued = 0;
+ int last;
/* see if peer supports ASCONF */
if (stcb->asoc.asconf_supported == 0) {
@@ -1337,15 +1339,21 @@ sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
* if this is deleting the last address from the assoc, mark it as
* pending.
*/
- if ((type == SCTP_DEL_IP_ADDRESS) && !stcb->asoc.asconf_del_pending &&
- (sctp_local_addr_count(stcb) < 2)) {
- /* set the pending delete info only */
- stcb->asoc.asconf_del_pending = 1;
- stcb->asoc.asconf_addr_del_pending = ifa;
- atomic_add_int(&ifa->refcount, 1);
- SCTPDBG(SCTP_DEBUG_ASCONF2,
- "asconf_queue_add: mark delete last address pending\n");
- return (-1);
+ if ((type == SCTP_DEL_IP_ADDRESS) && !stcb->asoc.asconf_del_pending) {
+ if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
+ last = (sctp_local_addr_count(stcb) == 0);
+ } else {
+ last = (sctp_local_addr_count(stcb) == 1);
+ }
+ if (last) {
+ /* set the pending delete info only */
+ stcb->asoc.asconf_del_pending = 1;
+ stcb->asoc.asconf_addr_del_pending = ifa;
+ atomic_add_int(&ifa->refcount, 1);
+ SCTPDBG(SCTP_DEBUG_ASCONF2,
+ "asconf_queue_add: mark delete last address pending\n");
+ return (-1);
+ }
}
/* queue an asconf parameter */
status = sctp_asconf_queue_mgmt(stcb, ifa, type);
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 89047cb..c6bea83 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -186,7 +186,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
"No listener");
sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err,
- mflowtype, mflowid,
+ mflowtype, mflowid, inp->fibnum,
vrf_id, port);
}
goto outnow;
@@ -1484,7 +1484,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
sctp_send_shutdown_ack(stcb, stcb->asoc.primary_destination);
op_err = sctp_generate_cause(SCTP_CAUSE_COOKIE_IN_SHUTDOWN, "");
sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err,
- mflowtype, mflowid,
+ mflowtype, mflowid, inp->fibnum,
vrf_id, net->port);
if (how_indx < sizeof(asoc->cookie_how))
asoc->cookie_how[how_indx] = 2;
@@ -1694,7 +1694,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
*/
op_err = sctp_generate_cause(SCTP_CAUSE_NAT_COLLIDING_STATE, "");
sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err,
- mflowtype, mflowid,
+ mflowtype, mflowid, inp->fibnum,
vrf_id, port);
return (NULL);
}
@@ -2572,7 +2572,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
tim = now.tv_usec - cookie->time_entered.tv_usec;
scm->time_usec = htonl(tim);
sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err,
- mflowtype, mflowid,
+ mflowtype, mflowid, l_inp->fibnum,
vrf_id, port);
return (NULL);
}
@@ -2676,8 +2676,9 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
/* still no TCB... must be bad cookie-echo */
return (NULL);
}
- if ((*netp != NULL) && (mflowtype != M_HASHTYPE_NONE)) {
+ if (*netp != NULL) {
(*netp)->flowtype = mflowtype;
+ (*netp)->flowid = mflowid;
}
/*
* Ok, we built an association so confirm the address we sent the
@@ -2794,6 +2795,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
inp->partial_delivery_point = (*inp_p)->partial_delivery_point;
inp->sctp_context = (*inp_p)->sctp_context;
inp->local_strreset_support = (*inp_p)->local_strreset_support;
+ inp->fibnum = (*inp_p)->fibnum;
inp->inp_starting_point_for_iterator = NULL;
/*
* copy in the authentication parameters from the
@@ -4404,7 +4406,7 @@ __attribute__((noinline))
struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, struct sctp_chunkhdr *ch, struct sctp_inpcb *inp,
struct sctp_tcb *stcb, struct sctp_nets **netp, int *fwd_tsn_seen,
- uint8_t mflowtype, uint32_t mflowid,
+ uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum,
uint32_t vrf_id, uint16_t port)
{
struct sctp_association *asoc;
@@ -4568,7 +4570,7 @@ __attribute__((noinline))
msg);
/* no association, so it's out of the blue... */
sctp_handle_ootb(m, iphlen, *offset, src, dst, sh, inp, op_err,
- mflowtype, mflowid,
+ mflowtype, mflowid, inp->fibnum,
vrf_id, port);
*offset = length;
if (locked_tcb) {
@@ -4612,7 +4614,7 @@ __attribute__((noinline))
msg);
sctp_handle_ootb(m, iphlen, *offset, src, dst,
sh, inp, op_err,
- mflowtype, mflowid,
+ mflowtype, mflowid, fibnum,
vrf_id, port);
return (NULL);
}
@@ -5622,7 +5624,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
uint8_t compute_crc,
#endif
uint8_t ecn_bits,
- uint8_t mflowtype, uint32_t mflowid,
+ uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum,
uint32_t vrf_id, uint16_t port)
{
uint32_t high_tsn;
@@ -5661,8 +5663,9 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
net->port = port;
}
#endif
- if ((net != NULL) && (mflowtype != M_HASHTYPE_NONE)) {
+ if (net != NULL) {
net->flowtype = mflowtype;
+ net->flowid = mflowid;
}
if ((inp != NULL) && (stcb != NULL)) {
sctp_send_packet_dropped(stcb, net, m, length, iphlen, 1);
@@ -5691,8 +5694,9 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
net->port = port;
}
#endif
- if ((net != NULL) && (mflowtype != M_HASHTYPE_NONE)) {
+ if (net != NULL) {
net->flowtype = mflowtype;
+ net->flowid = mflowid;
}
if (inp == NULL) {
SCTP_STAT_INCR(sctps_noport);
@@ -5701,7 +5705,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
}
if (ch->chunk_type == SCTP_SHUTDOWN_ACK) {
sctp_send_shutdown_complete2(src, dst, sh,
- mflowtype, mflowid,
+ mflowtype, mflowid, fibnum,
vrf_id, port);
goto out;
}
@@ -5716,7 +5720,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
"Out of the blue");
sctp_send_abort(m, iphlen, src, dst,
sh, 0, op_err,
- mflowtype, mflowid,
+ mflowtype, mflowid, fibnum,
vrf_id, port);
}
}
@@ -5775,7 +5779,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
msg);
sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
- mflowtype, mflowid,
+ mflowtype, mflowid, inp->fibnum,
vrf_id, port);
goto out;
}
@@ -5786,7 +5790,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
stcb = sctp_process_control(m, iphlen, &offset, length,
src, dst, sh, ch,
inp, stcb, &net, &fwd_tsn_seen,
- mflowtype, mflowid,
+ mflowtype, mflowid, fibnum,
vrf_id, port);
if (stcb) {
/*
@@ -5827,7 +5831,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
msg);
sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
- mflowtype, mflowid,
+ mflowtype, mflowid, fibnum,
vrf_id, port);
goto out;
}
@@ -5899,7 +5903,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
msg);
sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
- mflowtype, mflowid,
+ mflowtype, mflowid, inp->fibnum,
vrf_id, port);
goto out;
/* sa_ignore NOTREACHED */
@@ -6023,6 +6027,7 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
#endif
uint32_t mflowid;
uint8_t mflowtype;
+ uint16_t fibnum;
iphlen = off;
if (SCTP_GET_PKT_VRFID(i_pak, vrf_id)) {
@@ -6048,6 +6053,7 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
(int)m->m_pkthdr.csum_flags, CSUM_BITS);
mflowid = m->m_pkthdr.flowid;
mflowtype = M_HASHTYPE_GET(m);
+ fibnum = M_GETFIB(m);
SCTP_STAT_INCR(sctps_recvpackets);
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
/* Get IP, SCTP, and first chunk header together in the first mbuf. */
@@ -6107,7 +6113,7 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
compute_crc,
#endif
ecn_bits,
- mflowtype, mflowid,
+ mflowtype, mflowid, fibnum,
vrf_id, port);
out:
if (m) {
diff --git a/sys/netinet/sctp_input.h b/sys/netinet/sctp_input.h
index 0c3f8a5..148864b 100644
--- a/sys/netinet/sctp_input.h
+++ b/sys/netinet/sctp_input.h
@@ -45,7 +45,7 @@ sctp_common_input_processing(struct mbuf **, int, int, int,
uint8_t,
#endif
uint8_t,
- uint8_t, uint32_t,
+ uint8_t, uint32_t, uint16_t,
uint32_t, uint16_t);
struct sctp_stream_reset_request *
diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h
index 140f341..bae67f0 100644
--- a/sys/netinet/sctp_os_bsd.h
+++ b/sys/netinet/sctp_os_bsd.h
@@ -413,13 +413,8 @@ typedef struct callout sctp_os_timer_t;
typedef struct route sctp_route_t;
typedef struct rtentry sctp_rtentry_t;
-/*
- * XXX multi-FIB support was backed out in r179783 and it seems clear that the
- * VRF support as currently in FreeBSD is not ready to support multi-FIB.
- * It might be best to implement multi-FIB support for both v4 and v6 indepedent
- * of VRFs and leave those to a real MPLS stack.
- */
-#define SCTP_RTALLOC(ro, vrf_id) rtalloc_ign((struct route *)ro, 0UL)
+#define SCTP_RTALLOC(ro, vrf_id, fibnum) \
+ rtalloc_ign_fib((struct route *)ro, 0UL, fibnum)
/* Future zero copy wakeup/send function */
#define SCTP_ZERO_COPY_EVENT(inp, so)
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 515ee13..3ef837c 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -3389,7 +3389,7 @@ sctp_source_address_selection(struct sctp_inpcb *inp,
/*
* Need a route to cache.
*/
- SCTP_RTALLOC(ro, vrf_id);
+ SCTP_RTALLOC(ro, vrf_id, inp->fibnum);
}
if (ro->ro_rt == NULL) {
return (NULL);
@@ -4170,7 +4170,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
sctp_free_ifa(_lsrc);
} else {
ip->ip_src = over_addr->sin.sin_addr;
- SCTP_RTALLOC(ro, vrf_id);
+ SCTP_RTALLOC(ro, vrf_id, inp->fibnum);
}
}
if (port) {
@@ -4484,7 +4484,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
sctp_free_ifa(_lsrc);
} else {
lsa6->sin6_addr = over_addr->sin6.sin6_addr;
- SCTP_RTALLOC(ro, vrf_id);
+ SCTP_RTALLOC(ro, vrf_id, inp->fibnum);
}
(void)sa6_recoverscope(sin6);
}
@@ -5511,7 +5511,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
"Address added");
sctp_send_abort(init_pkt, iphlen, src, dst, sh, 0, op_err,
- mflowtype, mflowid,
+ mflowtype, mflowid, inp->fibnum,
vrf_id, port);
return;
}
@@ -5530,7 +5530,7 @@ do_a_abort:
}
sctp_send_abort(init_pkt, iphlen, src, dst, sh,
init_chk->init.initiate_tag, op_err,
- mflowtype, mflowid,
+ mflowtype, mflowid, inp->fibnum,
vrf_id, port);
return;
}
@@ -7985,6 +7985,7 @@ again_one_more_time:
} else {
r_mtu = mtu;
}
+ error = 0;
/************************/
/* ASCONF transmission */
/************************/
@@ -8108,6 +8109,12 @@ again_one_more_time:
* it is used to do appropriate
* source address selection.
*/
+ if (*now_filled == 0) {
+ (void)SCTP_GETTIME_TIMEVAL(now);
+ *now_filled = 1;
+ }
+ net->last_sent_time = *now;
+ hbflag = 0;
if ((error = sctp_lowlevel_chunk_output(inp, stcb, net,
(struct sockaddr *)&net->ro._l_addr,
outchain, auth_offset, auth,
@@ -8118,21 +8125,18 @@ again_one_more_time:
net->port, NULL,
0, 0,
so_locked))) {
- if (error == ENOBUFS) {
- asoc->ifp_had_enobuf = 1;
- SCTP_STAT_INCR(sctps_lowlevelerr);
- }
+ /*
+ * error, we could not
+ * output
+ */
+ SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error);
if (from_where == 0) {
SCTP_STAT_INCR(sctps_lowlevelerrusr);
}
- if (*now_filled == 0) {
- (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
- *now_filled = 1;
- *now = net->last_sent_time;
- } else {
- net->last_sent_time = *now;
+ if (error == ENOBUFS) {
+ asoc->ifp_had_enobuf = 1;
+ SCTP_STAT_INCR(sctps_lowlevelerr);
}
- hbflag = 0;
/* error, could not output */
if (error == EHOSTUNREACH) {
/*
@@ -8143,17 +8147,10 @@ again_one_more_time:
sctp_move_chunks_from_net(stcb, net);
}
*reason_code = 7;
- continue;
- } else
- asoc->ifp_had_enobuf = 0;
- if (*now_filled == 0) {
- (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
- *now_filled = 1;
- *now = net->last_sent_time;
+ break;
} else {
- net->last_sent_time = *now;
+ asoc->ifp_had_enobuf = 0;
}
- hbflag = 0;
/*
* increase the number we sent, if a
* cookie is sent we don't tell them
@@ -8186,6 +8183,10 @@ again_one_more_time:
}
}
}
+ if (error != 0) {
+ /* try next net */
+ continue;
+ }
/************************/
/* Control transmission */
/************************/
@@ -8382,6 +8383,15 @@ again_one_more_time:
sctp_timer_start(SCTP_TIMER_TYPE_COOKIE, inp, stcb, net);
cookie = 0;
}
+ /* Only HB or ASCONF advances time */
+ if (hbflag) {
+ if (*now_filled == 0) {
+ (void)SCTP_GETTIME_TIMEVAL(now);
+ *now_filled = 1;
+ }
+ net->last_sent_time = *now;
+ hbflag = 0;
+ }
if ((error = sctp_lowlevel_chunk_output(inp, stcb, net,
(struct sockaddr *)&net->ro._l_addr,
outchain,
@@ -8393,23 +8403,17 @@ again_one_more_time:
net->port, NULL,
0, 0,
so_locked))) {
- if (error == ENOBUFS) {
- asoc->ifp_had_enobuf = 1;
- SCTP_STAT_INCR(sctps_lowlevelerr);
- }
+ /*
+ * error, we could not
+ * output
+ */
+ SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error);
if (from_where == 0) {
SCTP_STAT_INCR(sctps_lowlevelerrusr);
}
- /* error, could not output */
- if (hbflag) {
- if (*now_filled == 0) {
- (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
- *now_filled = 1;
- *now = net->last_sent_time;
- } else {
- net->last_sent_time = *now;
- }
- hbflag = 0;
+ if (error == ENOBUFS) {
+ asoc->ifp_had_enobuf = 1;
+ SCTP_STAT_INCR(sctps_lowlevelerr);
}
if (error == EHOSTUNREACH) {
/*
@@ -8420,19 +8424,9 @@ again_one_more_time:
sctp_move_chunks_from_net(stcb, net);
}
*reason_code = 7;
- continue;
- } else
+ break;
+ } else {
asoc->ifp_had_enobuf = 0;
- /* Only HB or ASCONF advances time */
- if (hbflag) {
- if (*now_filled == 0) {
- (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
- *now_filled = 1;
- *now = net->last_sent_time;
- } else {
- net->last_sent_time = *now;
- }
- hbflag = 0;
}
/*
* increase the number we sent, if a
@@ -8466,6 +8460,10 @@ again_one_more_time:
}
}
}
+ if (error != 0) {
+ /* try next net */
+ continue;
+ }
/* JRI: if dest is in PF state, do not send data to it */
if ((asoc->sctp_cmt_on_off > 0) &&
(net != stcb->asoc.alternate) &&
@@ -8720,6 +8718,14 @@ no_data_fill:
*/
sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
}
+ if (bundle_at || hbflag) {
+ /* For data/asconf and hb set time */
+ if (*now_filled == 0) {
+ (void)SCTP_GETTIME_TIMEVAL(now);
+ *now_filled = 1;
+ }
+ net->last_sent_time = *now;
+ }
/* Now send it, if there is anything to send :> */
if ((error = sctp_lowlevel_chunk_output(inp,
stcb,
@@ -8738,23 +8744,13 @@ no_data_fill:
0, 0,
so_locked))) {
/* error, we could not output */
- if (error == ENOBUFS) {
- SCTP_STAT_INCR(sctps_lowlevelerr);
- asoc->ifp_had_enobuf = 1;
- }
+ SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error);
if (from_where == 0) {
SCTP_STAT_INCR(sctps_lowlevelerrusr);
}
- SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error);
- if (hbflag) {
- if (*now_filled == 0) {
- (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
- *now_filled = 1;
- *now = net->last_sent_time;
- } else {
- net->last_sent_time = *now;
- }
- hbflag = 0;
+ if (error == ENOBUFS) {
+ SCTP_STAT_INCR(sctps_lowlevelerr);
+ asoc->ifp_had_enobuf = 1;
}
if (error == EHOSTUNREACH) {
/*
@@ -8779,16 +8775,6 @@ no_data_fill:
endoutchain = NULL;
auth = NULL;
auth_offset = 0;
- if (bundle_at || hbflag) {
- /* For data/asconf and hb set time */
- if (*now_filled == 0) {
- (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
- *now_filled = 1;
- *now = net->last_sent_time;
- } else {
- net->last_sent_time = *now;
- }
- }
if (!no_out_cnt) {
*num_out += (ctl_cnt + bundle_at);
}
@@ -10853,7 +10839,7 @@ static void
sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, uint32_t vtag,
uint8_t type, struct mbuf *cause,
- uint8_t mflowtype, uint32_t mflowid,
+ uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum,
uint32_t vrf_id, uint16_t port)
{
struct mbuf *o_pak;
@@ -10933,6 +10919,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
SCTP_BUF_RESV_UF(mout, max_linkhdr);
SCTP_BUF_LEN(mout) = len;
SCTP_BUF_NEXT(mout) = cause;
+ M_SETFIB(mout, fibnum);
mout->m_pkthdr.flowid = mflowid;
M_HASHTYPE_SET(mout, mflowtype);
#ifdef INET
@@ -11120,11 +11107,11 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
void
sctp_send_shutdown_complete2(struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh,
- uint8_t mflowtype, uint32_t mflowid,
+ uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum,
uint32_t vrf_id, uint16_t port)
{
sctp_send_resp_msg(src, dst, sh, 0, SCTP_SHUTDOWN_COMPLETE, NULL,
- mflowtype, mflowid,
+ mflowtype, mflowid, fibnum,
vrf_id, port);
}
@@ -11943,7 +11930,7 @@ skip_stuff:
void
sctp_send_abort(struct mbuf *m, int iphlen, struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, uint32_t vtag, struct mbuf *cause,
- uint8_t mflowtype, uint32_t mflowid,
+ uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum,
uint32_t vrf_id, uint16_t port)
{
/* Don't respond to an ABORT with an ABORT. */
@@ -11953,7 +11940,7 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sockaddr *src, struct sockadd
return;
}
sctp_send_resp_msg(src, dst, sh, vtag, SCTP_ABORT_ASSOCIATION, cause,
- mflowtype, mflowid,
+ mflowtype, mflowid, fibnum,
vrf_id, port);
return;
}
@@ -11961,11 +11948,11 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sockaddr *src, struct sockadd
void
sctp_send_operr_to(struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, uint32_t vtag, struct mbuf *cause,
- uint8_t mflowtype, uint32_t mflowid,
+ uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum,
uint32_t vrf_id, uint16_t port)
{
sctp_send_resp_msg(src, dst, sh, vtag, SCTP_OPERATION_ERROR, cause,
- mflowtype, mflowid,
+ mflowtype, mflowid, fibnum,
vrf_id, port);
return;
}
diff --git a/sys/netinet/sctp_output.h b/sys/netinet/sctp_output.h
index 8789df9..8e45e5c 100644
--- a/sys/netinet/sctp_output.h
+++ b/sys/netinet/sctp_output.h
@@ -117,7 +117,7 @@ void sctp_send_shutdown_complete(struct sctp_tcb *, struct sctp_nets *, int);
void
sctp_send_shutdown_complete2(struct sockaddr *, struct sockaddr *,
struct sctphdr *,
- uint8_t, uint32_t,
+ uint8_t, uint32_t, uint16_t,
uint32_t, uint16_t);
void sctp_send_asconf(struct sctp_tcb *, struct sctp_nets *, int addr_locked);
@@ -187,13 +187,13 @@ sctp_send_str_reset_req(struct sctp_tcb *, uint16_t, uint16_t *, uint8_t,
void
sctp_send_abort(struct mbuf *, int, struct sockaddr *, struct sockaddr *,
struct sctphdr *, uint32_t, struct mbuf *,
- uint8_t, uint32_t,
+ uint8_t, uint32_t, uint16_t,
uint32_t, uint16_t);
void
sctp_send_operr_to(struct sockaddr *, struct sockaddr *,
struct sctphdr *, uint32_t, struct mbuf *,
- uint8_t, uint32_t,
+ uint8_t, uint32_t, uint16_t,
uint32_t, uint16_t);
#endif /* _KERNEL || __Userspace__ */
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 6fcb6d2..541d4ca 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -2485,6 +2485,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
inp->reconfig_supported = (uint8_t) SCTP_BASE_SYSCTL(sctp_reconfig_enable);
inp->nrsack_supported = (uint8_t) SCTP_BASE_SYSCTL(sctp_nrsack_enable);
inp->pktdrop_supported = (uint8_t) SCTP_BASE_SYSCTL(sctp_pktdrop_enable);
+ inp->fibnum = so->so_fibnum;
/* init the small hash table we use to track asocid <-> tcb */
inp->sctp_asocidhash = SCTP_HASH_INIT(SCTP_STACK_VTAG_HASH_SIZE, &inp->hashasocidmark);
if (inp->sctp_asocidhash == NULL) {
@@ -3949,7 +3950,9 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
sin6->sin6_scope_id = 0;
}
#endif
- SCTP_RTALLOC((sctp_route_t *) & net->ro, stcb->asoc.vrf_id);
+ SCTP_RTALLOC((sctp_route_t *) & net->ro,
+ stcb->asoc.vrf_id,
+ stcb->sctp_ep->fibnum);
if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro)) {
/* Get source address */
diff --git a/sys/netinet/sctp_pcb.h b/sys/netinet/sctp_pcb.h
index 963b89f..f5ede2a 100644
--- a/sys/netinet/sctp_pcb.h
+++ b/sys/netinet/sctp_pcb.h
@@ -430,6 +430,7 @@ struct sctp_inpcb {
struct mtx inp_rdata_mtx;
int32_t refcount;
uint32_t def_vrf_id;
+ uint16_t fibnum;
uint32_t total_sends;
uint32_t total_recvs;
uint32_t last_abort_code;
diff --git a/sys/netinet/sctp_syscalls.c b/sys/netinet/sctp_syscalls.c
index 28b4445..71e2f72 100644
--- a/sys/netinet/sctp_syscalls.c
+++ b/sys/netinet/sctp_syscalls.c
@@ -277,6 +277,10 @@ sys_sctp_generic_sendmsg (td, uap)
auio.uio_td = td;
auio.uio_offset = 0; /* XXX */
auio.uio_resid = 0;
+#ifdef KTRACE
+ if (KTRPOINT(td, KTR_GENIO))
+ ktruio = cloneuio(&auio);
+#endif /* KTRACE */
len = auio.uio_resid = uap->mlen;
CURVNET_SET(so->so_vnet);
error = sctp_lower_sosend(so, to, &auio, (struct mbuf *)NULL,
@@ -400,6 +404,10 @@ sys_sctp_generic_sendmsg_iov(td, uap)
goto sctp_bad;
}
}
+#ifdef KTRACE
+ if (KTRPOINT(td, KTR_GENIO))
+ ktruio = cloneuio(&auio);
+#endif /* KTRACE */
len = auio.uio_resid;
CURVNET_SET(so->so_vnet);
error = sctp_lower_sosend(so, to, &auio,
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index 2a59e13..907412c 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -2464,9 +2464,9 @@ flags_out:
}
/* get flags for PMTU */
if (net->dest_state & SCTP_ADDR_NO_PMTUD) {
- paddrp->spp_flags |= SPP_PMTUD_ENABLE;
- } else {
paddrp->spp_flags |= SPP_PMTUD_DISABLE;
+ } else {
+ paddrp->spp_flags |= SPP_PMTUD_ENABLE;
}
if (net->dscp & 0x01) {
paddrp->spp_dscp = net->dscp & 0xfc;
@@ -5678,16 +5678,23 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
}
if ((stcb != NULL) && (net != NULL)) {
- if ((net != stcb->asoc.primary_destination) &&
- (!(net->dest_state & SCTP_ADDR_UNCONFIRMED))) {
- /* Ok we need to set it */
- if (sctp_set_primary_addr(stcb, (struct sockaddr *)NULL, net) == 0) {
- if ((stcb->asoc.alternate) &&
- (!(net->dest_state & SCTP_ADDR_PF)) &&
- (net->dest_state & SCTP_ADDR_REACHABLE)) {
- sctp_free_remote_addr(stcb->asoc.alternate);
- stcb->asoc.alternate = NULL;
+ if (net != stcb->asoc.primary_destination) {
+ if (!(net->dest_state & SCTP_ADDR_UNCONFIRMED)) {
+ /* Ok we need to set it */
+ if (sctp_set_primary_addr(stcb, (struct sockaddr *)NULL, net) == 0) {
+ if ((stcb->asoc.alternate) &&
+ (!(net->dest_state & SCTP_ADDR_PF)) &&
+ (net->dest_state & SCTP_ADDR_REACHABLE)) {
+ sctp_free_remote_addr(stcb->asoc.alternate);
+ stcb->asoc.alternate = NULL;
+ }
+ } else {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
}
+ } else {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
}
}
} else {
@@ -6712,7 +6719,20 @@ sctp_ctloutput(struct socket *so, struct sockopt *sopt)
size_t optsize = 0;
void *p;
int error = 0;
+ struct sctp_inpcb *inp;
+ if ((sopt->sopt_level == SOL_SOCKET) &&
+ (sopt->sopt_name == SO_SETFIB)) {
+ inp = (struct sctp_inpcb *)so->so_pcb;
+ if (inp == NULL) {
+ SCTP_LTRACE_ERR_RET(so->so_pcb, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOBUFS);
+ return (EINVAL);
+ }
+ SCTP_INP_WLOCK(inp);
+ inp->fibnum = so->so_fibnum;
+ SCTP_INP_WUNLOCK(inp);
+ return (0);
+ }
if (sopt->sopt_level != IPPROTO_SCTP) {
/* wrong proto level... send back up to IP */
#ifdef INET6
diff --git a/sys/netinet/sctp_var.h b/sys/netinet/sctp_var.h
index 31d93dd..ae1b3eb 100644
--- a/sys/netinet/sctp_var.h
+++ b/sys/netinet/sctp_var.h
@@ -178,6 +178,7 @@ extern struct pr_usrreqs sctp_usrreqs;
if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&(__net)->ref_count)) { \
(void)SCTP_OS_TIMER_STOP(&(__net)->rxt_timer.timer); \
(void)SCTP_OS_TIMER_STOP(&(__net)->pmtu_timer.timer); \
+ (void)SCTP_OS_TIMER_STOP(&(__net)->hb_timer.timer); \
if ((__net)->ro.ro_rt) { \
RTFREE((__net)->ro.ro_rt); \
(__net)->ro.ro_rt = NULL; \
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 24110dd..c25ec39 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -3895,7 +3895,7 @@ sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
stcb->asoc.state |= SCTP_STATE_WAS_ABORTED;
}
sctp_send_abort(m, iphlen, src, dst, sh, vtag, op_err,
- mflowtype, mflowid,
+ mflowtype, mflowid, inp->fibnum,
vrf_id, port);
if (stcb != NULL) {
/* Ok, now lets free it */
@@ -4051,7 +4051,7 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset,
struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, struct sctp_inpcb *inp,
struct mbuf *cause,
- uint8_t mflowtype, uint32_t mflowid,
+ uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum,
uint32_t vrf_id, uint16_t port)
{
struct sctp_chunkhdr *ch, chunk_buf;
@@ -4093,7 +4093,7 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset,
return;
case SCTP_SHUTDOWN_ACK:
sctp_send_shutdown_complete2(src, dst, sh,
- mflowtype, mflowid,
+ mflowtype, mflowid, fibnum,
vrf_id, port);
return;
default:
@@ -4107,7 +4107,7 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset,
((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
(contains_init_chunk == 0))) {
sctp_send_abort(m, iphlen, src, dst, sh, 0, cause,
- mflowtype, mflowid,
+ mflowtype, mflowid, fibnum,
vrf_id, port);
}
}
diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h
index 2ffbc2a..7df0a6c 100644
--- a/sys/netinet/sctputil.h
+++ b/sys/netinet/sctputil.h
@@ -208,7 +208,7 @@ sctp_handle_ootb(struct mbuf *, int, int,
struct sockaddr *, struct sockaddr *,
struct sctphdr *, struct sctp_inpcb *,
struct mbuf *,
- uint8_t, uint32_t,
+ uint8_t, uint32_t, uint16_t,
uint32_t, uint16_t);
int
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index a64e403..d992492 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -347,11 +347,12 @@ tcp_timer_2msl(void *xtp)
tp = tcp_close(tp);
} else {
if (tp->t_state != TCPS_TIME_WAIT &&
- ticks - tp->t_rcvtime <= TP_MAXIDLE(tp))
- callout_reset_on(&tp->t_timers->tt_2msl,
- TP_KEEPINTVL(tp), tcp_timer_2msl, tp,
- inp_to_cpuid(inp));
- else
+ ticks - tp->t_rcvtime <= TP_MAXIDLE(tp)) {
+ if (!callout_reset(&tp->t_timers->tt_2msl,
+ TP_KEEPINTVL(tp), tcp_timer_2msl, tp)) {
+ tp->t_timers->tt_flags &= ~TT_2MSL_RST;
+ }
+ } else
tp = tcp_close(tp);
}
@@ -431,11 +432,14 @@ tcp_timer_keep(void *xtp)
tp->rcv_nxt, tp->snd_una - 1, 0);
free(t_template, M_TEMP);
}
- callout_reset_on(&tp->t_timers->tt_keep, TP_KEEPINTVL(tp),
- tcp_timer_keep, tp, inp_to_cpuid(inp));
- } else
- callout_reset_on(&tp->t_timers->tt_keep, TP_KEEPIDLE(tp),
- tcp_timer_keep, tp, inp_to_cpuid(inp));
+ if (!callout_reset(&tp->t_timers->tt_keep, TP_KEEPINTVL(tp),
+ tcp_timer_keep, tp)) {
+ tp->t_timers->tt_flags &= ~TT_KEEP_RST;
+ }
+ } else if (!callout_reset(&tp->t_timers->tt_keep, TP_KEEPIDLE(tp),
+ tcp_timer_keep, tp)) {
+ tp->t_timers->tt_flags &= ~TT_KEEP_RST;
+ }
#ifdef TCPDEBUG
if (inp->inp_socket->so_options & SO_DEBUG)
@@ -810,6 +814,7 @@ tcp_timer_activate(struct tcpcb *tp, uint32_t timer_type, u_int delta)
timeout_t *f_callout;
struct inpcb *inp = tp->t_inpcb;
int cpu = inp_to_cpuid(inp);
+ uint32_t f_reset;
#ifdef TCP_OFFLOAD
if (tp->t_flags & TF_TOE)
@@ -823,38 +828,49 @@ tcp_timer_activate(struct tcpcb *tp, uint32_t timer_type, u_int delta)
case TT_DELACK:
t_callout = &tp->t_timers->tt_delack;
f_callout = tcp_timer_delack;
+ f_reset = TT_DELACK_RST;
break;
case TT_REXMT:
t_callout = &tp->t_timers->tt_rexmt;
f_callout = tcp_timer_rexmt;
+ f_reset = TT_REXMT_RST;
break;
case TT_PERSIST:
t_callout = &tp->t_timers->tt_persist;
f_callout = tcp_timer_persist;
+ f_reset = TT_PERSIST_RST;
break;
case TT_KEEP:
t_callout = &tp->t_timers->tt_keep;
f_callout = tcp_timer_keep;
+ f_reset = TT_KEEP_RST;
break;
case TT_2MSL:
t_callout = &tp->t_timers->tt_2msl;
f_callout = tcp_timer_2msl;
+ f_reset = TT_2MSL_RST;
break;
default:
panic("tp %p bad timer_type %#x", tp, timer_type);
}
if (delta == 0) {
if ((tp->t_timers->tt_flags & timer_type) &&
- callout_stop(t_callout)) {
- tp->t_timers->tt_flags &= ~timer_type;
+ callout_stop(t_callout) &&
+ (tp->t_timers->tt_flags & f_reset)) {
+ tp->t_timers->tt_flags &= ~(timer_type | f_reset);
}
} else {
if ((tp->t_timers->tt_flags & timer_type) == 0) {
- tp->t_timers->tt_flags |= timer_type;
+ tp->t_timers->tt_flags |= (timer_type | f_reset);
callout_reset_on(t_callout, delta, f_callout, tp, cpu);
} else {
/* Reset already running callout on the same CPU. */
- callout_reset(t_callout, delta, f_callout, tp);
+ if (!callout_reset(t_callout, delta, f_callout, tp)) {
+ /*
+ * Callout not cancelled, consider it as not
+ * properly restarted. */
+ tp->t_timers->tt_flags &= ~f_reset;
+ }
}
}
}
@@ -891,6 +907,7 @@ tcp_timer_stop(struct tcpcb *tp, uint32_t timer_type)
{
struct callout *t_callout;
timeout_t *f_callout;
+ uint32_t f_reset;
tp->t_timers->tt_flags |= TT_STOPPED;
@@ -898,30 +915,36 @@ tcp_timer_stop(struct tcpcb *tp, uint32_t timer_type)
case TT_DELACK:
t_callout = &tp->t_timers->tt_delack;
f_callout = tcp_timer_delack_discard;
+ f_reset = TT_DELACK_RST;
break;
case TT_REXMT:
t_callout = &tp->t_timers->tt_rexmt;
f_callout = tcp_timer_rexmt_discard;
+ f_reset = TT_REXMT_RST;
break;
case TT_PERSIST:
t_callout = &tp->t_timers->tt_persist;
f_callout = tcp_timer_persist_discard;
+ f_reset = TT_PERSIST_RST;
break;
case TT_KEEP:
t_callout = &tp->t_timers->tt_keep;
f_callout = tcp_timer_keep_discard;
+ f_reset = TT_KEEP_RST;
break;
case TT_2MSL:
t_callout = &tp->t_timers->tt_2msl;
f_callout = tcp_timer_2msl_discard;
+ f_reset = TT_2MSL_RST;
break;
default:
panic("tp %p bad timer_type %#x", tp, timer_type);
}
if (tp->t_timers->tt_flags & timer_type) {
- if (callout_stop(t_callout)) {
- tp->t_timers->tt_flags &= ~timer_type;
+ if (callout_stop(t_callout) &&
+ (tp->t_timers->tt_flags & f_reset)) {
+ tp->t_timers->tt_flags &= ~(timer_type | f_reset);
} else {
/*
* Can't stop the callout, defer tcpcb actual deletion
diff --git a/sys/netinet/tcp_timer.h b/sys/netinet/tcp_timer.h
index 02a7782..dbb8aee 100644
--- a/sys/netinet/tcp_timer.h
+++ b/sys/netinet/tcp_timer.h
@@ -160,6 +160,12 @@ struct tcp_timer {
#define TT_2MSL 0x0010
#define TT_MASK (TT_DELACK|TT_REXMT|TT_PERSIST|TT_KEEP|TT_2MSL)
+#define TT_DELACK_RST 0x0100
+#define TT_REXMT_RST 0x0200
+#define TT_PERSIST_RST 0x0400
+#define TT_KEEP_RST 0x0800
+#define TT_2MSL_RST 0x1000
+
#define TT_STOPPED 0x00010000
#define TP_KEEPINIT(tp) ((tp)->t_keepinit ? (tp)->t_keepinit : tcp_keepinit)
diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c
index 54c65b6..009c47f 100644
--- a/sys/netinet6/sctp6_usrreq.c
+++ b/sys/netinet6/sctp6_usrreq.c
@@ -84,6 +84,7 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port)
#endif
uint32_t mflowid;
uint8_t mflowtype;
+ uint16_t fibnum;
iphlen = *offp;
if (SCTP_GET_PKT_VRFID(*i_pak, vrf_id)) {
@@ -109,6 +110,7 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port)
(int)m->m_pkthdr.csum_flags, CSUM_BITS);
mflowid = m->m_pkthdr.flowid;
mflowtype = M_HASHTYPE_GET(m);
+ fibnum = M_GETFIB(m);
SCTP_STAT_INCR(sctps_recvpackets);
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
/* Get IP, SCTP, and first chunk header together in the first mbuf. */
@@ -169,7 +171,7 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port)
compute_crc,
#endif
ecn_bits,
- mflowtype, mflowid,
+ mflowtype, mflowid, fibnum,
vrf_id, port);
out:
if (m) {
diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c
index 1e70fb2..b6c6a6a 100644
--- a/sys/netipsec/key.c
+++ b/sys/netipsec/key.c
@@ -7714,14 +7714,6 @@ key_sa_chgstate(struct secasvar *sav, u_int8_t state)
}
}
-void
-key_sa_stir_iv(struct secasvar *sav)
-{
-
- IPSEC_ASSERT(sav->iv != NULL, ("null IV"));
- key_randomfill(sav->iv, sav->ivlen);
-}
-
/*
* Take one of the kernel's security keys and convert it into a PF_KEY
* structure within an mbuf, suitable for sending up to a waiting
diff --git a/sys/netipsec/key.h b/sys/netipsec/key.h
index 29abb80..82811be 100644
--- a/sys/netipsec/key.h
+++ b/sys/netipsec/key.h
@@ -105,7 +105,6 @@ extern void key_init(void);
extern void key_destroy(void);
#endif
extern void key_sa_recordxfer(struct secasvar *, struct mbuf *);
-extern void key_sa_stir_iv(struct secasvar *);
#ifdef IPSEC_NAT_T
u_int16_t key_portfromsaddr(struct sockaddr *);
#define KEY_PORTFROMSADDR(saddr) \
diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c
index 3f210c2..384f565 100644
--- a/sys/netpfil/pf/pf_norm.c
+++ b/sys/netpfil/pf/pf_norm.c
@@ -76,7 +76,6 @@ struct pf_fragment_cmp {
uint32_t frc_id;
sa_family_t frc_af;
uint8_t frc_proto;
- uint8_t frc_direction;
};
struct pf_fragment {
@@ -86,7 +85,6 @@ struct pf_fragment {
#define fr_id fr_key.frc_id
#define fr_af fr_key.frc_af
#define fr_proto fr_key.frc_proto
-#define fr_direction fr_key.frc_direction
RB_ENTRY(pf_fragment) fr_entry;
TAILQ_ENTRY(pf_fragment) frag_next;
@@ -157,7 +155,7 @@ static struct mbuf *pf_fragcache(struct mbuf **, struct ip*,
#endif /* INET */
#ifdef INET6
static int pf_reassemble6(struct mbuf **, struct ip6_hdr *,
- struct ip6_frag *, uint16_t, uint16_t, int, u_short *);
+ struct ip6_frag *, uint16_t, uint16_t, u_short *);
static void pf_scrub_ip6(struct mbuf **, uint8_t);
#endif /* INET6 */
@@ -178,7 +176,6 @@ pf_ip2key(struct ip *ip, int dir, struct pf_fragment_cmp *key)
key->frc_af = AF_INET;
key->frc_proto = ip->ip_p;
key->frc_id = ip->ip_id;
- key->frc_direction = dir;
}
#endif /* INET */
@@ -663,7 +660,7 @@ pf_reassemble(struct mbuf **m0, struct ip *ip, int dir, u_short *reason)
#ifdef INET6
static int
pf_reassemble6(struct mbuf **m0, struct ip6_hdr *ip6, struct ip6_frag *fraghdr,
- uint16_t hdrlen, uint16_t extoff, int dir, u_short *reason)
+ uint16_t hdrlen, uint16_t extoff, u_short *reason)
{
struct mbuf *m = *m0;
struct pf_frent *frent;
@@ -697,7 +694,6 @@ pf_reassemble6(struct mbuf **m0, struct ip6_hdr *ip6, struct ip6_frag *fraghdr,
/* Only the first fragment's protocol is relevant. */
key.frc_proto = 0;
key.frc_id = fraghdr->ip6f_ident;
- key.frc_direction = dir;
if ((frag = pf_fillup_fragment(&key, frent, reason)) == NULL) {
PF_FRAG_UNLOCK();
@@ -823,6 +819,8 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
(*frag)->fr_max = 0;
(*frag)->fr_src.v4 = h->ip_src;
(*frag)->fr_dst.v4 = h->ip_dst;
+ (*frag)->fr_af = AF_INET;
+ (*frag)->fr_proto = h->ip_p;
(*frag)->fr_id = h->ip_id;
(*frag)->fr_timeout = time_uptime;
@@ -1553,7 +1551,7 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
off += sizeof(frag);
/* Returns PF_DROP or *m0 is NULL or completely reassembled mbuf. */
- if (pf_reassemble6(m0, h, &frag, off, extoff, dir, reason) != PF_PASS)
+ if (pf_reassemble6(m0, h, &frag, off, extoff, reason) != PF_PASS)
return (PF_DROP);
m = *m0;
if (m == NULL)
diff --git a/sys/ofed/drivers/infiniband/core/umem.c b/sys/ofed/drivers/infiniband/core/umem.c
index cdd2e67..5f4465f 100644
--- a/sys/ofed/drivers/infiniband/core/umem.c
+++ b/sys/ofed/drivers/infiniband/core/umem.c
@@ -272,7 +272,7 @@ struct ib_umem *ib_umem_get_ex(struct ib_ucontext *context, unsigned long addr,
PROC_LOCK(proc);
if (ptoa(npages +
pmap_wired_count(vm_map_pmap(&proc->p_vmspace->vm_map))) >
- lim_cur(proc, RLIMIT_MEMLOCK)) {
+ lim_cur_proc(proc, RLIMIT_MEMLOCK)) {
PROC_UNLOCK(proc);
kfree(umem);
return ERR_PTR(-ENOMEM);
diff --git a/sys/ofed/drivers/infiniband/hw/mthca/mthca_memfree.c b/sys/ofed/drivers/infiniband/hw/mthca/mthca_memfree.c
index 0cdebaf..ad5818e 100644
--- a/sys/ofed/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/sys/ofed/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -553,7 +553,8 @@ out:
proc = curproc;
pmap = vm_map_pmap(&proc->p_vmspace->vm_map);
PROC_LOCK(proc);
- if (ptoa(pmap_wired_count(pmap) + 1) > lim_cur(proc, RLIMIT_MEMLOCK)) {
+ if (ptoa(pmap_wired_count(pmap) + 1) >
+ lim_cur_proc(proc, RLIMIT_MEMLOCK)) {
PROC_UNLOCK(proc);
ret = -ENOMEM;
goto out;
diff --git a/sys/ofed/include/linux/file.h b/sys/ofed/include/linux/file.h
index f1a7398..e2cebab 100644
--- a/sys/ofed/include/linux/file.h
+++ b/sys/ofed/include/linux/file.h
@@ -33,6 +33,7 @@
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/refcount.h>
+#include <sys/capsicum.h>
#include <sys/proc.h>
#include <linux/fs.h>
@@ -46,10 +47,11 @@ extern struct fileops linuxfileops;
static inline struct linux_file *
linux_fget(unsigned int fd)
{
+ cap_rights_t rights;
struct file *file;
- if (fget_unlocked(curthread->td_proc->p_fd, fd, NULL, &file,
- NULL) != 0) {
+ if (fget_unlocked(curthread->td_proc->p_fd, fd,
+ cap_rights_init(&rights), &file, NULL) != 0) {
return (NULL);
}
return (struct linux_file *)file->f_data;
@@ -71,10 +73,11 @@ fput(struct linux_file *filp)
static inline void
put_unused_fd(unsigned int fd)
{
+ cap_rights_t rights;
struct file *file;
- if (fget_unlocked(curthread->td_proc->p_fd, fd, NULL, &file,
- NULL) != 0) {
+ if (fget_unlocked(curthread->td_proc->p_fd, fd,
+ cap_rights_init(&rights), &file, NULL) != 0) {
return;
}
/*
@@ -91,10 +94,11 @@ put_unused_fd(unsigned int fd)
static inline void
fd_install(unsigned int fd, struct linux_file *filp)
{
+ cap_rights_t rights;
struct file *file;
- if (fget_unlocked(curthread->td_proc->p_fd, fd, NULL, &file,
- NULL) != 0) {
+ if (fget_unlocked(curthread->td_proc->p_fd, fd,
+ cap_rights_init(&rights), &file, NULL) != 0) {
file = NULL;
}
filp->_file = file;
diff --git a/sys/opencrypto/crypto.c b/sys/opencrypto/crypto.c
index 0ecdeb3..d084b77 100644
--- a/sys/opencrypto/crypto.c
+++ b/sys/opencrypto/crypto.c
@@ -1181,8 +1181,8 @@ crypto_kdone(struct cryptkop *krp)
/* XXX: What if driver is loaded in the meantime? */
if (krp->krp_hid < crypto_drivers_num) {
cap = &crypto_drivers[krp->krp_hid];
+ KASSERT(cap->cc_koperations > 0, ("cc_koperations == 0"));
cap->cc_koperations--;
- KASSERT(cap->cc_koperations >= 0, ("cc_koperations < 0"));
if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
crypto_remove(cap);
}
diff --git a/sys/powerpc/conf/NOTES b/sys/powerpc/conf/NOTES
index 974c91b..9bfe6a9 100644
--- a/sys/powerpc/conf/NOTES
+++ b/sys/powerpc/conf/NOTES
@@ -3,6 +3,28 @@
# This file contains machine dependent kernel configuration notes. For
# machine independent notes, look in /sys/conf/NOTES.
+#
+# Enable the kernel DTrace hooks which are required to load the DTrace
+# kernel modules.
+#
+options KDTRACE_HOOKS
+
+# DTrace core
+# NOTE: introduces CDDL-licensed components into the kernel
+#device dtrace
+
+# DTrace modules
+#device dtrace_lockstat
+#device dtrace_profile
+#device dtrace_sdt
+#device dtrace_fbt
+#device dtrace_systrace
+#device dtrace_prototype
+#device dtnfscl
+#device dtmalloc
+
+# Alternatively include all the DTrace modules
+#device dtraceall
#####################################################################
diff --git a/sys/powerpc/powerpc/trap.c b/sys/powerpc/powerpc/trap.c
index 0ceb170..bfbd94d 100644
--- a/sys/powerpc/powerpc/trap.c
+++ b/sys/powerpc/powerpc/trap.c
@@ -196,8 +196,8 @@ trap(struct trapframe *frame)
if (user) {
td->td_pticks = 0;
td->td_frame = frame;
- if (td->td_ucred != p->p_ucred)
- cred_update_thread(td);
+ if (td->td_cowgen != p->p_cowgen)
+ thread_cow_update(td);
/* User Mode Traps */
switch (type) {
diff --git a/sys/security/audit/audit_arg.c b/sys/security/audit/audit_arg.c
index 2e86842..c006b90 100644
--- a/sys/security/audit/audit_arg.c
+++ b/sys/security/audit/audit_arg.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/filedesc.h>
+#include <sys/capsicum.h>
#include <sys/ipc.h>
#include <sys/mount.h>
#include <sys/proc.h>
@@ -894,6 +895,7 @@ audit_arg_fcntl_rights(uint32_t fcntlrights)
void
audit_sysclose(struct thread *td, int fd)
{
+ cap_rights_t rights;
struct kaudit_record *ar;
struct vnode *vp;
struct file *fp;
@@ -906,7 +908,7 @@ audit_sysclose(struct thread *td, int fd)
audit_arg_fd(fd);
- if (getvnode(td->td_proc->p_fd, fd, 0, &fp) != 0)
+ if (getvnode(td, fd, cap_rights_init(&rights), &fp) != 0)
return;
vp = fp->f_vnode;
diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c
index b4f0e27..e9917e5 100644
--- a/sys/sparc64/sparc64/trap.c
+++ b/sys/sparc64/sparc64/trap.c
@@ -277,8 +277,8 @@ trap(struct trapframe *tf)
td->td_pticks = 0;
td->td_frame = tf;
addr = tf->tf_tpc;
- if (td->td_ucred != p->p_ucred)
- cred_update_thread(td);
+ if (td->td_cowgen != p->p_cowgen)
+ thread_cow_update(td);
switch (tf->tf_type) {
case T_DATA_MISS:
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
index eca30ff..fe95111 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -83,8 +83,8 @@ struct filedesc {
int fd_lastfile; /* high-water mark of fd_ofiles */
int fd_freefile; /* approx. next free file */
u_short fd_cmask; /* mask for file creation */
- u_short fd_refcnt; /* thread reference count */
- u_short fd_holdcnt; /* hold count on structure + mutex */
+ int fd_refcnt; /* thread reference count */
+ int fd_holdcnt; /* hold count on structure + mutex */
struct sx fd_sx; /* protects members of this struct */
struct kqlist fd_kqlist; /* list of kqueues on this filedesc */
int fd_holdleaderscount; /* block fdfree() for shared close() */
@@ -147,7 +147,9 @@ int dupfdopen(struct thread *td, struct filedesc *fdp, int dfd, int mode,
int falloc(struct thread *td, struct file **resultfp, int *resultfd,
int flags);
int falloc_noinstall(struct thread *td, struct file **resultfp);
-int finstall(struct thread *td, struct file *fp, int *resultfp, int flags,
+void _finstall(struct filedesc *fdp, struct file *fp, int fd, int flags,
+ struct filecaps *fcaps);
+int finstall(struct thread *td, struct file *fp, int *resultfd, int flags,
struct filecaps *fcaps);
int fdalloc(struct thread *td, int minfd, int *result);
int fdallocn(struct thread *td, int minfd, int *fds, int n);
@@ -163,7 +165,7 @@ struct filedesc *fdshare(struct filedesc *fdp);
struct filedesc_to_leader *
filedesc_to_leader_alloc(struct filedesc_to_leader *old,
struct filedesc *fdp, struct proc *leader);
-int getvnode(struct filedesc *fdp, int fd, cap_rights_t *rightsp,
+int getvnode(struct thread *td, int fd, cap_rights_t *rightsp,
struct file **fpp);
void mountcheckdirs(struct vnode *olddp, struct vnode *newdp);
diff --git a/sys/sys/lockstat.h b/sys/sys/lockstat.h
index ed9cffa..2a7853f 100644
--- a/sys/sys/lockstat.h
+++ b/sys/sys/lockstat.h
@@ -198,6 +198,9 @@ extern uint64_t lockstat_nsecs(void);
(*lockstat_probe_func)(id, (uintptr_t)(lp), 0, 0, 0, 0); \
} while (0)
+#define LOCKSTAT_WRITER 0
+#define LOCKSTAT_READER 1
+
#else /* !KDTRACE_HOOKS */
#define LOCKSTAT_RECORD(probe, lp, arg1)
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 098d8f8..a146da8 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1100076 /* Master, propagated to newvers */
+#define __FreeBSD_version 1100077 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h
index f4d46b2..e0e7fcb 100644
--- a/sys/sys/pmc.h
+++ b/sys/sys/pmc.h
@@ -105,7 +105,12 @@
__PMC_CPU(PPC_MPC85XX, 0x340, "Freescale PowerPC MPC85XX") \
__PMC_CPU(PPC_970, 0x380, "IBM PowerPC 970") \
__PMC_CPU(GENERIC, 0x400, "Generic") \
- __PMC_CPU(ARMV7, 0x500, "ARMv7") \
+ __PMC_CPU(ARMV7_CORTEX_A5, 0x500, "ARMv7 Cortex A5") \
+ __PMC_CPU(ARMV7_CORTEX_A7, 0x501, "ARMv7 Cortex A7") \
+ __PMC_CPU(ARMV7_CORTEX_A8, 0x502, "ARMv7 Cortex A8") \
+ __PMC_CPU(ARMV7_CORTEX_A9, 0x503, "ARMv7 Cortex A9") \
+ __PMC_CPU(ARMV7_CORTEX_A15, 0x504, "ARMv7 Cortex A15") \
+ __PMC_CPU(ARMV7_CORTEX_A17, 0x505, "ARMv7 Cortex A17") \
__PMC_CPU(ARMV8_CORTEX_A53, 0x600, "ARMv8 Cortex A53") \
__PMC_CPU(ARMV8_CORTEX_A57, 0x601, "ARMv8 Cortex A57")
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 018b595..e6c83b4 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -246,6 +246,7 @@ struct thread {
int td_intr_nesting_level; /* (k) Interrupt recursion. */
int td_pinned; /* (k) Temporary cpu pin count. */
struct ucred *td_ucred; /* (k) Reference to credentials. */
+ struct plimit *td_limit; /* (k) Resource limits. */
u_int td_estcpu; /* (t) estimated cpu utilization */
int td_slptick; /* (t) Time at sleep. */
int td_blktick; /* (t) Time spent blocked. */
@@ -308,6 +309,7 @@ struct thread {
off_t tdu_off;
} td_uretoff; /* (k) Syscall aux returns. */
#define td_retval td_uretoff.tdu_retval
+ u_int td_cowgen; /* (k) Generation of COW pointers. */
struct callout td_slpcallout; /* (h) Callout for sleep. */
struct trapframe *td_frame; /* (k) */
struct vm_object *td_kstack_obj;/* (a) Kstack object. */
@@ -498,7 +500,7 @@ struct proc {
struct filedesc *p_fd; /* (b) Open files. */
struct filedesc_to_leader *p_fdtol; /* (b) Tracking node */
struct pstats *p_stats; /* (b) Accounting/statistics (CPU). */
- struct plimit *p_limit; /* (c) Process limits. */
+ struct plimit *p_limit; /* (c) Resource limits. */
struct callout p_limco; /* (c) Limit callout handle */
struct sigacts *p_sigacts; /* (x) Signal actions, state (CPU). */
@@ -533,6 +535,7 @@ struct proc {
pid_t p_oppid; /* (c + e) Save ppid in ptrace. XXX */
struct vmspace *p_vmspace; /* (b) Address space. */
u_int p_swtick; /* (c) Tick when swapped in or out. */
+ u_int p_cowgen; /* (c) Generation of COW pointers. */
struct itimerval p_realtimer; /* (c) Alarm timer. */
struct rusage p_ru; /* (a) Exit information. */
struct rusage_ext p_rux; /* (cu) Internal resource usage. */
@@ -833,6 +836,11 @@ extern pid_t pid_max;
KASSERT((p)->p_lock == 0, ("process held")); \
} while (0)
+#define PROC_UPDATE_COW(p) do { \
+ PROC_LOCK_ASSERT((p), MA_OWNED); \
+ (p)->p_cowgen++; \
+} while (0)
+
/* Check whether a thread is safe to be swapped out. */
#define thread_safetoswapout(td) ((td)->td_flags & TDF_CANSWAP)
@@ -977,6 +985,10 @@ void cpu_thread_swapin(struct thread *);
void cpu_thread_swapout(struct thread *);
struct thread *thread_alloc(int pages);
int thread_alloc_stack(struct thread *, int pages);
+void thread_cow_get_proc(struct thread *newtd, struct proc *p);
+void thread_cow_get(struct thread *newtd, struct thread *td);
+void thread_cow_free(struct thread *td);
+void thread_cow_update(struct thread *td);
void thread_exit(void) __dead2;
void thread_free(struct thread *td);
void thread_link(struct thread *td, struct proc *p);
diff --git a/sys/sys/resourcevar.h b/sys/sys/resourcevar.h
index a07fdf8..b4c707d 100644
--- a/sys/sys/resourcevar.h
+++ b/sys/sys/resourcevar.h
@@ -130,13 +130,16 @@ int kern_proc_setrlimit(struct thread *td, struct proc *p, u_int which,
struct plimit
*lim_alloc(void);
void lim_copy(struct plimit *dst, struct plimit *src);
-rlim_t lim_cur(struct proc *p, int which);
+rlim_t lim_cur(struct thread *td, int which);
+rlim_t lim_cur_proc(struct proc *p, int which);
void lim_fork(struct proc *p1, struct proc *p2);
void lim_free(struct plimit *limp);
struct plimit
*lim_hold(struct plimit *limp);
-rlim_t lim_max(struct proc *p, int which);
-void lim_rlimit(struct proc *p, int which, struct rlimit *rlp);
+rlim_t lim_max(struct thread *td, int which);
+rlim_t lim_max_proc(struct proc *p, int which);
+void lim_rlimit(struct thread *td, int which, struct rlimit *rlp);
+void lim_rlimit_proc(struct proc *p, int which, struct rlimit *rlp);
void ruadd(struct rusage *ru, struct rusage_ext *rux, struct rusage *ru2,
struct rusage_ext *rux2);
void rucollect(struct rusage *ru, struct rusage *ru2);
@@ -156,5 +159,7 @@ void ui_racct_foreach(void (*callback)(struct racct *racct,
void *arg2, void *arg3), void *arg2, void *arg3);
#endif
+void lim_update_thread(struct thread *td);
+
#endif /* _KERNEL */
#endif /* !_SYS_RESOURCEVAR_H_ */
diff --git a/sys/sys/sbuf.h b/sys/sys/sbuf.h
index 40de36e..580cbd2 100644
--- a/sys/sys/sbuf.h
+++ b/sys/sys/sbuf.h
@@ -58,6 +58,14 @@ struct sbuf {
ssize_t s_sect_len; /* current length of section */
};
+#ifndef HD_COLUMN_MASK
+#define HD_COLUMN_MASK 0xff
+#define HD_DELIM_MASK 0xff00
+#define HD_OMIT_COUNT (1 << 16)
+#define HD_OMIT_HEX (1 << 17)
+#define HD_OMIT_CHARS (1 << 18)
+#endif /* HD_COLUMN_MASK */
+
__BEGIN_DECLS
/*
* API functions
@@ -89,6 +97,8 @@ int sbuf_done(const struct sbuf *);
void sbuf_delete(struct sbuf *);
void sbuf_start_section(struct sbuf *, ssize_t *);
ssize_t sbuf_end_section(struct sbuf *, ssize_t, size_t, int);
+void sbuf_hexdump(struct sbuf *, const void *, int, const char *,
+ int);
#ifdef _KERNEL
struct uio;
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index a30130f..36ef8af 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -692,7 +692,7 @@ int vn_rdwr_inchunks(enum uio_rw rw, struct vnode *vp, void *base,
struct ucred *active_cred, struct ucred *file_cred, size_t *aresid,
struct thread *td);
int vn_rlimit_fsize(const struct vnode *vn, const struct uio *uio,
- const struct thread *td);
+ struct thread *td);
int vn_stat(struct vnode *vp, struct stat *sb, struct ucred *active_cred,
struct ucred *file_cred, struct thread *td);
int vn_start_write(struct vnode *vp, struct mount **mpp, int flags);
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index c384064..2b9c334 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -2766,7 +2766,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS)
return (error);
if (cmd.version != FFS_CMD_VERSION)
return (ERPCMISMATCH);
- if ((error = getvnode(td->td_proc->p_fd, cmd.handle,
+ if ((error = getvnode(td, cmd.handle,
cap_rights_init(&rights, CAP_FSCK), &fp)) != 0)
return (error);
vp = fp->f_data;
@@ -3080,7 +3080,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS)
(intmax_t)cmd.value);
}
#endif /* DEBUG */
- if ((error = getvnode(td->td_proc->p_fd, cmd.value,
+ if ((error = getvnode(td, cmd.value,
cap_rights_init(&rights, CAP_FSCK), &vfp)) != 0)
break;
if (vfp->f_vnode->v_type != VCHR) {
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index ce43bcd..ffd8802 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -1410,6 +1410,14 @@ ffs_statfs(mp, sbp)
return (0);
}
+static bool
+sync_doupdate(struct inode *ip)
+{
+
+ return ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED |
+ IN_UPDATE)) != 0);
+}
+
/*
* For a lazy sync, we only care about access times, quotas and the
* superblock. Other filesystem changes are already converted to
@@ -1443,15 +1451,15 @@ ffs_sync_lazy(mp)
* Test also all the other timestamp flags too, to pick up
* any other cases that could be missed.
*/
- if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED |
- IN_UPDATE)) == 0) {
+ if (!sync_doupdate(ip) && (vp->v_iflag & VI_OWEINACT) == 0) {
VI_UNLOCK(vp);
continue;
}
if ((error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK,
td)) != 0)
continue;
- error = ffs_update(vp, 0);
+ if (sync_doupdate(ip))
+ error = ffs_update(vp, 0);
if (error != 0)
allerror = error;
vput(vp);
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 3005491..b3ad70e 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -224,16 +224,14 @@ swap_reserve_by_cred(vm_ooffset_t incr, struct ucred *cred)
mtx_unlock(&sw_dev_mtx);
if (res) {
- PROC_LOCK(curproc);
UIDINFO_VMSIZE_LOCK(uip);
if ((overcommit & SWAP_RESERVE_RLIMIT_ON) != 0 &&
- uip->ui_vmsize + incr > lim_cur(curproc, RLIMIT_SWAP) &&
+ uip->ui_vmsize + incr > lim_cur(curthread, RLIMIT_SWAP) &&
priv_check(curthread, PRIV_VM_SWAP_NORLIMIT))
res = 0;
else
uip->ui_vmsize += incr;
UIDINFO_VMSIZE_UNLOCK(uip);
- PROC_UNLOCK(curproc);
if (!res) {
mtx_lock(&sw_dev_mtx);
swap_reserved -= incr;
@@ -1120,10 +1118,6 @@ swap_pager_getpages(vm_object_t object, vm_page_t *m, int count, int reqpage)
mreq = m[reqpage];
- KASSERT(mreq->object == object,
- ("swap_pager_getpages: object mismatch %p/%p",
- object, mreq->object));
-
/*
* Calculate range to retrieve. The pages have already been assigned
* their swapblks. We require a *contiguous* range but we know it to
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 0c84d44..7391465 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -679,19 +679,12 @@ vnode_locked:
/*
* Found the page. Leave it busy while we play
* with it.
- */
-
- /*
- * Relookup in case pager changed page. Pager
+ *
+ * Pager could have changed the page. Pager
* is responsible for disposition of old page
* if moved.
*/
- fs.m = vm_page_lookup(fs.object, fs.pindex);
- if (!fs.m) {
- unlock_and_deallocate(&fs);
- goto RetryFault;
- }
-
+ fs.m = marray[reqpage];
hardfault++;
break; /* break to PAGE HAS BEEN FOUND */
}
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c
index c9ee890..1ff17c2 100644
--- a/sys/vm/vm_glue.c
+++ b/sys/vm/vm_glue.c
@@ -230,7 +230,7 @@ vsunlock(void *addr, size_t len)
static vm_page_t
vm_imgact_hold_page(vm_object_t object, vm_ooffset_t offset)
{
- vm_page_t m, ma[1];
+ vm_page_t m;
vm_pindex_t pindex;
int rv;
@@ -238,11 +238,7 @@ vm_imgact_hold_page(vm_object_t object, vm_ooffset_t offset)
pindex = OFF_TO_IDX(offset);
m = vm_page_grab(object, pindex, VM_ALLOC_NORMAL);
if (m->valid != VM_PAGE_BITS_ALL) {
- ma[0] = m;
- rv = vm_pager_get_pages(object, ma, 1, 0);
- m = vm_page_lookup(object, pindex);
- if (m == NULL)
- goto out;
+ rv = vm_pager_get_pages(object, &m, 1, 0);
if (rv != VM_PAGER_OK) {
vm_page_lock(m);
vm_page_free(m);
@@ -571,7 +567,7 @@ vm_thread_swapin(struct thread *td)
{
vm_object_t ksobj;
vm_page_t ma[KSTACK_MAX_PAGES];
- int i, j, k, pages, rv;
+ int i, j, pages, rv;
pages = td->td_kstack_pages;
ksobj = td->td_kstack_obj;
@@ -593,9 +589,12 @@ vm_thread_swapin(struct thread *td)
if (rv != VM_PAGER_OK)
panic("vm_thread_swapin: cannot get kstack for proc: %d",
td->td_proc->p_pid);
+ /*
+ * All pages in the array are in place, due to the
+ * pager is always the swap pager, which doesn't
+ * free or remove wired non-req pages from object.
+ */
vm_object_pip_wakeup(ksobj);
- for (k = i; k < j; k++)
- ma[k] = vm_page_lookup(ksobj, k);
vm_page_xunbusy(ma[i]);
} else if (vm_page_xbusied(ma[i]))
vm_page_xunbusy(ma[i]);
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c
index d4527b3..fd16bf2 100644
--- a/sys/vm/vm_kern.c
+++ b/sys/vm/vm_kern.c
@@ -391,8 +391,7 @@ void
kmem_unback(vm_object_t object, vm_offset_t addr, vm_size_t size)
{
vm_page_t m;
- vm_offset_t offset;
- int i;
+ vm_offset_t i, offset;
KASSERT(object == kmem_object || object == kernel_object,
("kmem_unback: only supports kernel objects."));
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index bad9994..12ebf5d 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -3424,10 +3424,8 @@ vm_map_stack(vm_map_t map, vm_offset_t addrbos, vm_size_t max_ssize,
growsize = sgrowsiz;
init_ssize = (max_ssize < growsize) ? max_ssize : growsize;
vm_map_lock(map);
- PROC_LOCK(curproc);
- lmemlim = lim_cur(curproc, RLIMIT_MEMLOCK);
- vmemlim = lim_cur(curproc, RLIMIT_VMEM);
- PROC_UNLOCK(curproc);
+ lmemlim = lim_cur(curthread, RLIMIT_MEMLOCK);
+ vmemlim = lim_cur(curthread, RLIMIT_VMEM);
if (!old_mlock && map->flags & MAP_WIREFUTURE) {
if (ptoa(pmap_wired_count(map->pmap)) + init_ssize > lmemlim) {
rv = KERN_NO_SPACE;
@@ -3556,12 +3554,10 @@ vm_map_growstack(struct proc *p, vm_offset_t addr)
int error;
#endif
+ lmemlim = lim_cur(curthread, RLIMIT_MEMLOCK);
+ stacklim = lim_cur(curthread, RLIMIT_STACK);
+ vmemlim = lim_cur(curthread, RLIMIT_VMEM);
Retry:
- PROC_LOCK(p);
- lmemlim = lim_cur(p, RLIMIT_MEMLOCK);
- stacklim = lim_cur(p, RLIMIT_STACK);
- vmemlim = lim_cur(p, RLIMIT_VMEM);
- PROC_UNLOCK(p);
vm_map_lock_read(map);
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 489a987..d331a9b 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -316,9 +316,9 @@ sys_mmap(td, uap)
if (addr == 0 ||
(addr >= round_page((vm_offset_t)vms->vm_taddr) &&
addr < round_page((vm_offset_t)vms->vm_daddr +
- lim_max(td->td_proc, RLIMIT_DATA))))
+ lim_max_proc(td->td_proc, RLIMIT_DATA))))
addr = round_page((vm_offset_t)vms->vm_daddr +
- lim_max(td->td_proc, RLIMIT_DATA));
+ lim_max_proc(td->td_proc, RLIMIT_DATA));
PROC_UNLOCK(td->td_proc);
}
if (size == 0) {
@@ -1028,7 +1028,7 @@ vm_mlock(struct proc *proc, struct ucred *cred, const void *addr0, size_t len)
map = &proc->p_vmspace->vm_map;
PROC_LOCK(proc);
nsize = ptoa(npages + pmap_wired_count(map->pmap));
- if (nsize > lim_cur(proc, RLIMIT_MEMLOCK)) {
+ if (nsize > lim_cur_proc(proc, RLIMIT_MEMLOCK)) {
PROC_UNLOCK(proc);
return (ENOMEM);
}
@@ -1088,7 +1088,7 @@ sys_mlockall(td, uap)
*/
if (!old_mlock && uap->how & MCL_CURRENT) {
PROC_LOCK(td->td_proc);
- if (map->size > lim_cur(td->td_proc, RLIMIT_MEMLOCK)) {
+ if (map->size > lim_cur(td, RLIMIT_MEMLOCK)) {
PROC_UNLOCK(td->td_proc);
return (ENOMEM);
}
@@ -1481,7 +1481,7 @@ vm_mmap_object(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
if (map == &td->td_proc->p_vmspace->vm_map) {
PROC_LOCK(td->td_proc);
- if (map->size + size > lim_cur(td->td_proc, RLIMIT_VMEM)) {
+ if (map->size + size > lim_cur_proc(td->td_proc, RLIMIT_VMEM)) {
PROC_UNLOCK(td->td_proc);
return (ENOMEM);
}
@@ -1491,7 +1491,7 @@ vm_mmap_object(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
}
if (!old_mlock && map->flags & MAP_WIREFUTURE) {
if (ptoa(pmap_wired_count(map->pmap)) + size >
- lim_cur(td->td_proc, RLIMIT_MEMLOCK)) {
+ lim_cur_proc(td->td_proc, RLIMIT_MEMLOCK)) {
racct_set_force(td->td_proc, RACCT_VMEM,
map->size);
PROC_UNLOCK(td->td_proc);
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index e240b67..c7f3153 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -2046,7 +2046,7 @@ vm_object_page_cache(vm_object_t object, vm_pindex_t start, vm_pindex_t end)
boolean_t
vm_object_populate(vm_object_t object, vm_pindex_t start, vm_pindex_t end)
{
- vm_page_t m, ma[1];
+ vm_page_t m;
vm_pindex_t pindex;
int rv;
@@ -2054,11 +2054,7 @@ vm_object_populate(vm_object_t object, vm_pindex_t start, vm_pindex_t end)
for (pindex = start; pindex < end; pindex++) {
m = vm_page_grab(object, pindex, VM_ALLOC_NORMAL);
if (m->valid != VM_PAGE_BITS_ALL) {
- ma[0] = m;
- rv = vm_pager_get_pages(object, ma, 1, 0);
- m = vm_page_lookup(object, pindex);
- if (m == NULL)
- break;
+ rv = vm_pager_get_pages(object, &m, 1, 0);
if (rv != VM_PAGER_OK) {
vm_page_lock(m);
vm_page_free(m);
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index 2f57579..bd77500 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -1159,6 +1159,17 @@ vm_pageout_scan(struct vm_domain *vmd, int pass)
queues_locked = FALSE;
/*
+ * Invalid pages can be easily freed. They cannot be
+ * mapped, vm_page_free() asserts this.
+ */
+ if (m->valid == 0 && m->hold_count == 0) {
+ vm_page_free(m);
+ PCPU_INC(cnt.v_dfree);
+ --page_shortage;
+ goto drop_page;
+ }
+
+ /*
* We bump the activation count if the page has been
* referenced while in the inactive queue. This makes
* it less likely that the page will be added back to the
@@ -1192,15 +1203,10 @@ vm_pageout_scan(struct vm_domain *vmd, int pass)
queues_locked = TRUE;
vm_page_requeue_locked(m);
}
- VM_OBJECT_WUNLOCK(object);
- vm_page_unlock(m);
- goto relock_queues;
+ goto drop_page;
}
if (m->hold_count != 0) {
- vm_page_unlock(m);
- VM_OBJECT_WUNLOCK(object);
-
/*
* Held pages are essentially stuck in the
* queue. So, they ought to be discounted
@@ -1209,7 +1215,7 @@ vm_pageout_scan(struct vm_domain *vmd, int pass)
* loop over the active queue below.
*/
addl_page_shortage++;
- goto relock_queues;
+ goto drop_page;
}
/*
@@ -1224,20 +1230,13 @@ vm_pageout_scan(struct vm_domain *vmd, int pass)
if (m->dirty == 0 && object->ref_count != 0)
pmap_remove_all(m);
- if (m->valid == 0) {
+ if (m->dirty == 0) {
/*
- * Invalid pages can be easily freed
+ * Clean pages can be freed.
*/
vm_page_free(m);
PCPU_INC(cnt.v_dfree);
--page_shortage;
- } else if (m->dirty == 0) {
- /*
- * Clean pages can be placed onto the cache queue.
- * This effectively frees them.
- */
- vm_page_cache(m);
- --page_shortage;
} else if ((m->flags & PG_WINATCFLS) == 0 && pass < 2) {
/*
* Dirty pages need to be paged out, but flushing
@@ -1305,6 +1304,7 @@ vm_pageout_scan(struct vm_domain *vmd, int pass)
vm_page_lock_assert(m, MA_NOTOWNED);
goto relock_queues;
}
+drop_page:
vm_page_unlock(m);
VM_OBJECT_WUNLOCK(object);
relock_queues:
@@ -1851,7 +1851,7 @@ again:
/*
* get a limit
*/
- lim_rlimit(p, RLIMIT_RSS, &rsslim);
+ lim_rlimit_proc(p, RLIMIT_RSS, &rsslim);
limit = OFF_TO_IDX(
qmin(rsslim.rlim_cur, rsslim.rlim_max));
diff --git a/sys/vm/vm_pager.c b/sys/vm/vm_pager.c
index ed9b562..b4fe8d0 100644
--- a/sys/vm/vm_pager.c
+++ b/sys/vm/vm_pager.c
@@ -250,8 +250,78 @@ vm_pager_deallocate(object)
(*pagertab[object->type]->pgo_dealloc) (object);
}
+static void
+vm_pager_assert_in(vm_object_t object, vm_page_t *m, int count)
+{
+#ifdef INVARIANTS
+
+ VM_OBJECT_ASSERT_WLOCKED(object);
+ KASSERT(count > 0, ("%s: 0 count", __func__));
+ /*
+ * All pages must be busied, not mapped, not fully valid,
+ * not dirty and belong to the proper object.
+ */
+ for (int i = 0 ; i < count; i++) {
+ vm_page_assert_xbusied(m[i]);
+ KASSERT(!pmap_page_is_mapped(m[i]),
+ ("%s: page %p is mapped", __func__, m[i]));
+ KASSERT(m[i]->valid != VM_PAGE_BITS_ALL,
+ ("%s: request for a valid page %p", __func__, m[i]));
+ KASSERT(m[i]->dirty == 0,
+ ("%s: page %p is dirty", __func__, m[i]));
+ KASSERT(m[i]->object == object,
+ ("%s: wrong object %p/%p", __func__, object, m[i]->object));
+ }
+#endif
+}
+
+/*
+ * Page in the pages for the object using its associated pager.
+ * The requested page must be fully valid on successful return.
+ */
+int
+vm_pager_get_pages(vm_object_t object, vm_page_t *m, int count, int reqpage)
+{
+ int r;
+
+ vm_pager_assert_in(object, m, count);
+
+ r = (*pagertab[object->type]->pgo_getpages)(object, m, count, reqpage);
+ if (r != VM_PAGER_OK)
+ return (r);
+
+ /*
+ * If pager has replaced the page, assert that it had
+ * updated the array. Also assert that page is still
+ * busied.
+ */
+ KASSERT(m[reqpage] == vm_page_lookup(object, m[reqpage]->pindex),
+ ("%s: mismatch page %p pindex %ju", __func__,
+ m[reqpage], (uintmax_t )m[reqpage]->pindex));
+ vm_page_assert_xbusied(m[reqpage]);
+
+ /*
+ * Pager didn't fill up entire page. Zero out
+ * partially filled data.
+ */
+ if (m[reqpage]->valid != VM_PAGE_BITS_ALL)
+ vm_page_zero_invalid(m[reqpage], TRUE);
+
+ return (VM_PAGER_OK);
+}
+
+int
+vm_pager_get_pages_async(vm_object_t object, vm_page_t *m, int count,
+ int reqpage, pgo_getpages_iodone_t iodone, void *arg)
+{
+
+ vm_pager_assert_in(object, m, count);
+
+ return ((*pagertab[object->type]->pgo_getpages_async)(object, m,
+ count, reqpage, iodone, arg));
+}
+
/*
- * vm_pager_get_pages() - inline, see vm/vm_pager.h
* vm_pager_put_pages() - inline, see vm/vm_pager.h
* vm_pager_has_page() - inline, see vm/vm_pager.h
*/
diff --git a/sys/vm/vm_pager.h b/sys/vm/vm_pager.h
index 3accc69..6884729 100644
--- a/sys/vm/vm_pager.h
+++ b/sys/vm/vm_pager.h
@@ -106,49 +106,15 @@ vm_object_t vm_pager_allocate(objtype_t, void *, vm_ooffset_t, vm_prot_t,
vm_ooffset_t, struct ucred *);
void vm_pager_bufferinit(void);
void vm_pager_deallocate(vm_object_t);
-static __inline int vm_pager_get_pages(vm_object_t, vm_page_t *, int, int);
-static inline int vm_pager_get_pages_async(vm_object_t, vm_page_t *, int,
- int, pgo_getpages_iodone_t, void *);
+int vm_pager_get_pages(vm_object_t, vm_page_t *, int, int);
+int vm_pager_get_pages_async(vm_object_t, vm_page_t *, int, int,
+ pgo_getpages_iodone_t, void *);
static __inline boolean_t vm_pager_has_page(vm_object_t, vm_pindex_t, int *, int *);
void vm_pager_init(void);
vm_object_t vm_pager_object_lookup(struct pagerlst *, void *);
void vm_pager_free_nonreq(vm_object_t object, vm_page_t ma[], int reqpage,
int npages, boolean_t object_locked);
-/*
- * vm_page_get_pages:
- *
- * Retrieve pages from the VM system in order to map them into an object
- * ( or into VM space somewhere ). If the pagein was successful, we
- * must fully validate it.
- */
-static __inline int
-vm_pager_get_pages(
- vm_object_t object,
- vm_page_t *m,
- int count,
- int reqpage
-) {
- int r;
-
- VM_OBJECT_ASSERT_WLOCKED(object);
- r = (*pagertab[object->type]->pgo_getpages)(object, m, count, reqpage);
- if (r == VM_PAGER_OK && m[reqpage]->valid != VM_PAGE_BITS_ALL) {
- vm_page_zero_invalid(m[reqpage], TRUE);
- }
- return (r);
-}
-
-static inline int
-vm_pager_get_pages_async(vm_object_t object, vm_page_t *m, int count,
- int reqpage, pgo_getpages_iodone_t iodone, void *arg)
-{
-
- VM_OBJECT_ASSERT_WLOCKED(object);
- return ((*pagertab[object->type]->pgo_getpages_async)(object, m,
- count, reqpage, iodone, arg));
-}
-
static __inline void
vm_pager_put_pages(
vm_object_t object,
diff --git a/sys/vm/vm_unix.c b/sys/vm/vm_unix.c
index cc77ff7..201c13b 100644
--- a/sys/vm/vm_unix.c
+++ b/sys/vm/vm_unix.c
@@ -83,11 +83,9 @@ sys_obreak(td, uap)
int error = 0;
boolean_t do_map_wirefuture;
- PROC_LOCK(td->td_proc);
- datalim = lim_cur(td->td_proc, RLIMIT_DATA);
- lmemlim = lim_cur(td->td_proc, RLIMIT_MEMLOCK);
- vmemlim = lim_cur(td->td_proc, RLIMIT_VMEM);
- PROC_UNLOCK(td->td_proc);
+ datalim = lim_cur(td, RLIMIT_DATA);
+ lmemlim = lim_cur(td, RLIMIT_MEMLOCK);
+ vmemlim = lim_cur(td, RLIMIT_VMEM);
do_map_wirefuture = FALSE;
new = round_page((vm_offset_t)uap->nsize);
diff --git a/sys/x86/acpica/acpi_wakeup.c b/sys/x86/acpica/acpi_wakeup.c
index 0eb6823..bc1c55c 100644
--- a/sys/x86/acpica/acpi_wakeup.c
+++ b/sys/x86/acpica/acpi_wakeup.c
@@ -210,7 +210,7 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state)
if (acpi_resume_beep != 0)
timer_spkr_acquire();
- AcpiSetFirmwareWakingVector(WAKECODE_PADDR(sc));
+ AcpiSetFirmwareWakingVector(WAKECODE_PADDR(sc), 0);
intr_suspend();
@@ -298,7 +298,7 @@ acpi_wakeup_machdep(struct acpi_softc *sc, int state, int sleep_result,
#endif
intr_resume(/*suspend_cancelled*/false);
- AcpiSetFirmwareWakingVector(0);
+ AcpiSetFirmwareWakingVector(0, 0);
} else {
/* Wakeup MD procedures in interrupt enabled context */
if (sleep_result == 1 && mem_range_softc.mr_op != NULL &&
diff --git a/sys/xen/blkif.h b/sys/xen/blkif.h
index 48b71ea..8a19d5d 100644
--- a/sys/xen/blkif.h
+++ b/sys/xen/blkif.h
@@ -46,7 +46,7 @@ struct blkif_x86_32_request {
blkif_vdev_t handle; /* only for read/write requests */
uint64_t id; /* private guest value, echoed in resp */
blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
- struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK];
+ struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
};
struct blkif_x86_32_response {
uint64_t id; /* copied from request */
@@ -64,7 +64,7 @@ struct blkif_x86_64_request {
blkif_vdev_t handle; /* only for read/write requests */
uint64_t __attribute__((__aligned__(8))) id;
blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
- struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK];
+ struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
};
struct blkif_x86_64_response {
uint64_t __attribute__((__aligned__(8))) id;
@@ -114,7 +114,7 @@ enum blkif_protocol {
static void inline blkif_get_x86_32_req(blkif_request_t *dst, blkif_x86_32_request_t *src)
{
- int i, n = BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK;
+ int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
dst->operation = src->operation;
dst->nr_segments = src->nr_segments;
dst->handle = src->handle;
@@ -129,7 +129,7 @@ static void inline blkif_get_x86_32_req(blkif_request_t *dst, blkif_x86_32_reque
static void inline blkif_get_x86_64_req(blkif_request_t *dst, blkif_x86_64_request_t *src)
{
- int i, n = BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK;
+ int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
dst->operation = src->operation;
dst->nr_segments = src->nr_segments;
dst->handle = src->handle;
diff --git a/sys/xen/interface/io/blkif.h b/sys/xen/interface/io/blkif.h
index 9155662..b725776 100644
--- a/sys/xen/interface/io/blkif.h
+++ b/sys/xen/interface/io/blkif.h
@@ -457,21 +457,9 @@
#define BLKIF_OP_DISCARD 5
/*
- * Maximum scatter/gather segments associated with a request header block.
- * This is carefully chosen so that sizeof(blkif_ring_t) <= PAGE_SIZE.
- * NB. This could be 12 if the ring indexes weren't stored in the same page.
- */
-#define BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK 11
-
-/*
- * Maximum scatter/gather segments associated with a segment block.
- */
-#define BLKIF_MAX_SEGMENTS_PER_SEGMENT_BLOCK 14
-
-/*
* Maximum scatter/gather segments per request (header + segment blocks).
*/
-#define BLKIF_MAX_SEGMENTS_PER_REQUEST 255
+#define BLKIF_MAX_SEGMENTS_PER_REQUEST 11
/*
* NB. first_sect and last_sect in blkif_request_segment, as well as
@@ -512,22 +500,11 @@ struct blkif_request {
blkif_vdev_t handle; /* only for read/write requests */
uint64_t id; /* private guest value, echoed in resp */
blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
- blkif_request_segment_t seg[BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK];
+ blkif_request_segment_t seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
};
typedef struct blkif_request blkif_request_t;
/*
- * A segment block is a ring request structure that contains only
- * segment data.
- *
- * sizeof(struct blkif_segment_block) <= sizeof(struct blkif_request)
- */
-struct blkif_segment_block {
- blkif_request_segment_t seg[BLKIF_MAX_SEGMENTS_PER_SEGMENT_BLOCK];
-};
-typedef struct blkif_segment_block blkif_segment_block_t;
-
-/*
* Cast to this structure when blkif_request.operation == BLKIF_OP_DISCARD
* sizeof(struct blkif_request_discard) <= sizeof(struct blkif_request)
*/
@@ -564,21 +541,6 @@ typedef struct blkif_response blkif_response_t;
*/
DEFINE_RING_TYPES(blkif, struct blkif_request, struct blkif_response);
-/*
- * Index to, and treat as a segment block, an entry in the ring.
- */
-#define BLKRING_GET_SEG_BLOCK(_r, _idx) \
- (((blkif_segment_block_t *)RING_GET_REQUEST(_r, _idx))->seg)
-
-/*
- * The number of ring request blocks required to handle an I/O
- * request containing _segs segments.
- */
-#define BLKIF_SEGS_TO_BLOCKS(_segs) \
- ((((_segs - BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK) \
- + (BLKIF_MAX_SEGMENTS_PER_SEGMENT_BLOCK - 1)) \
- / BLKIF_MAX_SEGMENTS_PER_SEGMENT_BLOCK) + /*header_block*/1)
-
#define VDISK_CDROM 0x1
#define VDISK_REMOVABLE 0x2
#define VDISK_READONLY 0x4
OpenPOWER on IntegriCloud