summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2016-11-10 07:35:47 -0200
committerRenato Botelho <renato@netgate.com>2016-11-10 07:35:47 -0200
commite06dd1d464d989e4c819e9fc383761d74be6f119 (patch)
treee574c8d6488a2657dccd8e8fd18ef708f393c545
parentad34a03fa7496e0be9fcc7c56c8e49fa763d34a0 (diff)
parentae76dae508b95eb0ab4a3b9bd65333a903686046 (diff)
downloadFreeBSD-src-e06dd1d464d989e4c819e9fc383761d74be6f119.zip
FreeBSD-src-e06dd1d464d989e4c819e9fc383761d74be6f119.tar.gz
Merge remote-tracking branch 'origin/stable/11' into devel-11
-rw-r--r--contrib/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp11
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c2
-rw-r--r--contrib/tzdata/CONTRIBUTING73
-rw-r--r--contrib/tzdata/LICENSE4
-rw-r--r--contrib/tzdata/Makefile793
-rw-r--r--contrib/tzdata/NEWS3782
-rw-r--r--contrib/tzdata/README71
-rw-r--r--contrib/tzdata/Theory840
-rw-r--r--contrib/tzdata/antarctica7
-rw-r--r--contrib/tzdata/asia17
-rw-r--r--contrib/tzdata/australasia18
-rw-r--r--contrib/tzdata/backzone677
-rw-r--r--contrib/tzdata/checklinks.awk48
-rw-r--r--contrib/tzdata/checktab.awk177
-rw-r--r--contrib/tzdata/europe145
-rw-r--r--contrib/tzdata/leapseconds.awk76
-rw-r--r--contrib/tzdata/version1
-rw-r--r--contrib/tzdata/zone.tab3
-rw-r--r--contrib/tzdata/zone1970.tab3
-rwxr-xr-xcontrib/tzdata/zoneinfo2tdf.pl52
-rw-r--r--etc/Makefile2
-rw-r--r--etc/rc.d/Makefile1
-rwxr-xr-xetc/rc.d/zfs2
-rwxr-xr-xetc/rc.d/zfsbe71
-rw-r--r--gnu/lib/libgcc/Makefile4
-rw-r--r--lib/libc/sys/getloginclass.27
-rw-r--r--libexec/ftpd/blacklist.c6
-rw-r--r--libexec/ftpd/blacklist_client.h23
-rw-r--r--libexec/ftpd/ftpd.810
-rw-r--r--libexec/ftpd/ftpd.c26
-rw-r--r--release/arm/CUBIEBOARD.conf2
-rw-r--r--release/doc/share/xml/security.xml8
-rw-r--r--share/examples/Makefile2
-rw-r--r--share/man/man4/ddb.486
-rw-r--r--share/man/man4/jedec_ts.4130
-rw-r--r--sys/amd64/amd64/machdep.c1
-rw-r--r--sys/amd64/amd64/trap.c76
-rw-r--r--sys/amd64/include/cputypes.h46
-rw-r--r--sys/amd64/include/db_machdep.h12
-rw-r--r--sys/amd64/vmm/amd/svm.c9
-rw-r--r--sys/arm/allwinner/a10/a10_padconf.c (renamed from sys/arm/allwinner/a10_padconf.c)0
-rw-r--r--sys/arm/allwinner/a10/files.a104
-rw-r--r--sys/arm/allwinner/a10_ahci.c4
-rw-r--r--sys/arm/allwinner/a10_codec.c4
-rw-r--r--sys/arm/allwinner/a10_dmac.c2
-rw-r--r--sys/arm/allwinner/a10_ehci.c14
-rw-r--r--sys/arm/allwinner/a10_fb.c16
-rw-r--r--sys/arm/allwinner/a10_gpio.c8
-rw-r--r--sys/arm/allwinner/a10_hdmi.c6
-rw-r--r--sys/arm/allwinner/a10_mmc.c312
-rw-r--r--sys/arm/allwinner/a10_mmc.h257
-rw-r--r--sys/arm/allwinner/aw_if_dwc.c6
-rw-r--r--sys/arm/allwinner/aw_machdep.c (renamed from sys/arm/allwinner/allwinner_machdep.c)5
-rw-r--r--sys/arm/allwinner/aw_machdep.h (renamed from sys/arm/allwinner/allwinner_machdep.h)2
-rw-r--r--sys/arm/allwinner/aw_mp.c2
-rw-r--r--sys/arm/allwinner/aw_rsb.c4
-rw-r--r--sys/arm/allwinner/aw_rtc.c2
-rw-r--r--sys/arm/allwinner/aw_ts.c230
-rw-r--r--sys/arm/allwinner/aw_usbphy.c6
-rw-r--r--sys/arm/allwinner/aw_wdog.c1
-rw-r--r--sys/arm/allwinner/clk/aw_ahbclk.c2
-rw-r--r--sys/arm/allwinner/clk/aw_apbclk.c2
-rw-r--r--sys/arm/allwinner/clk/aw_axiclk.c2
-rw-r--r--sys/arm/allwinner/clk/aw_codecclk.c2
-rw-r--r--sys/arm/allwinner/clk/aw_cpuclk.c2
-rw-r--r--sys/arm/allwinner/clk/aw_cpusclk.c2
-rw-r--r--sys/arm/allwinner/clk/aw_debeclk.c2
-rw-r--r--sys/arm/allwinner/clk/aw_gate.c2
-rw-r--r--sys/arm/allwinner/clk/aw_gmacclk.c2
-rw-r--r--sys/arm/allwinner/clk/aw_hdmiclk.c2
-rw-r--r--sys/arm/allwinner/clk/aw_lcdclk.c2
-rw-r--r--sys/arm/allwinner/clk/aw_mmcclk.c2
-rw-r--r--sys/arm/allwinner/clk/aw_modclk.c2
-rw-r--r--sys/arm/allwinner/clk/aw_pll.c4
-rw-r--r--sys/arm/allwinner/clk/aw_usbclk.c4
-rw-r--r--sys/arm/allwinner/files.a105
-rw-r--r--sys/arm/allwinner/files.allwinner4
-rw-r--r--sys/arm/allwinner/files.allwinner_up3
-rw-r--r--sys/arm/allwinner/if_awg.c8
-rw-r--r--sys/arm/allwinner/if_emac.c2
-rw-r--r--sys/arm/allwinner/std.allwinner_up (renamed from sys/arm/allwinner/std.a10)5
-rw-r--r--sys/arm/allwinner/timer.c2
-rw-r--r--sys/arm/amlogic/aml8726/aml8726_machdep.c1
-rw-r--r--sys/arm/amlogic/aml8726/aml8726_wdt.c1
-rw-r--r--sys/arm/arm/gic.c4
-rw-r--r--sys/arm/arm/nexus.c53
-rw-r--r--sys/arm/at91/at91_aic.c2
-rw-r--r--sys/arm/at91/at91_cfata.c2
-rw-r--r--sys/arm/at91/at91_mci.c2
-rw-r--r--sys/arm/at91/at91_ohci.c6
-rw-r--r--sys/arm/at91/at91_ohci_fdt.c6
-rw-r--r--sys/arm/at91/at91_pit.c1
-rw-r--r--sys/arm/at91/at91_pmc.c2
-rw-r--r--sys/arm/at91/at91_st.c1
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_dma.c2
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_spi.c2
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_wdog.c1
-rw-r--r--sys/arm/cavium/cns11xx/ehci_ebus.c6
-rw-r--r--sys/arm/cavium/cns11xx/ohci_ec.c6
-rw-r--r--sys/arm/conf/ALLWINNER_UP (renamed from sys/arm/conf/A10)7
-rw-r--r--sys/arm/conf/CUBIEBOARD33
-rw-r--r--sys/arm/freescale/imx/imx51_ipuv3.c2
-rw-r--r--sys/arm/freescale/imx/imx51_ipuv3_fbd.c2
-rw-r--r--sys/arm/include/atomic-v6.h22
-rw-r--r--sys/arm/lpc/lpc_fb.c2
-rw-r--r--sys/arm/lpc/lpc_gpio.c2
-rw-r--r--sys/arm/lpc/lpc_mmc.c2
-rw-r--r--sys/arm/lpc/lpc_spi.c2
-rw-r--r--sys/arm/mv/mpic.c1
-rw-r--r--sys/arm/nvidia/as3722.c4
-rw-r--r--sys/arm/nvidia/as3722_regulators.c128
-rw-r--r--sys/arm/nvidia/tegra124/tegra124_car.c11
-rw-r--r--sys/arm/nvidia/tegra124/tegra124_coretemp.c17
-rw-r--r--sys/arm/nvidia/tegra124/tegra124_cpufreq.c34
-rw-r--r--sys/arm/nvidia/tegra124/tegra124_machdep.c12
-rw-r--r--sys/arm/nvidia/tegra124/tegra124_pmc.c12
-rw-r--r--sys/arm/nvidia/tegra124/tegra124_xusbpadctl.c14
-rw-r--r--sys/arm/nvidia/tegra_abpmisc.c6
-rw-r--r--sys/arm/nvidia/tegra_ahci.c41
-rw-r--r--sys/arm/nvidia/tegra_efuse.c11
-rw-r--r--sys/arm/nvidia/tegra_ehci.c18
-rw-r--r--sys/arm/nvidia/tegra_gpio.c18
-rw-r--r--sys/arm/nvidia/tegra_i2c.c14
-rw-r--r--sys/arm/nvidia/tegra_lic.c15
-rw-r--r--sys/arm/nvidia/tegra_pcie.c915
-rw-r--r--sys/arm/nvidia/tegra_pinmux.c11
-rw-r--r--sys/arm/nvidia/tegra_rtc.c9
-rw-r--r--sys/arm/nvidia/tegra_sdhci.c22
-rw-r--r--sys/arm/nvidia/tegra_soctherm.c10
-rw-r--r--sys/arm/nvidia/tegra_uart.c4
-rw-r--r--sys/arm/nvidia/tegra_usbphy.c23
-rw-r--r--sys/arm/rockchip/rk30xx_gpio.c2
-rw-r--r--sys/arm/rockchip/rk30xx_wdog.c1
-rw-r--r--sys/arm/samsung/exynos/exynos5_xhci.c6
-rw-r--r--sys/arm/ti/am335x/am335x_gpio.c2
-rw-r--r--sys/arm/ti/am335x/am335x_lcd_syscons.c2
-rw-r--r--sys/arm/ti/am335x/am335x_musb.c11
-rw-r--r--sys/arm/ti/am335x/am335x_scm_padconf.c2
-rw-r--r--sys/arm/ti/omap4/omap4_prcm_clks.c2
-rw-r--r--sys/arm/ti/omap4/omap4_wugen.c12
-rw-r--r--sys/arm/ti/ti_cpuid.c2
-rw-r--r--sys/arm/ti/ti_pinmux.c2
-rw-r--r--sys/arm/ti/ti_prcm.c2
-rw-r--r--sys/arm/ti/ti_scm.c2
-rw-r--r--sys/arm/ti/twl/twl.c2
-rw-r--r--sys/arm/ti/twl/twl_clks.c2
-rw-r--r--sys/arm/ti/twl/twl_vreg.c2
-rw-r--r--sys/arm/ti/usb/omap_ehci.c7
-rw-r--r--sys/arm/xilinx/zy7_ehci.c11
-rw-r--r--sys/arm/xscale/i8134x/i80321_timer.c1
-rw-r--r--sys/arm/xscale/i8134x/i80321_wdog.c1
-rw-r--r--sys/arm/xscale/ixp425/avila_ata.c2
-rw-r--r--sys/arm/xscale/ixp425/ixp425_intr.h1
-rw-r--r--sys/arm/xscale/ixp425/ixp425_npe.c2
-rw-r--r--sys/arm/xscale/ixp425/ixp425_qmgr.c2
-rw-r--r--sys/arm/xscale/ixp425/ixp425_timer.c1
-rw-r--r--sys/arm/xscale/ixp425/ixp425_wdog.c2
-rw-r--r--sys/arm64/arm64/nexus.c37
-rw-r--r--sys/boot/fdt/dts/arm/bananapi.dts4
-rw-r--r--sys/boot/kshim/bsd_kernel.c11
-rw-r--r--sys/cam/cam_periph.c43
-rw-r--r--sys/cam/cam_periph.h1
-rw-r--r--sys/cam/cam_queue.c7
-rw-r--r--sys/cam/cam_queue.h11
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zrlock.c48
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c22
-rw-r--r--sys/compat/linprocfs/linprocfs.c31
-rw-r--r--sys/conf/NOTES5
-rw-r--r--sys/conf/files1
-rw-r--r--sys/ddb/db_examine.c2
-rw-r--r--sys/ddb/db_expr.c36
-rw-r--r--sys/ddb/db_main.c5
-rw-r--r--sys/ddb/db_run.c40
-rw-r--r--sys/ddb/ddb.h3
-rw-r--r--sys/dev/acpi_support/atk0110.c417
-rw-r--r--sys/dev/dwc/if_dwc.c4
-rw-r--r--sys/dev/evdev/evdev.c15
-rw-r--r--sys/dev/evdev/evdev.h66
-rw-r--r--sys/dev/evdev/evdev_utils.c7
-rw-r--r--sys/dev/extres/clk/clk.c17
-rw-r--r--sys/dev/extres/clk/clk.h5
-rw-r--r--sys/dev/extres/clk/clk_fixed.c2
-rw-r--r--sys/dev/extres/hwreset/hwreset.c17
-rw-r--r--sys/dev/extres/hwreset/hwreset.h6
-rw-r--r--sys/dev/extres/phy/phy.c23
-rw-r--r--sys/dev/extres/phy/phy.h11
-rw-r--r--sys/dev/extres/regulator/regulator.c94
-rw-r--r--sys/dev/extres/regulator/regulator.h22
-rw-r--r--sys/dev/fdt/simplebus.c2
-rw-r--r--sys/dev/gpio/gpiobus.c27
-rw-r--r--sys/dev/gpio/gpiobusvar.h2
-rw-r--r--sys/dev/gpio/ofw_gpiobus.c2
-rw-r--r--sys/dev/iicbus/ofw_iicbus.c2
-rw-r--r--sys/dev/iicbus/twsi/a10_twsi.c4
-rw-r--r--sys/dev/jedec_ts/jedec_ts.c179
-rw-r--r--sys/dev/ofw/ofw_bus_subr.c30
-rw-r--r--sys/dev/ofw/ofw_bus_subr.h11
-rw-r--r--sys/dev/ofw/ofwbus.c56
-rw-r--r--sys/dev/pci/pci_host_generic.c2
-rw-r--r--sys/dev/puc/puc.c3
-rw-r--r--sys/dev/uart/uart_cpu_powerpc.c8
-rw-r--r--sys/dev/uart/uart_dev_snps.c8
-rw-r--r--sys/dev/usb/controller/at91dci_atmelarm.c6
-rw-r--r--sys/dev/usb/controller/at91dci_fdt.c6
-rw-r--r--sys/dev/usb/controller/atmegadci_atmelarm.c6
-rw-r--r--sys/dev/usb/controller/dwc_otg_fdt.c6
-rw-r--r--sys/dev/usb/controller/ehci_ixp4xx.c6
-rw-r--r--sys/dev/usb/controller/ehci_mv.c6
-rw-r--r--sys/dev/usb/controller/ehci_pci.c6
-rw-r--r--sys/dev/usb/controller/generic_ehci.c6
-rw-r--r--sys/dev/usb/controller/generic_ohci.c13
-rw-r--r--sys/dev/usb/controller/musb_otg_atmelarm.c6
-rw-r--r--sys/dev/usb/controller/ohci_pci.c6
-rw-r--r--sys/dev/usb/controller/ohci_s3c24x0.c6
-rw-r--r--sys/dev/usb/controller/saf1761_otg_boot.c7
-rw-r--r--sys/dev/usb/controller/saf1761_otg_fdt.c6
-rw-r--r--sys/dev/usb/controller/uhci_pci.c6
-rw-r--r--sys/dev/usb/controller/uss820dci_atmelarm.c6
-rw-r--r--sys/dev/usb/controller/xhci_mv.c7
-rw-r--r--sys/dev/usb/controller/xhci_pci.c6
-rw-r--r--sys/dev/usb/input/ums.c75
-rw-r--r--sys/dev/usb/template/usb_template_mtp.c2
-rw-r--r--sys/dev/usb/usb_device.c8
-rw-r--r--sys/dev/usb/video/udl.c9
-rw-r--r--sys/dev/vnic/mrml_bridge.c2
-rw-r--r--sys/dev/vnic/thunder_mdio_fdt.c2
-rw-r--r--sys/fs/autofs/autofs_vnops.c18
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c6
-rw-r--r--sys/fs/nullfs/null_subr.c2
-rw-r--r--sys/i386/i386/db_disasm.c13
-rw-r--r--sys/i386/i386/db_interface.c24
-rw-r--r--sys/i386/i386/db_trace.c55
-rw-r--r--sys/i386/i386/trap.c79
-rw-r--r--sys/i386/i386/vm86.c8
-rw-r--r--sys/i386/include/cputypes.h5
-rw-r--r--sys/i386/include/db_machdep.h19
-rw-r--r--sys/i386/include/md_var.h1
-rw-r--r--sys/kern/bus_if.m29
-rw-r--r--sys/kern/kern_synch.c8
-rw-r--r--sys/kern/pic_if.m12
-rw-r--r--sys/kern/subr_bus.c86
-rw-r--r--sys/kern/subr_intr.c372
-rw-r--r--sys/kern/subr_smp.c53
-rw-r--r--sys/kern/subr_witness.c4
-rw-r--r--sys/kern/vfs_lookup.c32
-rw-r--r--sys/kern/vfs_mount.c7
-rw-r--r--sys/kern/vfs_subr.c6
-rw-r--r--sys/mips/atheros/ar71xx_ehci.c6
-rw-r--r--sys/mips/atheros/ar71xx_ohci.c6
-rw-r--r--sys/mips/cavium/usb/octusb_octeon.c6
-rw-r--r--sys/mips/include/intr.h2
-rw-r--r--sys/mips/mediatek/mtk_dotg.c6
-rw-r--r--sys/mips/mediatek/mtk_ehci.c6
-rw-r--r--sys/mips/mediatek/mtk_ohci.c6
-rw-r--r--sys/mips/mediatek/mtk_xhci.c6
-rw-r--r--sys/mips/mips/mips_pic.c89
-rw-r--r--sys/mips/mips/nexus.c48
-rw-r--r--sys/mips/rmi/xls_ehci.c6
-rw-r--r--sys/mips/rt305x/rt305x_dotg.c6
-rw-r--r--sys/mips/rt305x/rt305x_ehci.c6
-rw-r--r--sys/mips/rt305x/rt305x_ohci.c6
-rw-r--r--sys/modules/dtb/allwinner/Makefile3
-rw-r--r--sys/modules/dtb/nvidia/Makefile6
-rw-r--r--sys/modules/i2c/Makefile2
-rw-r--r--sys/modules/i2c/jedec_ts/Makefile7
-rw-r--r--sys/netinet/tcp_syncache.c4
-rw-r--r--sys/ofed/drivers/net/mlx4/en_tx.c15
-rw-r--r--sys/sys/bus.h14
-rw-r--r--sys/sys/intr.h39
-rw-r--r--sys/vm/device_pager.c5
-rw-r--r--sys/vm/vm_fault.c106
-rw-r--r--sys/vm/vm_pager.h1
-rw-r--r--sys/x86/include/cputypes.h5
-rw-r--r--sys/x86/include/frame.h16
-rw-r--r--sys/x86/include/x86_smp.h3
-rw-r--r--sys/x86/include/x86_var.h5
-rw-r--r--sys/x86/x86/cpu_machdep.c53
-rw-r--r--sys/x86/x86/identcpu.c43
-rw-r--r--sys/x86/x86/mp_x86.c35
-rw-r--r--tools/build/mk/OptionalObsoleteFiles.inc1
-rw-r--r--usr.bin/calendar/Makefile10
-rw-r--r--usr.bin/localedef/ctype.c6
-rw-r--r--usr.bin/localedef/parser.y23
-rw-r--r--usr.bin/mkcsmapper/yacc.y2
-rw-r--r--usr.bin/sed/compile.c3
-rw-r--r--usr.sbin/amd/Makefile.inc4
-rw-r--r--usr.sbin/amd/amd/Makefile4
-rw-r--r--usr.sbin/amd/libamu/Makefile2
-rw-r--r--usr.sbin/cron/cron/cron.85
-rw-r--r--usr.sbin/cron/cron/cron.c10
-rw-r--r--usr.sbin/mountd/mountd.84
-rw-r--r--usr.sbin/mountd/mountd.c2
292 files changed, 10267 insertions, 2657 deletions
diff --git a/contrib/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/contrib/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 92cf1cd..9cbf488 100644
--- a/contrib/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/contrib/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -7562,6 +7562,7 @@ static SDValue performIntToFpCombine(SDNode *N, SelectionDAG &DAG,
/// Fold a floating-point multiply by power of two into floating-point to
/// fixed-point conversion.
static SDValue performFpToIntCombine(SDNode *N, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI,
const AArch64Subtarget *Subtarget) {
if (!Subtarget->hasNEON())
return SDValue();
@@ -7604,10 +7605,16 @@ static SDValue performFpToIntCombine(SDNode *N, SelectionDAG &DAG,
ResTy = FloatBits == 32 ? MVT::v2i32 : MVT::v2i64;
break;
case 4:
- ResTy = MVT::v4i32;
+ ResTy = FloatBits == 32 ? MVT::v4i32 : MVT::v4i64;
break;
}
+ if (ResTy == MVT::v4i64 && DCI.isBeforeLegalizeOps())
+ return SDValue();
+
+ assert((ResTy != MVT::v4i64 || DCI.isBeforeLegalizeOps()) &&
+ "Illegal vector type after legalization");
+
SDLoc DL(N);
bool IsSigned = N->getOpcode() == ISD::FP_TO_SINT;
unsigned IntrinsicOpcode = IsSigned ? Intrinsic::aarch64_neon_vcvtfp2fxs
@@ -9711,7 +9718,7 @@ SDValue AArch64TargetLowering::PerformDAGCombine(SDNode *N,
return performIntToFpCombine(N, DAG, Subtarget);
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT:
- return performFpToIntCombine(N, DAG, Subtarget);
+ return performFpToIntCombine(N, DAG, DCI, Subtarget);
case ISD::FDIV:
return performFDivCombine(N, DAG, Subtarget);
case ISD::OR:
diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c b/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c
index 0c44316..716a881 100644
--- a/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c
+++ b/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c
@@ -88,7 +88,7 @@ static struct test {
0xFFFF, 0x5D, 0x5B, 0x10000, 0x10FFFF, 0x5D, 0x0A
},
#ifdef __FreeBSD__
- { 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1,
+ { 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1,
#else
{ 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1,
#endif
diff --git a/contrib/tzdata/CONTRIBUTING b/contrib/tzdata/CONTRIBUTING
new file mode 100644
index 0000000..e40102e
--- /dev/null
+++ b/contrib/tzdata/CONTRIBUTING
@@ -0,0 +1,73 @@
+Contributing to the tz code and data
+
+The time zone database is by no means authoritative: governments
+change timekeeping rules erratically and sometimes with little
+warning, the data entries do not cover all of civil time before
+1970, and undoubtedly errors remain in the code and data. Feel
+free to fill gaps or fix mistakes, and please email improvements
+to tz@iana.org for use in the future.
+
+To email small changes, please run a POSIX shell command like
+'diff -u old/europe new/europe >myfix.patch', and attach
+myfix.patch to the email.
+
+For more-elaborate changes, please read the Theory file and browse
+the mailing list archives <http://mm.icann.org/pipermail/tz/> for
+examples of patches that tend to work well. Ideally, additions to
+data should contain commentary citing reliable sources as
+justification.
+
+Please submit changes against either the latest release in
+<ftp://ftp.iana.org/tz/> or the master branch of the experimental
+Git repository. If you use Git the following workflow may be helpful:
+
+ * Copy the experimental repository.
+
+ git clone https://github.com/eggert/tz.git
+ cd tz
+
+ * Get current with the master branch.
+
+ git checkout master
+ git pull
+
+ * Switch to a new branch for the changes. Choose a different
+ branch name for each change set.
+
+ git checkout -b mybranch
+
+ * Edit source files. Include commentary that justifies the
+ changes by citing reliable sources.
+
+ * Debug the changes, e.g.:
+
+ make check
+ make install
+ ./zdump -v America/Los_Angeles
+
+ * For each separable change, commit it in the new branch, e.g.:
+
+ git add northamerica
+ git commit
+
+ See recent 'git log' output for the commit-message style.
+
+ * Create patch files 0001-*, 0002-*, ...
+
+ git format-patch master
+
+ * After reviewing the patch files, send the patches to tz@iana.org
+ for others to review.
+
+ git send-email master
+
+ * Start anew by getting current with the master branch again
+ (the second step above).
+
+Please do not create issues or pull requests on GitHub, as the
+proper procedure for proposing and distributing patches is via
+email as illustrated above.
+
+-----
+
+This file is in the public domain.
diff --git a/contrib/tzdata/LICENSE b/contrib/tzdata/LICENSE
new file mode 100644
index 0000000..148eb23
--- /dev/null
+++ b/contrib/tzdata/LICENSE
@@ -0,0 +1,4 @@
+With a few exceptions, all files in the tz code and data (including
+this one) are in the public domain. The exceptions are date.c,
+newstrftime.3, and strftime.c, which contain material derived from BSD
+and which use the BSD 3-clause license.
diff --git a/contrib/tzdata/Makefile b/contrib/tzdata/Makefile
new file mode 100644
index 0000000..74b950c
--- /dev/null
+++ b/contrib/tzdata/Makefile
@@ -0,0 +1,793 @@
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# Package name for the code distribution.
+PACKAGE= tzcode
+
+# Version number for the distribution, overridden in the 'tarballs' rule below.
+VERSION= unknown
+
+# Email address for bug reports.
+BUGEMAIL= tz@iana.org
+
+# Change the line below for your time zone (after finding the zone you want in
+# the time zone files, or adding it to a time zone file).
+# Alternately, if you discover you've got the wrong time zone, you can just
+# zic -l rightzone
+# to correct things.
+# Use the command
+# make zonenames
+# to get a list of the values you can use for LOCALTIME.
+
+LOCALTIME= GMT
+
+# If you want something other than Eastern United States time as a template
+# for handling POSIX-style time zone environment variables,
+# change the line below (after finding the zone you want in the
+# time zone files, or adding it to a time zone file).
+# (When a POSIX-style environment variable is handled, the rules in the
+# template file are used to determine "spring forward" and "fall back" days and
+# times; the environment variable itself specifies UT offsets of standard and
+# summer time.)
+# Alternately, if you discover you've got the wrong time zone, you can just
+# zic -p rightzone
+# to correct things.
+# Use the command
+# make zonenames
+# to get a list of the values you can use for POSIXRULES.
+# If you want POSIX compatibility, use "America/New_York".
+
+POSIXRULES= America/New_York
+
+# Also see TZDEFRULESTRING below, which takes effect only
+# if the time zone files cannot be accessed.
+
+# Everything gets put in subdirectories of. . .
+
+TOPDIR= /usr/local
+
+# "Compiled" time zone information is placed in the "TZDIR" directory
+# (and subdirectories).
+# Use an absolute path name for TZDIR unless you're just testing the software.
+
+TZDIR_BASENAME= zoneinfo
+TZDIR= $(TOPDIR)/etc/$(TZDIR_BASENAME)
+
+# Types to try, as an alternative to time_t. int64_t should be first.
+TIME_T_ALTERNATIVES= int64_t int32_t uint32_t uint64_t
+
+# The "tzselect", "zic", and "zdump" commands get installed in. . .
+
+ETCDIR= $(TOPDIR)/etc
+
+# If you "make INSTALL", the "date" command gets installed in. . .
+
+BINDIR= $(TOPDIR)/bin
+
+# Manual pages go in subdirectories of. . .
+
+MANDIR= $(TOPDIR)/man
+
+# Library functions are put in an archive in LIBDIR.
+
+LIBDIR= $(TOPDIR)/lib
+
+# If you always want time values interpreted as "seconds since the epoch
+# (not counting leap seconds)", use
+# REDO= posix_only
+# below. If you always want right time values interpreted as "seconds since
+# the epoch" (counting leap seconds)", use
+# REDO= right_only
+# below. If you want both sets of data available, with leap seconds not
+# counted normally, use
+# REDO= posix_right
+# below. If you want both sets of data available, with leap seconds counted
+# normally, use
+# REDO= right_posix
+# below. POSIX mandates that leap seconds not be counted; for compatibility
+# with it, use "posix_only" or "posix_right".
+
+REDO= posix_right
+
+# If you want out-of-scope and often-wrong data from the file 'backzone', use
+# PACKRATDATA= backzone
+# To omit this data, use
+# PACKRATDATA=
+
+PACKRATDATA=
+
+# Since "." may not be in PATH...
+
+YEARISTYPE= ./yearistype
+
+# Non-default libraries needed to link.
+LDLIBS=
+
+# Add the following to the end of the "CFLAGS=" line as needed.
+# -DBIG_BANG=-9999999LL if the Big Bang occurred at time -9999999 (see zic.c)
+# -DHAVE_DECL_ASCTIME_R=0 if <time.h> does not declare asctime_r
+# -DHAVE_DIRECT_H if mkdir needs <direct.h> (MS-Windows)
+# -DHAVE_DOS_FILE_NAMES if file names have drive specifiers etc. (MS-DOS)
+# -DHAVE_GETTEXT=1 if 'gettext' works (e.g., GNU/Linux, FreeBSD, Solaris)
+# -DHAVE_INCOMPATIBLE_CTIME_R=1 if your system's time.h declares
+# ctime_r and asctime_r incompatibly with the POSIX standard
+# (Solaris when _POSIX_PTHREAD_SEMANTICS is not defined).
+# -DHAVE_INTTYPES_H=1 if you have a pre-C99 compiler with "inttypes.h"
+# -DHAVE_LINK=0 if your system lacks a link function
+# -DHAVE_LOCALTIME_R=0 if your system lacks a localtime_r function
+# -DHAVE_LOCALTIME_RZ=0 if you do not want zdump to use localtime_rz
+# This defaults to 1 if a working localtime_rz seems to be available.
+# localtime_rz can make zdump significantly faster, but is nonstandard.
+# -DHAVE_POSIX_DECLS=0 if your system's include files do not declare
+# functions like 'link' or variables like 'tzname' required by POSIX
+# -DHAVE_STDINT_H=1 if you have a pre-C99 compiler with "stdint.h"
+# -DHAVE_STRFTIME_L=1 if <time.h> declares locale_t and strftime_l
+# This defaults to 0 if _POSIX_VERSION < 200809, 1 otherwise.
+# -DHAVE_STRDUP=0 if your system lacks the strdup function
+# -DHAVE_SYMLINK=0 if your system lacks the symlink function
+# -DHAVE_SYS_STAT_H=0 if your compiler lacks a "sys/stat.h"
+# -DHAVE_SYS_WAIT_H=0 if your compiler lacks a "sys/wait.h"
+# -DHAVE_TZSET=0 if your system lacks a tzset function
+# -DHAVE_UNISTD_H=0 if your compiler lacks a "unistd.h" (Microsoft C++ 7?)
+# -DEPOCH_LOCAL=1 if the 'time' function returns local time not UT
+# -DEPOCH_OFFSET=N if the 'time' function returns a value N greater
+# than what POSIX specifies, assuming local time is UT.
+# For example, N is 252460800 on AmigaOS.
+# -DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU=1
+# if you do not want run time warnings about formats that may cause
+# year 2000 grief
+# -Dssize_t=long on ancient hosts that lack ssize_t
+# -DTHREAD_SAFE=1 to make localtime.c thread-safe, as POSIX requires;
+# not needed by the main-program tz code, which is single-threaded.
+# Append other compiler flags as needed, e.g., -pthread on GNU/Linux.
+# -Dtime_tz=\"T\" to use T as the time_t type, rather than the system time_t
+# -DTZ_DOMAIN=\"foo\" to use "foo" for gettext domain name; default is "tz"
+# -DTZ_DOMAINDIR=\"/path\" to use "/path" for gettext directory;
+# the default is system-supplied, typically "/usr/lib/locale"
+# -DTZDEFRULESTRING=\",date/time,date/time\" to default to the specified
+# DST transitions if the time zone files cannot be accessed
+# -DUNINIT_TRAP=1 if reading uninitialized storage can cause problems
+# other than simply getting garbage data
+# -DUSE_LTZ=0 to build zdump with the system time zone library
+# Also set TZDOBJS=zdump.o and CHECK_TIME_T_ALTERNATIVES= below.
+# -DZIC_MAX_ABBR_LEN_WO_WARN=3
+# (or some other number) to set the maximum time zone abbreviation length
+# that zic will accept without a warning (the default is 6)
+# $(GCC_DEBUG_FLAGS) if you are using recent GCC and want lots of checking
+GCC_DEBUG_FLAGS = -Dlint -g3 -O3 -fno-common -fstrict-aliasing \
+ -Wall -Wextra \
+ -Wbad-function-cast -Wcast-align -Wdate-time \
+ -Wdeclaration-after-statement \
+ -Wdouble-promotion \
+ -Wformat=2 -Winit-self -Wjump-misses-init \
+ -Wlogical-op -Wmissing-prototypes -Wnested-externs \
+ -Wold-style-definition -Woverlength-strings -Wpointer-arith \
+ -Wshadow -Wstrict-prototypes -Wsuggest-attribute=const \
+ -Wsuggest-attribute=format -Wsuggest-attribute=noreturn \
+ -Wsuggest-attribute=pure -Wtrampolines \
+ -Wunused -Wwrite-strings \
+ -Wno-address -Wno-format-nonliteral -Wno-sign-compare \
+ -Wno-type-limits -Wno-unused-parameter
+#
+# If you want to use System V compatibility code, add
+# -DUSG_COMPAT
+# to the end of the "CFLAGS=" line. This arrange for "timezone" and "daylight"
+# variables to be kept up-to-date by the time conversion functions. Neither
+# "timezone" nor "daylight" is described in X3J11's work.
+#
+# If your system has a "GMT offset" field in its "struct tm"s
+# (or if you decide to add such a field in your system's "time.h" file),
+# add the name to a define such as
+# -DTM_GMTOFF=tm_gmtoff
+# to the end of the "CFLAGS=" line. If not defined, the code attempts to
+# guess TM_GMTOFF from other macros; define NO_TM_GMTOFF to suppress this.
+# Similarly, if your system has a "zone abbreviation" field, define
+# -DTM_ZONE=tm_zone
+# and define NO_TM_ZONE to suppress any guessing. These two fields are not
+# required by POSIX, but are widely available on GNU/Linux and BSD systems.
+#
+# If you want functions that were inspired by early versions of X3J11's work,
+# add
+# -DSTD_INSPIRED
+# to the end of the "CFLAGS=" line. This arranges for the functions
+# "tzsetwall", "offtime", "timelocal", "timegm", "timeoff",
+# "posix2time", and "time2posix" to be added to the time conversion library.
+# "tzsetwall" is like "tzset" except that it arranges for local wall clock
+# time (rather than the time specified in the TZ environment variable)
+# to be used.
+# "offtime" is like "gmtime" except that it accepts a second (long) argument
+# that gives an offset to add to the time_t when converting it.
+# "timelocal" is equivalent to "mktime".
+# "timegm" is like "timelocal" except that it turns a struct tm into
+# a time_t using UT (rather than local time as "timelocal" does).
+# "timeoff" is like "timegm" except that it accepts a second (long) argument
+# that gives an offset to use when converting to a time_t.
+# "posix2time" and "time2posix" are described in an included manual page.
+# X3J11's work does not describe any of these functions.
+# Sun has provided "tzsetwall", "timelocal", and "timegm" in SunOS 4.0.
+# These functions may well disappear in future releases of the time
+# conversion package.
+#
+# If you don't want functions that were inspired by NetBSD, add
+# -DNETBSD_INSPIRED=0
+# to the end of the "CFLAGS=" line. Otherwise, the functions
+# "localtime_rz", "mktime_z", "tzalloc", and "tzfree" are added to the
+# time library, and if STD_INSPIRED is also defined the functions
+# "posix2time_z" and "time2posix_z" are added as well.
+# The functions ending in "_z" (or "_rz") are like their unsuffixed
+# (or suffixed-by-"_r") counterparts, except with an extra first
+# argument of opaque type timezone_t that specifies the time zone.
+# "tzalloc" allocates a timezone_t value, and "tzfree" frees it.
+#
+# If you want to allocate state structures in localtime, add
+# -DALL_STATE
+# to the end of the "CFLAGS=" line. Storage is obtained by calling malloc.
+#
+# If you want an "altzone" variable (a la System V Release 3.1), add
+# -DALTZONE
+# to the end of the "CFLAGS=" line.
+# This variable is not described in X3J11's work.
+#
+# NIST-PCTS:151-2, Version 1.4, (1993-12-03) is a test suite put
+# out by the National Institute of Standards and Technology
+# which claims to test C and Posix conformance. If you want to pass PCTS, add
+# -DPCTS
+# to the end of the "CFLAGS=" line.
+#
+# If you want strict compliance with XPG4 as of 1994-04-09, add
+# -DXPG4_1994_04_09
+# to the end of the "CFLAGS=" line. This causes "strftime" to always return
+# 53 as a week number (rather than 52 or 53) for those days in January that
+# before the first Monday in January when a "%V" format is used and January 1
+# falls on a Friday, Saturday, or Sunday.
+
+CFLAGS=
+
+# Linker flags. Default to $(LFLAGS) for backwards compatibility
+# to release 2012h and earlier.
+
+LDFLAGS= $(LFLAGS)
+
+# For leap seconds, this Makefile uses LEAPSECONDS='-L leapseconds' in
+# submake command lines. The default is no leap seconds.
+
+LEAPSECONDS=
+
+# The zic command and its arguments.
+
+zic= ./zic
+ZIC= $(zic) $(ZFLAGS)
+
+ZFLAGS=
+
+# How to use zic to install tz binary files.
+
+ZIC_INSTALL= $(ZIC) -y $(YEARISTYPE) -d $(DESTDIR)$(TZDIR) $(LEAPSECONDS)
+
+# The name of a Posix-compliant 'awk' on your system.
+AWK= awk
+
+# The full path name of a Posix-compliant shell, preferably one that supports
+# the Korn shell's 'select' statement as an extension.
+# These days, Bash is the most popular.
+# It should be OK to set this to /bin/sh, on platforms where /bin/sh
+# lacks 'select' or doesn't completely conform to Posix, but /bin/bash
+# is typically nicer if it works.
+KSHELL= /bin/bash
+
+# The path where SGML DTDs are kept and the catalog file(s) to use when
+# validating. The default should work on both Debian and Red Hat.
+SGML_TOPDIR= /usr
+SGML_DTDDIR= $(SGML_TOPDIR)/share/xml/w3c-sgml-lib/schema/dtd
+SGML_SEARCH_PATH= $(SGML_DTDDIR)/REC-html401-19991224
+SGML_CATALOG_FILES= \
+ $(SGML_TOPDIR)/share/doc/w3-recs/html/www.w3.org/TR/1999/REC-html401-19991224/HTML4.cat:$(SGML_TOPDIR)/share/sgml/html/4.01/HTML4.cat
+
+# The name, arguments and environment of a program to validate your web pages.
+# See <http://openjade.sourceforge.net/doc/> for a validator, and
+# <https://validator.w3.org/source/> for a validation library.
+VALIDATE = nsgmls
+VALIDATE_FLAGS = -s -B -wall -wno-unused-param
+VALIDATE_ENV = \
+ SGML_CATALOG_FILES=$(SGML_CATALOG_FILES) \
+ SGML_SEARCH_PATH=$(SGML_SEARCH_PATH) \
+ SP_CHARSET_FIXED=YES \
+ SP_ENCODING=UTF-8
+
+# This expensive test requires USE_LTZ.
+# To suppress it, define this macro to be empty.
+CHECK_TIME_T_ALTERNATIVES = check_time_t_alternatives
+
+# SAFE_CHAR is a regular expression that matches a safe character.
+# Some parts of this distribution are limited to safe characters;
+# others can use any UTF-8 character.
+# For now, the safe characters are a safe subset of ASCII.
+# The caller must set the shell variable 'sharp' to the character '#',
+# since Makefile macros cannot contain '#'.
+# TAB_CHAR is a single tab character, in single quotes.
+TAB_CHAR= ' '
+SAFE_CHARSET1= $(TAB_CHAR)' !\"'$$sharp'$$%&'\''()*+,./0123456789:;<=>?@'
+SAFE_CHARSET2= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\^_`'
+SAFE_CHARSET3= 'abcdefghijklmnopqrstuvwxyz{|}~'
+SAFE_CHARSET= $(SAFE_CHARSET1)$(SAFE_CHARSET2)$(SAFE_CHARSET3)
+SAFE_CHAR= '[]'$(SAFE_CHARSET)'-]'
+
+# OK_CHAR matches any character allowed in the distributed files.
+# This is the same as SAFE_CHAR, except that multibyte letters are
+# also allowed so that commentary can contain people's names and quote
+# non-English sources. For non-letters the sources are limited to
+# ASCII renderings for the convenience of maintainers whose text editors
+# mishandle UTF-8 by default (e.g., XEmacs 21.4.22).
+OK_CHAR= '[][:alpha:]'$(SAFE_CHARSET)'-]'
+
+# SAFE_LINE matches a line of safe characters.
+# SAFE_SHARP_LINE is similar, except any OK character can follow '#';
+# this is so that comments can contain non-ASCII characters.
+# OK_LINE matches a line of OK characters.
+SAFE_LINE= '^'$(SAFE_CHAR)'*$$'
+SAFE_SHARP_LINE='^'$(SAFE_CHAR)'*('$$sharp$(OK_CHAR)'*)?$$'
+OK_LINE= '^'$(OK_CHAR)'*$$'
+
+# Flags to give 'tar' when making a distribution.
+# Try to use flags appropriate for GNU tar.
+GNUTARFLAGS= --numeric-owner --owner=0 --group=0 --mode=go+u,go-w --sort=name
+TARFLAGS= `if tar $(GNUTARFLAGS) --version >/dev/null 2>&1; \
+ then echo $(GNUTARFLAGS); \
+ else :; \
+ fi`
+
+# Flags to give 'gzip' when making a distribution.
+GZIPFLAGS= -9n
+
+###############################################################################
+
+#MAKE= make
+
+cc= cc
+CC= $(cc) -DTZDIR=\"$(TZDIR)\"
+
+AR= ar
+
+# ':' on typical hosts; 'ranlib' on the ancient hosts that still need ranlib.
+RANLIB= :
+
+TZCOBJS= zic.o
+TZDOBJS= zdump.o localtime.o asctime.o
+DATEOBJS= date.o localtime.o strftime.o asctime.o
+LIBSRCS= localtime.c asctime.c difftime.c
+LIBOBJS= localtime.o asctime.o difftime.o
+HEADERS= tzfile.h private.h
+NONLIBSRCS= zic.c zdump.c
+NEWUCBSRCS= date.c strftime.c
+SOURCES= $(HEADERS) $(LIBSRCS) $(NONLIBSRCS) $(NEWUCBSRCS) \
+ tzselect.ksh workman.sh
+MANS= newctime.3 newstrftime.3 newtzset.3 time2posix.3 \
+ tzfile.5 tzselect.8 zic.8 zdump.8
+MANTXTS= newctime.3.txt newstrftime.3.txt newtzset.3.txt \
+ time2posix.3.txt \
+ tzfile.5.txt tzselect.8.txt zic.8.txt zdump.8.txt \
+ date.1.txt
+COMMON= CONTRIBUTING LICENSE Makefile NEWS README Theory version
+WEB_PAGES= tz-art.htm tz-how-to.html tz-link.htm
+DOCS= $(MANS) date.1 $(MANTXTS) $(WEB_PAGES)
+PRIMARY_YDATA= africa antarctica asia australasia \
+ europe northamerica southamerica
+YDATA= $(PRIMARY_YDATA) pacificnew etcetera backward
+NDATA= systemv factory
+TDATA= $(YDATA) $(NDATA)
+ZONETABLES= zone1970.tab zone.tab
+TABDATA= iso3166.tab leapseconds $(ZONETABLES)
+LEAP_DEPS= leapseconds.awk leap-seconds.list
+DATA= $(YDATA) $(NDATA) backzone $(TABDATA) \
+ leap-seconds.list yearistype.sh
+AWK_SCRIPTS= checklinks.awk checktab.awk leapseconds.awk
+MISC= $(AWK_SCRIPTS) zoneinfo2tdf.pl
+TZS_YEAR= 2050
+TZS= to$(TZS_YEAR).tzs
+TZS_NEW= to$(TZS_YEAR)new.tzs
+TZS_DEPS= $(PRIMARY_YDATA) asctime.c localtime.c \
+ private.h tzfile.h zdump.c zic.c
+ENCHILADA= $(COMMON) $(DOCS) $(SOURCES) $(DATA) $(MISC) $(TZS)
+
+# Consult these files when deciding whether to rebuild the 'version' file.
+# This list is not the same as the output of 'git ls-files', since
+# .gitignore is not distributed.
+VERSION_DEPS= \
+ CONTRIBUTING LICENSE Makefile NEWS README Theory \
+ africa antarctica asctime.c asia australasia \
+ backward backzone \
+ checklinks.awk checktab.awk \
+ date.1 date.c difftime.c \
+ etcetera europe factory iso3166.tab \
+ leap-seconds.list leapseconds.awk localtime.c \
+ newctime.3 newstrftime.3 newtzset.3 northamerica \
+ pacificnew private.h \
+ southamerica strftime.c systemv \
+ time2posix.3 tz-art.htm tz-how-to.html tz-link.htm \
+ tzfile.5 tzfile.h tzselect.8 tzselect.ksh \
+ workman.sh yearistype.sh \
+ zdump.8 zdump.c zic.8 zic.c \
+ zone.tab zone1970.tab zoneinfo2tdf.pl
+
+# And for the benefit of csh users on systems that assume the user
+# shell should be used to handle commands in Makefiles. . .
+
+SHELL= /bin/sh
+
+all: tzselect yearistype zic zdump libtz.a $(TABDATA)
+
+ALL: all date $(ENCHILADA)
+
+install: all $(DATA) $(REDO) $(MANS)
+ mkdir -p $(DESTDIR)$(ETCDIR) $(DESTDIR)$(TZDIR) \
+ $(DESTDIR)$(LIBDIR) \
+ $(DESTDIR)$(MANDIR)/man3 $(DESTDIR)$(MANDIR)/man5 \
+ $(DESTDIR)$(MANDIR)/man8
+ $(ZIC_INSTALL) -l $(LOCALTIME) -p $(POSIXRULES)
+ cp -f iso3166.tab $(ZONETABLES) $(DESTDIR)$(TZDIR)/.
+ cp tzselect zic zdump $(DESTDIR)$(ETCDIR)/.
+ cp libtz.a $(DESTDIR)$(LIBDIR)/.
+ $(RANLIB) $(DESTDIR)$(LIBDIR)/libtz.a
+ cp -f newctime.3 newtzset.3 $(DESTDIR)$(MANDIR)/man3/.
+ cp -f tzfile.5 $(DESTDIR)$(MANDIR)/man5/.
+ cp -f tzselect.8 zdump.8 zic.8 $(DESTDIR)$(MANDIR)/man8/.
+
+INSTALL: ALL install date.1
+ mkdir -p $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man1
+ cp date $(DESTDIR)$(BINDIR)/.
+ cp -f date.1 $(DESTDIR)$(MANDIR)/man1/.
+
+version: $(VERSION_DEPS)
+ { (type git) >/dev/null 2>&1 && \
+ V=`git describe --match '[0-9][0-9][0-9][0-9][a-z]*' \
+ --abbrev=7 --dirty` || \
+ V=$(VERSION); } && \
+ printf '%s\n' "$$V" >$@.out
+ mv $@.out $@
+
+version.h: version
+ VERSION=`cat version` && printf '%s\n' \
+ 'static char const PKGVERSION[]="($(PACKAGE)) ";' \
+ "static char const TZVERSION[]=\"$$VERSION\";" \
+ 'static char const REPORT_BUGS_TO[]="$(BUGEMAIL)";' \
+ >$@.out
+ mv $@.out $@
+
+zdump: $(TZDOBJS)
+ $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(TZDOBJS) $(LDLIBS)
+
+zic: $(TZCOBJS)
+ $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(TZCOBJS) $(LDLIBS)
+
+yearistype: yearistype.sh
+ cp yearistype.sh yearistype
+ chmod +x yearistype
+
+leapseconds: $(LEAP_DEPS)
+ $(AWK) -f leapseconds.awk leap-seconds.list >$@.out
+ mv $@.out $@
+
+# Arguments to pass to submakes of install_data.
+# They can be overridden by later submake arguments.
+INSTALLARGS = \
+ DESTDIR=$(DESTDIR) \
+ LEAPSECONDS='$(LEAPSECONDS)' \
+ PACKRATDATA='$(PACKRATDATA)' \
+ TZDIR=$(TZDIR) \
+ YEARISTYPE=$(YEARISTYPE) \
+ ZIC='$(ZIC)'
+
+# 'make install_data' installs one set of tz binary files.
+# It can be tailored by setting LEAPSECONDS, PACKRATDATA, etc.
+install_data: zic leapseconds yearistype $(PACKRATDATA) $(TDATA)
+ $(ZIC_INSTALL) $(TDATA)
+ $(AWK) '/^Rule/' $(TDATA) | $(ZIC_INSTALL) - $(PACKRATDATA)
+
+posix_only:
+ $(MAKE) $(INSTALLARGS) LEAPSECONDS= install_data
+
+right_only:
+ $(MAKE) $(INSTALLARGS) LEAPSECONDS='-L leapseconds' \
+ install_data
+
+# In earlier versions of this makefile, the other two directories were
+# subdirectories of $(TZDIR). However, this led to configuration errors.
+# For example, with posix_right under the earlier scheme,
+# TZ='right/Australia/Adelaide' got you localtime with leap seconds,
+# but gmtime without leap seconds, which led to problems with applications
+# like sendmail that subtract gmtime from localtime.
+# Therefore, the other two directories are now siblings of $(TZDIR).
+# You must replace all of $(TZDIR) to switch from not using leap seconds
+# to using them, or vice versa.
+right_posix: right_only
+ rm -fr $(DESTDIR)$(TZDIR)-leaps
+ ln -s $(TZDIR_BASENAME) $(DESTDIR)$(TZDIR)-leaps || \
+ $(MAKE) $(INSTALLARGS) TZDIR=$(TZDIR)-leaps right_only
+ $(MAKE) $(INSTALLARGS) TZDIR=$(TZDIR)-posix posix_only
+
+posix_right: posix_only
+ rm -fr $(DESTDIR)$(TZDIR)-posix
+ ln -s $(TZDIR_BASENAME) $(DESTDIR)$(TZDIR)-posix || \
+ $(MAKE) $(INSTALLARGS) TZDIR=$(TZDIR)-posix posix_only
+ $(MAKE) $(INSTALLARGS) TZDIR=$(TZDIR)-leaps right_only
+
+# This obsolescent rule is present for backwards compatibility with
+# tz releases 2014g through 2015g. It should go away eventually.
+posix_packrat:
+ $(MAKE) $(INSTALLARGS) PACKRATDATA=backzone posix_only
+
+zones: $(REDO)
+
+$(TZS_NEW): $(TDATA) zdump zic
+ mkdir -p tzs.dir
+ $(zic) -d tzs.dir $(TDATA)
+ $(AWK) '/^Link/{print $$1 "\t" $$2 "\t" $$3}' \
+ $(TDATA) | LC_ALL=C sort >$@.out
+ wd=`pwd` && \
+ zones=`$(AWK) -v wd="$$wd" \
+ '/^Zone/{print wd "/tzs.dir/" $$2}' $(TDATA) \
+ | LC_ALL=C sort` && \
+ ./zdump -i -c $(TZS_YEAR) $$zones >>$@.out
+ sed 's,^TZ=".*tzs\.dir/,TZ=",' $@.out >$@.sed.out
+ rm -fr tzs.dir $@.out
+ mv $@.sed.out $@
+
+# If $(TZS) does not already exist (e.g., old-format tarballs), create it.
+# If it exists but 'make check_tzs' fails, a maintainer should inspect the
+# failed output and fix the inconsistency, perhaps by running 'make force_tzs'.
+$(TZS):
+ $(MAKE) force_tzs
+
+force_tzs: $(TZS_NEW)
+ cp $(TZS_NEW) $(TZS)
+
+libtz.a: $(LIBOBJS)
+ $(AR) ru $@ $(LIBOBJS)
+ $(RANLIB) $@
+
+date: $(DATEOBJS)
+ $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(DATEOBJS) $(LDLIBS)
+
+tzselect: tzselect.ksh version
+ VERSION=`cat version` && sed \
+ -e 's|#!/bin/bash|#!$(KSHELL)|g' \
+ -e 's|AWK=[^}]*|AWK=$(AWK)|g' \
+ -e 's|\(PKGVERSION\)=.*|\1='\''($(PACKAGE)) '\''|' \
+ -e 's|\(REPORT_BUGS_TO\)=.*|\1=$(BUGEMAIL)|' \
+ -e 's|TZDIR=[^}]*|TZDIR=$(TZDIR)|' \
+ -e 's|\(TZVERSION\)=.*|\1='"$$VERSION"'|' \
+ <$@.ksh >$@.out
+ chmod +x $@.out
+ mv $@.out $@
+
+check: check_character_set check_white_space check_links check_sorted \
+ check_tables check_tzs check_web
+
+check_character_set: $(ENCHILADA)
+ LC_ALL=en_US.utf8 && export LC_ALL && \
+ sharp='#' && \
+ ! grep -Env $(SAFE_LINE) $(MANS) date.1 $(MANTXTS) \
+ $(MISC) $(SOURCES) $(WEB_PAGES) \
+ CONTRIBUTING LICENSE Makefile README version && \
+ ! grep -Env $(SAFE_SHARP_LINE) $(TDATA) backzone \
+ leapseconds yearistype.sh zone.tab && \
+ ! grep -Env $(OK_LINE) $(ENCHILADA)
+
+check_white_space: $(ENCHILADA)
+ patfmt=' \t|[\f\r\v]' && pat=`printf "$$patfmt\\n"` && \
+ ! grep -En "$$pat" $(ENCHILADA)
+ ! grep -n '[[:space:]]$$' $(ENCHILADA)
+
+CHECK_CC_LIST = { n = split($$1,a,/,/); for (i=2; i<=n; i++) print a[1], a[i]; }
+
+check_sorted: backward backzone iso3166.tab zone.tab zone1970.tab
+ $(AWK) '/^Link/ {print $$3}' backward | LC_ALL=C sort -cu
+ $(AWK) '/^Zone/ {print $$2}' backzone | LC_ALL=C sort -cu
+ $(AWK) '/^[^#]/ {print $$1}' iso3166.tab | LC_ALL=C sort -cu
+ $(AWK) '/^[^#]/ {print $$1}' zone.tab | LC_ALL=C sort -c
+ $(AWK) '/^[^#]/ {print substr($$0, 1, 2)}' zone1970.tab | \
+ LC_ALL=C sort -c
+ $(AWK) '/^[^#]/ $(CHECK_CC_LIST)' zone1970.tab | \
+ LC_ALL=C sort -cu
+
+check_links: checklinks.awk $(TDATA)
+ $(AWK) -f checklinks.awk $(TDATA)
+
+check_tables: checktab.awk $(PRIMARY_YDATA) $(ZONETABLES)
+ for tab in $(ZONETABLES); do \
+ $(AWK) -f checktab.awk -v zone_table=$$tab $(PRIMARY_YDATA) \
+ || exit; \
+ done
+
+check_tzs: $(TZS) $(TZS_NEW)
+ diff -u $(TZS) $(TZS_NEW)
+
+check_web: $(WEB_PAGES)
+ $(VALIDATE_ENV) $(VALIDATE) $(VALIDATE_FLAGS) $(WEB_PAGES)
+
+clean_misc:
+ rm -f core *.o *.out \
+ date tzselect version.h zdump zic yearistype libtz.a
+clean: clean_misc
+ rm -fr *.dir tzdb-*/ $(TZS_NEW)
+
+maintainer-clean: clean
+ @echo 'This command is intended for maintainers to use; it'
+ @echo 'deletes files that may need special tools to rebuild.'
+ rm -f leapseconds version $(MANTXTS) $(TZS) *.asc *.tar.*
+
+names:
+ @echo $(ENCHILADA)
+
+public: check check_public $(CHECK_TIME_T_ALTERNATIVES) \
+ tarballs signatures
+
+date.1.txt: date.1
+newctime.3.txt: newctime.3
+newstrftime.3.txt: newstrftime.3
+newtzset.3.txt: newtzset.3
+time2posix.3.txt: time2posix.3
+tzfile.5.txt: tzfile.5
+tzselect.8.txt: tzselect.8
+zdump.8.txt: zdump.8
+zic.8.txt: zic.8
+
+$(MANTXTS): workman.sh
+ LC_ALL=C sh workman.sh `expr $@ : '\(.*\)\.txt$$'` >$@.out
+ mv $@.out $@
+
+# Set the time stamps to those of the git repository, if available,
+# and if the files have not changed since then.
+# This uses GNU 'touch' syntax 'touch -d@N FILE',
+# where N is the number of seconds since 1970.
+# If git or GNU 'touch' is absent, don't bother to sync with git timestamps.
+# Also, set the timestamp of each prebuilt file like 'leapseconds'
+# to be the maximum of the files it depends on.
+set-timestamps.out: $(ENCHILADA)
+ rm -f $@
+ if (type git) >/dev/null 2>&1 && \
+ files=`git ls-files $(ENCHILADA)` && \
+ touch -md @1 test.out; then \
+ rm -f test.out && \
+ for file in $$files; do \
+ if git diff --quiet $$file; then \
+ time=`git log -1 --format='tformat:%ct' $$file` && \
+ touch -cmd @$$time $$file; \
+ else \
+ echo >&2 "$$file: warning: does not match repository"; \
+ fi || exit; \
+ done; \
+ fi
+ touch -cmr `ls -t $(LEAP_DEPS) | sed 1q` leapseconds
+ for file in `ls $(MANTXTS) | sed 's/\.txt$$//'`; do \
+ touch -cmr `ls -t $$file workman.sh | sed 1q` $$file.txt || \
+ exit; \
+ done
+ touch -cmr `ls -t $(TZS_DEPS) | sed 1q` $(TZS)
+ touch -cmr `ls -t $(VERSION_DEPS) | sed 1q` version
+ touch $@
+
+# The zics below ensure that each data file can stand on its own.
+# We also do an all-files run to catch links to links.
+
+check_public:
+ $(MAKE) maintainer-clean
+ $(MAKE) "CFLAGS=$(GCC_DEBUG_FLAGS)" ALL
+ mkdir -p public.dir
+ for i in $(TDATA) ; do \
+ $(zic) -v -d public.dir $$i 2>&1 || exit; \
+ done
+ $(zic) -v -d public.dir $(TDATA)
+ rm -fr public.dir
+
+# Check that the code works under various alternative
+# implementations of time_t.
+check_time_t_alternatives:
+ if diff -q Makefile Makefile 2>/dev/null; then \
+ quiet_option='-q'; \
+ else \
+ quiet_option=''; \
+ fi && \
+ wd=`pwd` && \
+ zones=`$(AWK) '/^[^#]/ { print $$3 }' <zone1970.tab` && \
+ for type in $(TIME_T_ALTERNATIVES); do \
+ mkdir -p time_t.dir/$$type && \
+ $(MAKE) clean_misc && \
+ $(MAKE) TOPDIR="$$wd/time_t.dir/$$type" \
+ CFLAGS='$(CFLAGS) -Dtime_tz='"'$$type'" \
+ REDO='$(REDO)' \
+ install && \
+ diff $$quiet_option -r \
+ time_t.dir/int64_t/etc/zoneinfo \
+ time_t.dir/$$type/etc/zoneinfo && \
+ case $$type in \
+ int32_t) range=-2147483648,2147483647;; \
+ uint32_t) range=0,4294967296;; \
+ int64_t) continue;; \
+ *u*) range=0,10000000000;; \
+ *) range=-10000000000,10000000000;; \
+ esac && \
+ echo checking $$type zones ... && \
+ time_t.dir/int64_t/etc/zdump -V -t $$range $$zones \
+ >time_t.dir/int64_t.out && \
+ time_t.dir/$$type/etc/zdump -V -t $$range $$zones \
+ >time_t.dir/$$type.out && \
+ diff -u time_t.dir/int64_t.out time_t.dir/$$type.out \
+ || exit; \
+ done
+ rm -fr time_t.dir
+
+tarballs traditional_tarballs signatures traditional_signatures: version
+ VERSION=`cat version` && \
+ $(MAKE) VERSION="$$VERSION" $@_version
+
+tarballs_version: traditional_tarballs_version tzdb-$(VERSION).tar.lz
+traditional_tarballs_version: \
+ tzcode$(VERSION).tar.gz tzdata$(VERSION).tar.gz
+signatures_version: traditional_signatures_version tzdb-$(VERSION).tar.lz.asc
+traditional_signatures_version: \
+ tzcode$(VERSION).tar.gz.asc tzdata$(VERSION).tar.gz.asc \
+
+tzcode$(VERSION).tar.gz: set-timestamps.out
+ LC_ALL=C && export LC_ALL && \
+ tar $(TARFLAGS) -cf - \
+ $(COMMON) $(DOCS) $(SOURCES) | \
+ gzip $(GZIPFLAGS) >$@.out
+ mv $@.out $@
+
+tzdata$(VERSION).tar.gz: set-timestamps.out
+ LC_ALL=C && export LC_ALL && \
+ tar $(TARFLAGS) -cf - $(COMMON) $(DATA) $(MISC) | \
+ gzip $(GZIPFLAGS) >$@.out
+ mv $@.out $@
+
+tzdb-$(VERSION).tar.lz: set-timestamps.out
+ rm -fr tzdb-$(VERSION)
+ mkdir tzdb-$(VERSION)
+ ln $(ENCHILADA) tzdb-$(VERSION)
+ touch -cmr `ls -t tzdb-$(VERSION)/* | sed 1q` tzdb-$(VERSION)
+ LC_ALL=C && export LC_ALL && \
+ tar $(TARFLAGS) -cf - tzdb-$(VERSION) | lzip -9 >$@.out
+ mv $@.out $@
+
+tzcode$(VERSION).tar.gz.asc: tzcode$(VERSION).tar.gz
+ gpg --armor --detach-sign $?
+
+tzdata$(VERSION).tar.gz.asc: tzdata$(VERSION).tar.gz
+ gpg --armor --detach-sign $?
+
+tzdb-$(VERSION).tar.lz.asc: tzdb-$(VERSION).tar.lz
+ gpg --armor --detach-sign $?
+
+typecheck:
+ $(MAKE) clean
+ for i in "long long" unsigned; \
+ do \
+ $(MAKE) CFLAGS="-DTYPECHECK -D__time_t_defined -D_TIME_T \"-Dtime_t=$$i\"" ; \
+ ./zdump -v Europe/Rome ; \
+ $(MAKE) clean ; \
+ done
+
+zonenames: $(TDATA)
+ @$(AWK) '/^Zone/ { print $$2 } /^Link/ { print $$3 }' $(TDATA)
+
+asctime.o: private.h tzfile.h
+date.o: private.h
+difftime.o: private.h
+localtime.o: private.h tzfile.h
+strftime.o: private.h tzfile.h
+zdump.o: version.h
+zic.o: private.h tzfile.h version.h
+
+.KEEP_STATE:
+
+.PHONY: ALL INSTALL all
+.PHONY: check check_character_set check_links
+.PHONY: check_public check_sorted check_tables
+.PHONY: check_time_t_alternatives check_tzs check_web check_white_space
+.PHONY: clean clean_misc force_tzs
+.PHONY: install install_data maintainer-clean names
+.PHONY: posix_only posix_packrat posix_right
+.PHONY: public right_only right_posix signatures signatures_version
+.PHONY: tarballs tarballs_version typecheck
+.PHONY: zonenames zones
diff --git a/contrib/tzdata/NEWS b/contrib/tzdata/NEWS
new file mode 100644
index 0000000..da5c2a5
--- /dev/null
+++ b/contrib/tzdata/NEWS
@@ -0,0 +1,3782 @@
+News for the tz database
+
+Release 2016i - 2016-11-01 23:19:52 -0700
+
+ Briefly: Cyprus split into two time zones on 2016-10-30, and Tonga
+ reintroduces DST on 2016-11-06.
+
+ Changes to future time stamps
+
+ Pacific/Tongatapu begins DST on 2016-11-06 at 02:00, ending on
+ 2017-01-15 at 03:00. Assume future observances in Tonga will be
+ from the first Sunday in November through the third Sunday in
+ January, like Fiji. (Thanks to Pulu ʻAnau.) Switch to numeric
+ time zone abbreviations for this zone.
+
+ Changes to past and future time stamps
+
+ Northern Cyprus is now +03 year round, causing a split in Cyprus
+ time zones starting 2016-10-30 at 04:00. This creates a zone
+ Asia/Famagusta. (Thanks to Even Scharning and Matt Johnson.)
+
+ Antarctica/Casey switched from +08 to +11 on 2016-10-22.
+ (Thanks to Steffen Thorsen.)
+
+ Changes to past time stamps
+
+ Several corrections were made for pre-1975 time stamps in Italy.
+ These affect Europe/Malta, Europe/Rome, Europe/San_Marino, and
+ Europe/Vatican.
+
+ First, the 1893-11-01 00:00 transition in Italy used the new UT
+ offset (+01), not the old (+00:49:56). (Thanks to Michael
+ Deckers.)
+
+ Second, rules for daylight saving in Italy were changed to agree
+ with Italy's National Institute of Metrological Research (INRiM)
+ except for 1944, as follows (thanks to Pierpaolo Bernardi, Brian
+ Inglis, and Michael Deckers):
+
+ The 1916-06-03 transition was at 24:00, not 00:00.
+
+ The 1916-10-01, 1919-10-05, and 1920-09-19 transitions were at
+ 00:00, not 01:00.
+
+ The 1917-09-30 and 1918-10-06 transitions were at 24:00, not
+ 01:00.
+
+ The 1944-09-17 transition was at 03:00, not 01:00. This
+ particular change is taken from Italian law as INRiM's table,
+ (which says 02:00) appears to have a typo here. Also, keep the
+ 1944-04-03 transition for Europe/Rome, as Rome was controlled by
+ Germany then.
+
+ The 1967-1970 and 1972-1974 fallback transitions were at 01:00,
+ not 00:00.
+
+ Changes to code
+
+ The code should now be buildable on AmigaOS merely by setting the
+ appropriate Makefile variables. (From a patch by Carsten Larsen.)
+
+
+Release 2016h - 2016-10-19 23:17:57 -0700
+
+ Changes to future time stamps
+
+ Asia/Gaza and Asia/Hebron end DST on 2016-10-29 at 01:00, not
+ 2016-10-21 at 00:00. (Thanks to Sharef Mustafa.) Predict that
+ future fall transitions will be on the last Saturday of October
+ at 01:00, which is consistent with predicted spring transitions
+ on the last Saturday of March. (Thanks to Tim Parenti.)
+
+ Changes to past time stamps
+
+ In Turkey, transitions in 1986-1990 were at 01:00 standard time
+ not at 02:00, and the spring 1994 transition was on March 20, not
+ March 27. (Thanks to Kıvanç Yazan.)
+
+ Changes to past and future time zone abbreviations
+
+ Asia/Colombo now uses numeric time zone abbreviations like "+0530"
+ instead of alphabetic ones like "IST" and "LKT". Various
+ English-language sources use "IST", "LKT" and "SLST", with no
+ working consensus. (Usage of "SLST" mentioned by Sadika
+ Sumanapala.)
+
+ Changes to code
+
+ zic no longer mishandles relativizing file names when creating
+ symbolic links like /etc/localtime, when these symbolic links
+ are outside the usual directory hierarchy. This fixes a bug
+ introduced in 2016g. (Problem reported by Andreas Stieger.)
+
+ Changes to build procedure
+
+ New rules 'traditional_tarballs' and 'traditional_signatures' for
+ building just the traditional-format distribution. (Requested by
+ Deborah Goldsmith.)
+
+ The file 'version' is now put into the tzdata tarball too.
+ (Requested by Howard Hinnant.)
+
+ Changes to documentation and commentary
+
+ The 'Theory' file now has a section on interface stability.
+ (Requested by Paul Koning.) It also mentions features like
+ tm_zone and localtime_rz that have long been supported by the
+ reference code.
+
+ tz-link.htm has improved coverage of time zone boundaries suitable
+ for geolocation. (Thanks to heads-ups from Evan Siroky and Matt
+ Johnson.)
+
+ The US commentary now mentions Allen and the "day of two noons".
+
+ The Fiji commentary mentions the government's 2016-10-03 press
+ release. (Thanks to Raymond Kumar.)
+
+
+Release 2016g - 2016-09-13 08:56:38 -0700
+
+ Changes to future time stamps
+
+ Turkey switched from EET/EEST (+02/+03) to permanent +03,
+ effective 2016-09-07. (Thanks to Burak AYDIN.) Use "+03" rather
+ than an invented abbreviation for the new time.
+
+ New leap second 2016-12-31 23:59:60 UTC as per IERS Bulletin C 52.
+ (Thanks to Tim Parenti.)
+
+ Changes to past time stamps
+
+ For America/Los_Angeles, spring-forward transition times have been
+ corrected from 02:00 to 02:01 in 1948, and from 02:00 to 01:00 in
+ 1950-1966.
+
+ For zones using Soviet time on 1919-07-01, transitions to UT-based
+ time were at 00:00 UT, not at 02:00 local time. The affected
+ zones are Europe/Kirov, Europe/Moscow, Europe/Samara, and
+ Europe/Ulyanovsk. (Thanks to Alexander Belopolsky.)
+
+ Changes to past and future time zone abbreviations
+
+ The Factory zone now uses the time zone abbreviation -00 instead
+ of a long English-language string, as -00 is now the normal way to
+ represent an undefined time zone.
+
+ Several zones in Antarctica and the former Soviet Union, along
+ with zones intended for ships at sea that cannot use POSIX TZ
+ strings, now use numeric time zone abbreviations instead of
+ invented or obsolete alphanumeric abbreviations. The affected
+ zones are Antarctica/Casey, Antarctica/Davis,
+ Antarctica/DumontDUrville, Antarctica/Mawson, Antarctica/Rothera,
+ Antarctica/Syowa, Antarctica/Troll, Antarctica/Vostok,
+ Asia/Anadyr, Asia/Ashgabat, Asia/Baku, Asia/Bishkek, Asia/Chita,
+ Asia/Dushanbe, Asia/Irkutsk, Asia/Kamchatka, Asia/Khandyga,
+ Asia/Krasnoyarsk, Asia/Magadan, Asia/Omsk, Asia/Sakhalin,
+ Asia/Samarkand, Asia/Srednekolymsk, Asia/Tashkent, Asia/Tbilisi,
+ Asia/Ust-Nera, Asia/Vladivostok, Asia/Yakutsk, Asia/Yekaterinburg,
+ Asia/Yerevan, Etc/GMT-14, Etc/GMT-13, Etc/GMT-12, Etc/GMT-11,
+ Etc/GMT-10, Etc/GMT-9, Etc/GMT-8, Etc/GMT-7, Etc/GMT-6, Etc/GMT-5,
+ Etc/GMT-4, Etc/GMT-3, Etc/GMT-2, Etc/GMT-1, Etc/GMT+1, Etc/GMT+2,
+ Etc/GMT+3, Etc/GMT+4, Etc/GMT+5, Etc/GMT+6, Etc/GMT+7, Etc/GMT+8,
+ Etc/GMT+9, Etc/GMT+10, Etc/GMT+11, Etc/GMT+12, Europe/Kaliningrad,
+ Europe/Minsk, Europe/Samara, Europe/Volgograd, and
+ Indian/Kerguelen. For Europe/Moscow the invented abbreviation MSM
+ was replaced by +05, whereas MSK and MSD were kept as they are not
+ our invention and are widely used.
+
+ Changes to zone names
+
+ Rename Asia/Rangoon to Asia/Yangon, with a backward compatibility link.
+ (Thanks to David Massoud.)
+
+ Changes to code
+
+ zic no longer generates binary files containing POSIX TZ-like
+ strings that disagree with the local time type after the last
+ explicit transition in the data. This fixes a bug with
+ Africa/Casablanca and Africa/El_Aaiun in some year-2037 time
+ stamps on the reference platform. (Thanks to Alexander Belopolsky
+ for reporting the bug and suggesting a way forward.)
+
+ If the installed localtime and/or posixrules files are symbolic
+ links, zic now keeps them symbolic links when updating them, for
+ compatibility with platforms like OpenSUSE where other programs
+ configure these files as symlinks.
+
+ zic now avoids hard linking to symbolic links, avoids some
+ unnecessary mkdir and stat system calls, and uses shorter file
+ names internally.
+
+ zdump has a new -i option to generate transitions in a
+ more-compact but still human-readable format. This option is
+ experimental, and the output format may change in future versions.
+ (Thanks to Jon Skeet for suggesting that an option was needed,
+ and thanks to Tim Parenti and Chris Rovick for further comments.)
+
+ Changes to build procedure
+
+ An experimental distribution format is available, in addition
+ to the traditional format which will continue to be distributed.
+ The new format is a tarball tzdb-VERSION.tar.lz with signature
+ file tzdb-VERSION.tar.lz.asc. It unpacks to a top-level directory
+ tzdb-VERSION containing the code and data of the traditional
+ two-tarball format, along with extra data that may be useful.
+ (Thanks to Antonio Diaz Diaz, Oscar van Vlijmen, and many others
+ for comments about the experimental format.)
+
+ The release version number is now more accurate in the usual case
+ where releases are built from a Git repository. For example, if
+ 23 commits and some working-file changes have been made since
+ release 2016g, the version number is now something like
+ '2016g-23-g50556e3-dirty' instead of the misleading '2016g'.
+ Official releases uses the same version number format as before,
+ e.g., '2016g'. To support the more-accurate version number, its
+ specification has moved from a line in the Makefile to a new
+ source file 'version'.
+
+ The experimental distribution contains a file to2050.tzs that
+ contains what should be the output of 'zdump -i -c 2050' on
+ primary zones. If this file is available, 'make check' now checks
+ that zdump generates this output.
+
+ 'make check_web' now works on Fedora-like distributions.
+
+ Changes to documentation and commentary
+
+ tzfile.5 now documents the new restriction on POSIX TZ-like
+ strings that is now implemented by zic.
+
+ Comments now cite URLs for some 1917-1921 Russian DST decrees.
+ (Thanks to Alexander Belopolsky.)
+
+ tz-link.htm mentions JuliaTime (thanks to Curtis Vogt) and Time4J
+ (thanks to Meno Hochschild) and ThreeTen-Extra, and its
+ description of Java 8 has been brought up to date (thanks to
+ Stephen Colebourne). Its description of local time on Mars has
+ been updated to match current practice, and URLs have been updated
+ and some obsolete ones removed.
+
+
+Release 2016f - 2016-07-05 16:26:51 +0200
+
+ Changes affecting future time stamps
+
+ The Egyptian government changed its mind on short notice, and
+ Africa/Cairo will not introduce DST starting 2016-07-07 after all.
+ (Thanks to Mina Samuel.)
+
+ Asia/Novosibirsk switches from +06 to +07 on 2016-07-24 at 02:00.
+ (Thanks to Stepan Golosunov.)
+
+ Changes to past and future time stamps
+
+ Asia/Novokuznetsk and Asia/Novosibirsk now use numeric time zone
+ abbreviations instead of invented ones.
+
+ Changes affecting past time stamps
+
+ Europe/Minsk's 1992-03-29 spring-forward transition was at 02:00 not 00:00.
+ (Thanks to Stepan Golosunov.)
+
+
+Release 2016e - 2016-06-14 08:46:16 -0700
+
+ Changes affecting future time stamps
+
+ Africa/Cairo observes DST in 2016 from July 7 to the end of October.
+ Guess October 27 and 24:00 transitions. (Thanks to Steffen Thorsen.)
+ For future years, guess April's last Thursday to October's last
+ Thursday except for Ramadan.
+
+ Changes affecting past time stamps
+
+ Locations while uninhabited now use '-00', not 'zzz', as a
+ placeholder time zone abbreviation. This is inspired by Internet
+ RFC 3339 and is more consistent with numeric time zone
+ abbreviations already used elsewhere. The change affects several
+ arctic and antarctic locations, e.g., America/Cambridge_Bay before
+ 1920 and Antarctica/Troll before 2005.
+
+ Asia/Baku's 1992-09-27 transition from +04 (DST) to +04 (non-DST) was
+ at 03:00, not 23:00 the previous day. (Thanks to Michael Deckers.)
+
+ Changes to code
+
+ zic now outputs a dummy transition at time 2**31 - 1 in zones
+ whose POSIX-style TZ strings contain a '<'. This mostly works
+ around Qt bug 53071 <https://bugreports.qt.io/browse/QTBUG-53071>.
+ (Thanks to Zhanibek Adilbekov for reporting the Qt bug.)
+
+ Changes affecting documentation and commentary
+
+ tz-link.htm says why governments should give plenty of notice for
+ time zone or DST changes, and refers to Matt Johnson's blog post.
+
+ tz-link.htm mentions Tzdata for Elixir. (Thanks to Matt Johnson.)
+
+
+Release 2016d - 2016-04-17 22:50:29 -0700
+
+ Changes affecting future time stamps
+
+ America/Caracas switches from -0430 to -04 on 2016-05-01 at 02:30.
+ (Thanks to Alexander Krivenyshev for the heads-up.)
+
+ Asia/Magadan switches from +10 to +11 on 2016-04-24 at 02:00.
+ (Thanks to Alexander Krivenyshev and Matt Johnson.)
+
+ New zone Asia/Tomsk, split off from Asia/Novosibirsk. It covers
+ Tomsk Oblast, Russia, which switches from +06 to +07 on 2016-05-29
+ at 02:00. (Thanks to Stepan Golosunov.)
+
+ Changes affecting past time stamps
+
+ New zone Europe/Kirov, split off from Europe/Volgograd. It covers
+ Kirov Oblast, Russia, which switched from +04/+05 to +03/+04 on
+ 1989-03-26 at 02:00, roughly a year after Europe/Volgograd made
+ the same change. (Thanks to Stepan Golosunov.)
+
+ Russia and nearby locations had daylight-saving transitions on
+ 1992-03-29 at 02:00 and 1992-09-27 at 03:00, instead of on
+ 1992-03-28 at 23:00 and 1992-09-26 at 23:00. (Thanks to Stepan
+ Golosunov.)
+
+ Many corrections to historical time in Kazakhstan from 1991
+ through 2005. (Thanks to Stepan Golosunov.) Replace Kazakhstan's
+ invented time zone abbreviations with numeric abbreviations.
+
+ Changes to commentary
+
+ Mention Internet RFCs 7808 (TZDIST) and 7809 (CalDAV time zone references).
+
+
+Release 2016c - 2016-03-23 00:51:27 -0700
+
+ Changes affecting future time stamps
+
+ Azerbaijan no longer observes DST. (Thanks to Steffen Thorsen.)
+
+ Chile reverts from permanent to seasonal DST. (Thanks to Juan
+ Correa for the heads-up, and to Tim Parenti for corrections.)
+ Guess that future transitions are August's and May's second
+ Saturdays at 24:00 mainland time. Also, call the period from
+ 2014-09-07 through 2016-05-14 daylight saving time instead of
+ standard time, as that seems more appropriate now.
+
+ Changes affecting past time stamps
+
+ Europe/Kaliningrad and Europe/Vilnius changed from +03/+04 to
+ +02/+03 on 1989-03-26, not 1991-03-31. Europe/Volgograd changed
+ from +04/+05 to +03/+04 on 1988-03-27, not 1989-03-26.
+ (Thanks to Stepan Golosunov.)
+
+ Changes to commentary
+
+ Several updates and URLs for historical and proposed Russian changes.
+ (Thanks to Stepan Golosunov, Matt Johnson, and Alexander Krivenyshev.)
+
+
+Release 2016b - 2016-03-12 17:30:14 -0800
+
+ Compatibility note
+
+ Starting with release 2016b, some data entries cause zic implementations
+ derived from tz releases 2005j through 2015e to issue warnings like
+ "time zone abbreviation differs from POSIX standard (+03)".
+ These warnings should not otherwise affect zic's output and can safely be
+ ignored on today's platforms, as the warnings refer to a restriction in
+ POSIX.1-1988 that was removed in POSIX.1-2001. One way to suppress the
+ warnings is to upgrade to zic derived from tz releases 2015f and later.
+
+ Changes affecting future time stamps
+
+ New zones Europe/Astrakhan and Europe/Ulyanovsk for Astrakhan and
+ Ulyanovsk Oblasts, Russia, both of which will switch from +03 to +04 on
+ 2016-03-27 at 02:00 local time. They need distinct zones since their
+ post-1970 histories disagree. New zone Asia/Barnaul for Altai Krai and
+ Altai Republic, Russia, which will switch from +06 to +07 on the same date
+ and local time. The Astrakhan change is already official; the others have
+ passed the first reading in the State Duma and are extremely likely.
+ Also, Asia/Sakhalin moves from +10 to +11 on 2016-03-27 at 02:00.
+ (Thanks to Alexander Krivenyshev for the heads-up, and to Matt Johnson
+ and Stepan Golosunov for followup.)
+
+ As a trial of a new system that needs less information to be made up,
+ the new zones use numeric time zone abbreviations like "+04"
+ instead of invented abbreviations like "ASTT".
+
+ Haiti will not observe DST in 2016. (Thanks to Jean Antoine via
+ Steffen Thorsen.)
+
+ Palestine's spring-forward transition on 2016-03-26 is at 01:00, not 00:00.
+ (Thanks to Hannah Kreitem.) Guess future transitions will be March's last
+ Saturday at 01:00, not March's last Friday at 24:00.
+
+ Changes affecting past time stamps
+
+ Europe/Chisinau observed DST during 1990, and switched from +04 to
+ +03 at 1990-05-06 02:00, instead of switching from +03 to +02.
+ (Thanks to Stepan Golosunov.)
+
+ 1991 abbreviations in Europe/Samara should be SAMT/SAMST, not
+ KUYT/KUYST. (Thanks to Stepan Golosunov.)
+
+ Changes to code
+
+ tzselect's diagnostics and checking, and checktab.awk's checking,
+ have been improved. (Thanks to J William Piggott.)
+
+ tzcode now builds under MinGW. (Thanks to Ian Abbott and Esben Haabendal.)
+
+ tzselect now tests Julian-date TZ settings more accurately.
+ (Thanks to J William Piggott.)
+
+ Changes to commentary
+
+ Comments in zone tables have been improved. (Thanks to J William Piggott.)
+
+ tzselect again limits its menu comments so that menus fit on a
+ 24x80 alphanumeric display.
+
+ A new web page tz-how-to.html. (Thanks to Bill Seymour.)
+
+ In the Theory file, the description of possible time zone abbreviations in
+ tzdata has been cleaned up, as the old description was unclear and
+ inconsistent. (Thanks to Alain Mouette for reporting the problem.)
+
+
+Release 2016a - 2016-01-26 23:28:02 -0800
+
+ Changes affecting future time stamps
+
+ America/Cayman will not observe daylight saving this year after all.
+ Revert our guess that it would. (Thanks to Matt Johnson.)
+
+ Asia/Chita switches from +0800 to +0900 on 2016-03-27 at 02:00.
+ (Thanks to Alexander Krivenyshev.)
+
+ Asia/Tehran now has DST predictions for the year 2038 and later,
+ to be March 21 00:00 to September 21 00:00. This is likely better
+ than predicting no DST, albeit off by a day every now and then.
+
+ Changes affecting past and future time stamps
+
+ America/Metlakatla switched from PST all year to AKST/AKDT on
+ 2015-11-01 at 02:00. (Thanks to Steffen Thorsen.)
+
+ America/Santa_Isabel has been removed, and replaced with a
+ backward compatibility link to America/Tijuana. Its contents were
+ apparently based on a misreading of Mexican legislation.
+
+ Changes affecting past time stamps
+
+ Asia/Karachi's two transition times in 2002 were off by a minute.
+ (Thanks to Matt Johnson.)
+
+ Changes affecting build procedure
+
+ An installer can now combine leap seconds with use of the backzone file,
+ e.g., with 'make PACKRATDATA=backzone REDO=posix_right zones'.
+ The old 'make posix_packrat' rule is now marked as obsolescent.
+ (Thanks to Ian Abbott for an initial implementation.)
+
+ Changes affecting documentation and commentary
+
+ A new file LICENSE makes it easier to see that the code and data
+ are mostly public-domain. (Thanks to James Knight.) The three
+ non-public-domain files now use the current (3-clause) BSD license
+ instead of older versions of that license.
+
+ tz-link.htm mentions the BDE library (thanks to Andrew Paprocki),
+ CCTZ (thanks to Tim Parenti), TimeJones.com, and has a new section
+ on editing tz source files (with a mention of Sublime zoneinfo,
+ thanks to Gilmore Davidson).
+
+ The Theory and asia files now mention the 2015 book "The Global
+ Transformation of Time, 1870-1950", and cite a couple of reviews.
+
+ The America/Chicago entry now documents the informal use of US
+ central time in Fort Pierre, South Dakota. (Thanks to Rick
+ McDermid, Matt Johnson, and Steve Jones.)
+
+
+Release 2015g - 2015-10-01 00:39:51 -0700
+
+ Changes affecting future time stamps
+
+ Turkey's 2015 fall-back transition is scheduled for Nov. 8, not Oct. 25.
+ (Thanks to Fatih.)
+
+ Norfolk moves from +1130 to +1100 on 2015-10-04 at 02:00 local time.
+ (Thanks to Alexander Krivenyshev.)
+
+ Fiji's 2016 fall-back transition is scheduled for January 17, not 24.
+ (Thanks to Ken Rylander.)
+
+ Fort Nelson, British Columbia will not fall back on 2015-11-01. It has
+ effectively been on MST (-0700) since it advanced its clocks on 2015-03-08.
+ New zone America/Fort_Nelson. (Thanks to Matt Johnson.)
+
+ Changes affecting past time stamps
+
+ Norfolk observed DST from 1974-10-27 02:00 to 1975-03-02 02:00.
+
+ Changes affecting code
+
+ localtime no longer mishandles America/Anchorage after 2037.
+ (Thanks to Bradley White for reporting the bug.)
+
+ On hosts with signed 32-bit time_t, localtime no longer mishandles
+ Pacific/Fiji after 2038-01-16 14:00 UTC.
+
+ The localtime module allows the variables 'timezone', 'daylight',
+ and 'altzone' to be in common storage shared with other modules,
+ and declares them in case the system <time.h> does not.
+ (Problems reported by Kees Dekker.)
+
+ On platforms with tm_zone, strftime.c now assumes it is not NULL.
+ This simplifies the code and is consistent with zdump.c.
+ (Problem reported by Christos Zoulas.)
+
+ Changes affecting documentation
+
+ The tzfile man page now documents that transition times denote the
+ starts (not the ends) of the corresponding time periods.
+ (Ambiguity reported by Bill Seymour.)
+
+
+Release 2015f - 2015-08-10 18:06:56 -0700
+
+ Changes affecting future time stamps
+
+ North Korea switches to +0830 on 2015-08-15. (Thanks to Steffen Thorsen.)
+ The abbreviation remains "KST". (Thanks to Robert Elz.)
+
+ Uruguay no longer observes DST. (Thanks to Steffen Thorsen
+ and Pablo Camargo.)
+
+ Changes affecting past and future time stamps
+
+ Moldova starts and ends DST at 00:00 UTC, not at 01:00 UTC.
+ (Thanks to Roman Tudos.)
+
+ Changes affecting data format and code
+
+ zic's '-y YEARISTYPE' option is no longer documented. The TYPE
+ field of a Rule line should now be '-'; the old values 'even',
+ 'odd', 'uspres', 'nonpres', 'nonuspres' were already undocumented.
+ Although the implementation has not changed, these features do not
+ work in the default installation, they are not used in the data,
+ and they are now considered obsolescent.
+
+ zic now checks that two rules don't take effect at the same time.
+ (Thanks to Jon Skeet and Arthur David Olson.) Constraints on
+ simultaneity are now documented.
+
+ The two characters '%z' in a zone format now stand for the UTC
+ offset, e.g., '-07' for seven hours behind UTC and '+0530' for
+ five hours and thirty minutes ahead. This better supports time
+ zone abbreviations conforming to POSIX.1-2001 and later.
+
+ Changes affecting installed data files
+
+ Comments for America/Halifax and America/Glace_Bay have been improved.
+ (Thanks to Brian Inglis.)
+
+ Data entries have been simplified for Atlantic/Canary, Europe/Simferopol,
+ Europe/Sofia, and Europe/Tallinn. This yields slightly smaller
+ installed data files for Europe/Simferopol and Europe/Tallinn.
+ It does not affect timestamps. (Thanks to Howard Hinnant.)
+
+ Changes affecting code
+
+ zdump and zic no longer warn about valid time zone abbreviations
+ like '-05'.
+
+ Some Visual Studio 2013 warnings have been suppressed.
+ (Thanks to Kees Dekker.)
+
+ 'date' no longer sets the time of day and its -a, -d, -n and -t
+ options have been removed. Long obsolescent, the implementation
+ of these features had porting problems. Builders no longer need
+ to configure HAVE_ADJTIME, HAVE_SETTIMEOFDAY, or HAVE_UTMPX_H.
+ (Thanks to Kees Dekker for pointing out the problem.)
+
+ Changes affecting documentation
+
+ The Theory file mentions naming issues earlier, as these seem to be
+ poorly publicized (thanks to Gilmore Davidson for reporting the problem).
+
+ tz-link.htm mentions Time Zone Database Parser (thanks to Howard Hinnant).
+
+ Mention that Herbert Samuel introduced the term "Summer Time".
+
+
+Release 2015e - 2015-06-13 10:56:02 -0700
+
+ Changes affecting future time stamps
+
+ Morocco will suspend DST from 2015-06-14 03:00 through 2015-07-19 02:00,
+ not 06-13 and 07-18 as we had guessed. (Thanks to Milamber.)
+
+ Assume Cayman Islands will observe DST starting next year, using US rules.
+ Although it isn't guaranteed, it is the most likely.
+
+ Changes affecting data format
+
+ The file 'iso3166.tab' now uses UTF-8, so that its entries can better
+ spell the names of Åland Islands, Côte d'Ivoire, and Réunion.
+
+ Changes affecting code
+
+ When displaying data, tzselect converts it to the current locale's
+ encoding if the iconv command works. (Problem reported by random832.)
+
+ tzselect no longer mishandles Dominica, fixing a bug introduced
+ in Release 2014f. (Problem reported by Owen Leibman.)
+
+ zic -l no longer fails when compiled with -DTZDEFAULT=\"/etc/localtime\".
+ This fixes a bug introduced in Release 2014f.
+ (Problem reported by Leonardo Chiquitto.)
+
+
+Release 2015d - 2015-04-24 08:09:46 -0700
+
+ Changes affecting future time stamps
+
+ Egypt will not observe DST in 2015 and will consider canceling it
+ permanently. For now, assume no DST indefinitely.
+ (Thanks to Ahmed Nazmy and Tim Parenti.)
+
+ Changes affecting past time stamps
+
+ America/Whitehorse switched from UT -09 to -08 on 1967-05-28, not
+ 1966-07-01. Also, Yukon's time zone history is documented better.
+ (Thanks to Brian Inglis and Dennis Ferguson.)
+
+ Change affecting past and future time zone abbreviations
+
+ The abbreviations for Hawaii-Aleutian standard and daylight times
+ have been changed from HAST/HADT to HST/HDT, as per US Government
+ Printing Office style. This affects only America/Adak since 1983,
+ as America/Honolulu was already using the new style.
+
+ Changes affecting code
+
+ zic has some minor performance improvements.
+
+
+Release 2015c - 2015-04-11 08:55:55 -0700
+
+ Changes affecting future time stamps
+
+ Egypt's spring-forward transition is at 24:00 on April's last Thursday,
+ not 00:00 on April's last Friday. 2015's transition will therefore be on
+ Thursday, April 30 at 24:00, not Friday, April 24 at 00:00. Similar fixes
+ apply to 2026, 2037, 2043, etc. (Thanks to Steffen Thorsen.)
+
+ Changes affecting past time stamps
+
+ The following changes affect some pre-1991 Chile-related time stamps
+ in America/Santiago, Antarctica/Palmer, and Pacific/Easter.
+
+ The 1910 transition was January 10, not January 1.
+
+ The 1918 transition was September 10, not September 1.
+
+ The UT -04 time observed from 1932 to 1942 is now considered to
+ be standard time, not year-round DST.
+
+ Santiago observed DST (UT -03) from 1946-07-15 through
+ 1946-08-31, then reverted to standard time, then switched to -05
+ on 1947-04-01.
+
+ Assume transitions before 1968 were at 00:00, since we have no data
+ saying otherwise.
+
+ The spring 1988 transition was 1988-10-09, not 1988-10-02.
+ The fall 1990 transition was 1990-03-11, not 1990-03-18.
+
+ Assume no UTC offset change for Pacific/Easter on 1890-01-01,
+ and omit all transitions on Pacific/Easter from 1942 through 1946
+ since we have no data suggesting that they existed.
+
+ One more zone has been turned into a link, as it differed
+ from an existing zone only for older time stamps. As usual,
+ this change affects UTC offsets in pre-1970 time stamps only.
+ The zone's old contents have been moved to the 'backzone' file.
+ The affected zone is America/Montreal.
+
+ Changes affecting commentary
+
+ Mention the TZUpdater tool.
+
+ Mention "The Time Now". (Thanks to Brandon Ramsey.)
+
+
+Release 2015b - 2015-03-19 23:28:11 -0700
+
+ Changes affecting future time stamps
+
+ Mongolia will start observing DST again this year, from the last
+ Saturday in March at 02:00 to the last Saturday in September at 00:00.
+ (Thanks to Ganbold Tsagaankhuu.)
+
+ Palestine will start DST on March 28, not March 27. Also,
+ correct the fall 2014 transition from September 26 to October 24.
+ Adjust future predictions accordingly. (Thanks to Steffen Thorsen.)
+
+ Changes affecting past time stamps
+
+ The 1982 zone shift in Pacific/Easter has been corrected, fixing a 2015a
+ regression. (Thanks to Stuart Bishop for reporting the problem.)
+
+ Some more zones have been turned into links, when they differed
+ from existing zones only for older time stamps. As usual,
+ these changes affect UTC offsets in pre-1970 time stamps only.
+ Their old contents have been moved to the 'backzone' file.
+ The affected zones are: America/Antigua, America/Cayman,
+ Pacific/Midway, and Pacific/Saipan.
+
+ Changes affecting time zone abbreviations
+
+ Correct the 1992-2010 DST abbreviation in Volgograd from "MSK" to "MSD".
+ (Thanks to Hank W.)
+
+ Changes affecting code
+
+ Fix integer overflow bug in reference 'mktime' implementation.
+ (Problem reported by Jörg Richter.)
+
+ Allow -Dtime_tz=time_t compilations, and allow -Dtime_tz=... libraries
+ to be used in the same executable as standard-library time_t functions.
+ (Problems reported by Bradley White.)
+
+ Changes affecting commentary
+
+ Cite the recent Mexican decree changing Quintana Roo's time zone.
+ (Thanks to Carlos Raúl Perasso.)
+
+ Likewise for the recent Chilean decree. (Thanks to Eduardo Romero Urra.)
+
+ Update info about Mars time.
+
+
+Release 2015a - 2015-01-29 22:35:20 -0800
+
+ Changes affecting future time stamps
+
+ The Mexican state of Quintana Roo, represented by America/Cancun,
+ will shift from Central Time with DST to Eastern Time without DST
+ on 2015-02-01 at 02:00. (Thanks to Steffen Thorsen and Gwillim Law.)
+
+ Chile will not change clocks in April or thereafter; its new standard time
+ will be its old daylight saving time. This affects America/Santiago,
+ Pacific/Easter, and Antarctica/Palmer. (Thanks to Juan Correa.)
+
+ New leap second 2015-06-30 23:59:60 UTC as per IERS Bulletin C 49.
+ (Thanks to Tim Parenti.)
+
+ Changes affecting past time stamps
+
+ Iceland observed DST in 1919 and 1921, and its 1939 fallback
+ transition was Oct. 29, not Nov. 29. Remove incorrect data from
+ Shanks about time in Iceland between 1837 and 1908.
+
+ Some more zones have been turned into links, when they differed
+ from existing zones only for older time stamps. As usual,
+ these changes affect UTC offsets in pre-1970 time stamps only.
+ Their old contents have been moved to the 'backzone' file.
+ The affected zones are: Asia/Aden, Asia/Bahrain, Asia/Kuwait,
+ and Asia/Muscat.
+
+ Changes affecting code
+
+ tzalloc now scrubs time zone abbreviations compatibly with the way
+ that tzset always has, by replacing invalid bytes with '_' and by
+ shortening too-long abbreviations.
+
+ tzselect ports to POSIX awk implementations, no longer mishandles
+ POSIX TZ settings when GNU awk is used, and reports POSIX TZ
+ settings to the user. (Thanks to Stefan Kuhn.)
+
+ Changes affecting build procedure
+
+ 'make check' now checks for links to links in the data.
+ One such link (for Africa/Asmera) has been fixed.
+ (Thanks to Stephen Colebourne for pointing out the problem.)
+
+ Changes affecting commentary
+
+ The leapseconds file commentary now mentions the expiration date.
+ (Problem reported by Martin Burnicki.)
+
+ Update Mexican Library of Congress URL.
+
+
+Release 2014j - 2014-11-10 17:37:11 -0800
+
+ Changes affecting current and future time stamps
+
+ Turks & Caicos' switch from US eastern time to UT -04 year-round
+ did not occur on 2014-11-02 at 02:00. It's currently scheduled
+ for 2015-11-01 at 02:00. (Thanks to Chris Walton.)
+
+ Changes affecting past time stamps
+
+ Many pre-1989 time stamps have been corrected for Asia/Seoul and
+ Asia/Pyongyang, based on sources for the Korean-language Wikipedia
+ entry for time in Korea. (Thanks to Sanghyuk Jung.) Also, no
+ longer guess that Pyongyang mimicked Seoul time after World War II,
+ as this is politically implausible.
+
+ Some more zones have been turned into links, when they differed
+ from existing zones only for older time stamps. As usual,
+ these changes affect UTC offsets in pre-1970 time stamps only.
+ Their old contents have been moved to the 'backzone' file.
+ The affected zones are: Africa/Addis_Ababa, Africa/Asmara,
+ Africa/Dar_es_Salaam, Africa/Djibouti, Africa/Kampala,
+ Africa/Mogadishu, Indian/Antananarivo, Indian/Comoro, and
+ Indian/Mayotte.
+
+ Changes affecting commentary
+
+ The commentary is less enthusiastic about Shanks as a source,
+ and is more careful to distinguish UT from UTC.
+
+
+Release 2014i - 2014-10-21 22:04:57 -0700
+
+ Changes affecting future time stamps
+
+ Pacific/Fiji will observe DST from 2014-11-02 02:00 to 2015-01-18 03:00.
+ (Thanks to Ken Rylander for the heads-up.) Guess that future
+ years will use a similar pattern.
+
+ A new Zone Pacific/Bougainville, for the part of Papua New Guinea
+ that plans to switch from UT +10 to +11 on 2014-12-28 at 02:00.
+ (Thanks to Kiley Walbom for the heads-up.)
+
+ Changes affecting time zone abbreviations
+
+ Since Belarus is not changing its clocks even though Moscow is,
+ the time zone abbreviation in Europe/Minsk is changing from FET
+ to its more-traditional value MSK on 2014-10-26 at 01:00.
+ (Thanks to Alexander Bokovoy for the heads-up about Belarus.)
+
+ The new abbreviation IDT stands for the pre-1976 use of UT +08 in
+ Indochina, to distinguish it better from ICT (+07).
+
+ Changes affecting past time stamps
+
+ Many time stamps have been corrected for Asia/Ho_Chi_Minh before 1976
+ (thanks to Trần Ngọc Quân for an indirect pointer to Trần Tiến Bình's
+ authoritative book). Asia/Ho_Chi_Minh has been added to
+ zone1970.tab, to give tzselect users in Vietnam two choices,
+ since north and south Vietnam disagreed after our 1970 cutoff.
+
+ Asia/Phnom_Penh and Asia/Vientiane have been turned into links, as
+ they differed from existing zones only for older time stamps. As
+ usual, these changes affect pre-1970 time stamps only. Their old
+ contents have been moved to the 'backzone' file.
+
+ Changes affecting code
+
+ The time-related library functions now set errno on failure, and
+ some crashes in the new tzalloc-related library functions have
+ been fixed. (Thanks to Christos Zoulas for reporting most of
+ these problems and for suggesting fixes.)
+
+ If USG_COMPAT is defined and the requested time stamp is standard time,
+ the tz library's localtime and mktime functions now set the extern
+ variable timezone to a value appropriate for that time stamp; and
+ similarly for ALTZONE, daylight saving time, and the altzone variable.
+ This change is a companion to the tzname change in 2014h, and is
+ designed to make timezone and altzone more compatible with tzname.
+
+ The tz library's functions now set errno to EOVERFLOW if they fail
+ because the result cannot be represented. ctime and ctime_r now
+ return NULL and set errno when a time stamp is out of range, rather
+ than having undefined behavior.
+
+ Some bugs associated with the new 2014g functions have been fixed.
+ This includes a bug that largely incapacitated the new functions
+ time2posix_z and posix2time_z. (Thanks to Christos Zoulas.)
+ It also includes some uses of uninitialized variables after tzalloc.
+ The new code uses the standard type 'ssize_t', which the Makefile
+ now gives porting advice about.
+
+ Changes affecting commentary
+
+ Updated URLs for NRC Canada (thanks to Matt Johnson and Brian Inglis).
+
+
+Release 2014h - 2014-09-25 18:59:03 -0700
+
+ Changes affecting past time stamps
+
+ America/Jamaica's 1974 spring-forward transition was Jan. 6, not Apr. 28.
+
+ Shanks says Asia/Novokuznetsk switched from LMT (not "NMT") on 1924-05-01,
+ not 1920-01-06. The old entry was based on a misinterpretation of Shanks.
+
+ Some more zones have been turned into links, when they differed
+ from existing zones only for older time stamps. As usual,
+ these changes affect UTC offsets in pre-1970 time stamps only.
+ Their old contents have been moved to the 'backzone' file.
+ The affected zones are: Africa/Blantyre, Africa/Bujumbura,
+ Africa/Gaborone, Africa/Harare, Africa/Kigali, Africa/Lubumbashi,
+ Africa/Lusaka, Africa/Maseru, and Africa/Mbabane.
+
+ Changes affecting code
+
+ zdump -V and -v now output gmtoff= values on all platforms,
+ not merely on platforms defining TM_GMTOFF.
+
+ The tz library's localtime and mktime functions now set tzname to a value
+ appropriate for the requested time stamp, and zdump now uses this
+ on platforms not defining TM_ZONE, fixing a 2014g regression.
+ (Thanks to Tim Parenti for reporting the problem.)
+
+ The tz library no longer sets tzname if localtime or mktime fails.
+
+ zdump -c no longer mishandles transitions near year boundaries.
+ (Thanks to Tim Parenti for reporting the problem.)
+
+ An access to uninitialized data has been fixed.
+ (Thanks to Jörg Richter for reporting the problem.)
+
+ When THREAD_SAFE is defined, the code ports to the C11 memory model.
+ A memory leak has been fixed if ALL_STATE and THREAD_SAFE are defined
+ and two threads race to initialize data used by gmtime-like functions.
+ (Thanks to Andy Heninger for reporting the problems.)
+
+ Changes affecting build procedure
+
+ 'make check' now checks better for properly-sorted data.
+
+ Changes affecting documentation and commentary
+
+ zdump's gmtoff=N output is now documented, and its isdst=D output
+ is now documented to possibly output D values other than 0 or 1.
+
+ zdump -c's treatment of years is now documented to use the
+ Gregorian calendar and Universal Time without leap seconds,
+ and its behavior at cutoff boundaries is now documented better.
+ (Thanks to Arthur David Olson and Tim Parenti for reporting the problems.)
+
+ Programs are now documented to use the proleptic Gregorian calendar.
+ (Thanks to Alan Barrett for the suggestion.)
+
+ Fractional-second GMT offsets have been documented for civil time
+ in 19th-century Chennai, Jakarta, and New York.
+
+
+Release 2014g - 2014-08-28 12:31:23 -0700
+
+ Changes affecting future time stamps
+
+ Turks & Caicos is switching from US eastern time to UT -04
+ year-round, modeled as a switch on 2014-11-02 at 02:00.
+ [As noted in 2014j, this switch was later delayed.]
+
+ Changes affecting past time stamps
+
+ Time in Russia or the USSR before 1926 or so has been corrected by
+ a few seconds in the following zones: Asia/Irkutsk,
+ Asia/Krasnoyarsk, Asia/Omsk, Asia/Samarkand, Asia/Tbilisi,
+ Asia/Vladivostok, Asia/Yakutsk, Europe/Riga, Europe/Samara. For
+ Asia/Yekaterinburg the correction is a few minutes. (Thanks to
+ Vladimir Karpinsky.)
+
+ The Portuguese decree of 1911-05-26 took effect on 1912-01-01.
+ This affects 1911 time stamps in Africa/Bissau, Africa/Luanda,
+ Atlantic/Azores, and Atlantic/Madeira. Also, Lisbon's pre-1912
+ GMT offset was -0:36:45 (rounded from -0:36:44.68), not -0:36:32.
+ (Thanks to Stephen Colebourne for pointing to the decree.)
+
+ Asia/Dhaka ended DST on 2009-12-31 at 24:00, not 23:59.
+
+ A new file 'backzone' contains data which may appeal to
+ connoisseurs of old time stamps, although it is out of scope for
+ the tz database, is often poorly sourced, and contains some data
+ that is known to be incorrect. The new file is not recommended
+ for ordinary use and its entries are not installed by default.
+ (Thanks to Lester Caine for the high-quality Jersey, Guernsey, and
+ Isle of Man entries.)
+
+ Some more zones have been turned into links, when they differed
+ from existing zones only for older time stamps. As usual,
+ these changes affect UTC offsets in pre-1970 time stamps only.
+ Their old contents have been moved to the 'backzone' file.
+ The affected zones are: Africa/Bangui, Africa/Brazzaville,
+ Africa/Douala, Africa/Kinshasa, Africa/Libreville, Africa/Luanda,
+ Africa/Malabo, Africa/Niamey, and Africa/Porto-Novo.
+
+ Changes affecting code
+
+ Unless NETBSD_INSPIRED is defined to 0, the tz library now
+ supplies functions for creating and using objects that represent
+ time zones. The new functions are tzalloc, tzfree, localtime_rz,
+ mktime_z, and (if STD_INSPIRED is also defined) posix2time_z and
+ time2posix_z. They are intended for performance: for example,
+ localtime_rz (unlike localtime_r) is trivially thread-safe without
+ locking. (Thanks to Christos Zoulas for proposing NetBSD-inspired
+ functions, and to Alan Barrett and Jonathan Lennox for helping to
+ debug the change.)
+
+ zdump now builds with the tz library unless USE_LTZ is defined to 0,
+ This lets zdump use tz features even if the system library lacks them.
+ To build zdump with the system library, use 'make CFLAGS=-DUSE_LTZ=0
+ TZDOBJS=zdump.o CHECK_TIME_T_ALTERNATIVES='.
+
+ zdump now uses localtime_rz if available, as it's significantly faster,
+ and it can help zdump better diagnose invalid time zone names.
+ Define HAVE_LOCALTIME_RZ to 0 to suppress this. HAVE_LOCALTIME_RZ
+ defaults to 1 if NETBSD_INSPIRED && USE_LTZ. When localtime_rz is
+ not available, zdump now uses localtime_r and tzset if available,
+ as this is a bit cleaner and faster than plain localtime. Compile
+ with -DHAVE_LOCALTIME_R=0 and/or -DHAVE_TZSET=0 if your system
+ lacks these two functions.
+
+ If THREAD_SAFE is defined to 1, the tz library is now thread-safe.
+ Although not needed for tz's own applications, which are single-threaded,
+ this supports POSIX better if the tz library is used in multithreaded apps.
+
+ Some crashes have been fixed when zdump or the tz library is given
+ invalid or outlandish input.
+
+ The tz library no longer mishandles leap seconds on platforms with
+ unsigned time_t in time zones that lack ordinary transitions after 1970.
+
+ The tz code now attempts to infer TM_GMTOFF and TM_ZONE if not
+ already defined, to make it easier to configure on common platforms.
+ Define NO_TM_GMTOFF and NO_TM_ZONE to suppress this.
+
+ Unless the new macro UNINIT_TRAP is defined to 1, the tz code now
+ assumes that reading uninitialized memory yields garbage values
+ but does not cause other problems such as traps.
+
+ If TM_GMTOFF is defined and UNINIT_TRAP is 0, mktime is now
+ more likely to guess right for ambiguous time stamps near
+ transitions where tm_isdst does not change.
+
+ If HAVE_STRFTIME_L is defined to 1, the tz library now defines
+ strftime_l for compatibility with recent versions of POSIX.
+ Only the C locale is supported, though. HAVE_STRFTIME_L defaults
+ to 1 on recent POSIX versions, and to 0 otherwise.
+
+ tzselect -c now uses a hybrid distance measure that works better
+ in Africa. (Thanks to Alan Barrett for noting the problem.)
+
+ The C source code now ports to NetBSD when GCC_DEBUG_FLAGS is used,
+ or when time_tz is defined.
+
+ When HAVE_UTMPX_H is set the 'date' command now builds on systems
+ whose <utmpx.h> file does not define WTMPX_FILE, and when setting
+ the date it updates the wtmpx file if _PATH_WTMPX is defined.
+ This affects GNU/Linux and similar systems.
+
+ For easier maintenance later, some C code has been simplified,
+ some lint has been removed, and the code has been tweaked so that
+ plain 'make' is more likely to work.
+
+ The C type 'bool' is now used for boolean values, instead of 'int'.
+
+ The long-obsolete LOCALE_HOME code has been removed.
+
+ The long-obsolete 'gtime' function has been removed.
+
+ Changes affecting build procedure
+
+ 'zdump' no longer links in ialloc.o, as it's not needed.
+
+ 'make check_time_t_alternatives' no longer assumes GNU diff.
+
+ Changes affecting distribution tarballs
+
+ The files checktab.awk and zoneinfo2tdf.pl are now distributed in
+ the tzdata tarball instead of the tzcode tarball, since they help
+ maintain the data. The NEWS and Theory files are now also
+ distributed in the tzdata tarball, as they're relevant for data.
+ (Thanks to Alan Barrett for pointing this out.) Also, the
+ leapseconds.awk file is no longer distributed in the tzcode
+ tarball, since it belongs in the tzdata tarball (where 2014f
+ inadvertently also distributed it).
+
+ Changes affecting documentation and commentary
+
+ A new file CONTRIBUTING is distributed. (Thanks to Tim Parenti for
+ suggesting a CONTRIBUTING file, and to Tony Finch and Walter Harms
+ for debugging it.)
+
+ The man pages have been updated to use function prototypes,
+ to document thread-safe variants like localtime_r, and to document
+ the NetBSD-inspired functions tzalloc, tzfree, localtime_rz, and
+ mktime_z.
+
+ The fields in Link lines have been renamed to be more descriptive
+ and more like the parameters of 'ln'. LINK-FROM has become TARGET,
+ and LINK-TO has become LINK-NAME.
+
+ tz-link.htm mentions the IETF's tzdist working group; Windows
+ Runtime etc. (thanks to Matt Johnson); and HP-UX's tztab.
+
+ Some broken URLs have been fixed in the commentary. (Thanks to
+ Lester Caine.)
+
+ Commentary about Philippines DST has been updated, and commentary
+ on pre-1970 time in India has been added.
+
+
+Release 2014f - 2014-08-05 17:42:36 -0700
+
+ Changes affecting future time stamps
+
+ Russia will subtract an hour from most of its time zones on 2014-10-26
+ at 02:00 local time. (Thanks to Alexander Krivenyshev.)
+ There are a few exceptions: Magadan Oblast (Asia/Magadan) and Zabaykalsky
+ Krai are subtracting two hours; conversely, Chukotka Autonomous Okrug
+ (Asia/Anadyr), Kamchatka Krai (Asia/Kamchatka), Kemerovo Oblast
+ (Asia/Novokuznetsk), and the Samara Oblast and the Udmurt Republic
+ (Europe/Samara) are not changing their clocks. The changed zones are
+ Europe/Kaliningrad, Europe/Moscow, Europe/Simferopol, Europe/Volgograd,
+ Asia/Yekaterinburg, Asia/Omsk, Asia/Novosibirsk, Asia/Krasnoyarsk,
+ Asia/Irkutsk, Asia/Yakutsk, Asia/Vladivostok, Asia/Khandyga,
+ Asia/Sakhalin, and Asia/Ust-Nera; Asia/Magadan will have two hours
+ subtracted; and Asia/Novokuznetsk's time zone abbreviation is affected,
+ but not its UTC offset. Two zones are added: Asia/Chita (split
+ from Asia/Yakutsk, and also with two hours subtracted) and
+ Asia/Srednekolymsk (split from Asia/Magadan, but with only one hour
+ subtracted). (Thanks to Tim Parenti for much of the above.)
+
+ Changes affecting time zone abbreviations
+
+ Australian eastern time zone abbreviations are now AEST/AEDT not EST,
+ and similarly for the other Australian zones. That is, for eastern
+ standard and daylight saving time the abbreviations are AEST and AEDT
+ instead of the former EST for both; similarly, ACST/ACDT, ACWST/ACWDT,
+ and AWST/AWDT are now used instead of the former CST, CWST, and WST.
+ This change does not affect UTC offsets, only time zone abbreviations.
+ (Thanks to Rich Tibbett and many others.)
+
+ Asia/Novokuznetsk shifts from NOVT to KRAT (remaining on UT +07)
+ effective 2014-10-26 at 02:00 local time.
+
+ The time zone abbreviation for Xinjiang Time (observed in Ürümqi)
+ has been changed from URUT to XJT. (Thanks to Luther Ma.)
+
+ Prefer MSK/MSD for Moscow time in Russia, even in other cities.
+ Similarly, prefer EET/EEST for eastern European time in Russia.
+
+ Change time zone abbreviations in (western) Samoa to use "ST" and
+ "DT" suffixes, as this is more likely to match common practice.
+ Prefix "W" to (western) Samoa time when its standard-time offset
+ disagrees with that of American Samoa.
+
+ America/Metlakatla now uses PST, not MeST, to abbreviate its time zone.
+
+ Time zone abbreviations have been updated for Japan's two time
+ zones used 1896-1937. JWST now stands for Western Standard
+ Time, and JCST for Central Standard Time (formerly this was CJT).
+ These abbreviations are now used for time in Korea, Taiwan,
+ and Sakhalin while controlled by Japan.
+
+ Changes affecting past time stamps
+
+ China's five zones have been simplified to two, since the post-1970
+ differences in the other three seem to have been imaginary. The
+ zones Asia/Harbin, Asia/Chongqing, and Asia/Kashgar have been
+ removed; backwards-compatibility links still work, albeit with
+ different behaviors for time stamps before May 1980. Asia/Urumqi's
+ 1980 transition to UT +08 has been removed, so that it is now at
+ +06 and not +08. (Thanks to Luther Ma and to Alois Treindl;
+ Treindl sent helpful translations of two papers by Guo Qingsheng.)
+
+ Some zones have been turned into links, when they differed from existing
+ zones only for older UTC offsets where data entries were likely invented.
+ These changes affect UTC offsets in pre-1970 time stamps only. This is
+ similar to the change in release 2013e, except this time for western
+ Africa. The affected zones are: Africa/Bamako, Africa/Banjul,
+ Africa/Conakry, Africa/Dakar, Africa/Freetown, Africa/Lome,
+ Africa/Nouakchott, Africa/Ouagadougou, Africa/Sao_Tome, and
+ Atlantic/St_Helena. This also affects the backwards-compatibility
+ link Africa/Timbuktu. (Thanks to Alan Barrett, Stephen Colebourne,
+ Tim Parenti, and David Patte for reporting problems in earlier
+ versions of this change.)
+
+ Asia/Shanghai's pre-standard-time UT offset has been changed from
+ 8:05:57 to 8:05:43, the location of Xujiahui Observatory. Its
+ transition to standard time has been changed from 1928 to 1901.
+
+ Asia/Taipei switched to JWST on 1896-01-01, then to JST on 1937-10-01,
+ then to CST on 1945-09-21 at 01:00, and did not observe DST in 1945.
+ In 1946 it observed DST from 05-15 through 09-30; in 1947
+ from 04-15 through 10-31; and in 1979 from 07-01 through 09-30.
+ (Thanks to Yu-Cheng Chuang.)
+
+ Asia/Riyadh's transition to standard time is now 1947-03-14, not 1950.
+
+ Europe/Helsinki's 1942 fall-back transition was 10-04 at 01:00, not
+ 10-03 at 00:00. (Thanks to Konstantin Hyppönen.)
+
+ Pacific/Pago_Pago has been changed from UT -11:30 to -11 for the
+ period from 1911 to 1950.
+
+ Pacific/Chatham has been changed to New Zealand standard time plus
+ 45 minutes for the period before 1957, reflecting a 1956 remark in
+ the New Zealand parliament.
+
+ Europe/Budapest has several pre-1946 corrections: in 1918 the transition
+ out of DST was on 09-16, not 09-29; in 1919 it was on 11-24, not 09-15; in
+ 1945 it was on 11-01, not 11-03; in 1941 the transition to DST was 04-08
+ not 04-06 at 02:00; and there was no DST in 1920.
+
+ Africa/Accra is now assumed to have observed DST from 1920 through 1935.
+
+ Time in Russia before 1927 or so has been corrected by a few seconds in
+ the following zones: Europe/Moscow, Asia/Irkutsk, Asia/Tbilisi,
+ Asia/Tashkent, Asia/Vladivostok, Asia/Yekaterinburg, Europe/Helsinki, and
+ Europe/Riga. Also, Moscow's location has been changed to its Kilometer 0
+ point. (Thanks to Vladimir Karpinsky for the Moscow changes.)
+
+ Changes affecting data format
+
+ A new file 'zone1970.tab' supersedes 'zone.tab' in the installed data.
+ The new file's extended format allows multiple country codes per zone.
+ The older file is still installed but is deprecated; its format is
+ not changing and it will still be distributed for a while, but new
+ applications should use the new file.
+
+ The new file format simplifies maintenance of obscure locations.
+ To test this, it adds coverage for the Crozet Islands and the
+ Scattered Islands. (Thanks to Tobias Conradi and Antoine Leca.)
+
+ The file 'iso3166.tab' is planned to switch from ASCII to UTF-8.
+ It is still ASCII now, but commentary about the switch has been added.
+ The new file 'zone1970.tab' already uses UTF-8.
+
+ Changes affecting code
+
+ 'localtime', 'mktime', etc. now use much less stack space if ALL_STATE
+ is defined. (Thanks to Elliott Hughes for reporting the problem.)
+
+ 'zic' no longer mishandles input when ignoring case in locales that
+ are not compatible with English, e.g., unibyte Turkish locales when
+ compiled with HAVE_GETTEXT.
+
+ Error diagnostics of 'zic' and 'yearistype' have been reworded so that
+ they no longer use ASCII '-' as if it were a dash.
+
+ 'zic' now rejects output file names that contain '.' or '..' components.
+ (Thanks to Tim Parenti for reporting the problem.)
+
+ 'zic -v' now warns about output file names that do not follow
+ POSIX rules, or that contain a digit or '.'. (Thanks to Arthur
+ David Olson for starting the ball rolling on this.)
+
+ Some lint has been removed when using GCC_DEBUG_FLAGS with GCC 4.9.0.
+
+ Changes affecting build procedure
+
+ 'zic' no longer links in localtime.o and asctime.o, as they're not needed.
+ (Thanks to John Cochran.)
+
+ Changes affecting documentation and commentary
+
+ The 'Theory' file documents legacy names, the longstanding
+ exceptions to the POSIX-inspired file name rules.
+
+ The 'zic' documentation clarifies the role of time types when
+ interpreting dates. (Thanks to Arthur David Olson.)
+
+ Documentation and commentary now prefer UTF-8 to US-ASCII,
+ allowing the use of proper accents in foreign words and names.
+ Code and data have not changed because of this. (Thanks to
+ Garrett Wollman, Ian Abbott, and Guy Harris for helping to debug
+ this.)
+
+ Non-HTML documentation and commentary now use plain-text URLs instead of
+ HTML insertions, and are more consistent about bracketing URLs when they
+ are not already surrounded by white space. (Thanks to suggestions by
+ Steffen Nurpmeso.)
+
+ There is new commentary about Xujiahui Observatory, the five time-zone
+ project in China from 1918 to 1949, timekeeping in Japanese-occupied
+ Shanghai, and Tibet Time in the 1950s. The sharp-eyed can spot the
+ warlord Jin Shuren in the data.
+
+ Commentary about the coverage of each Russian zone has been standardized.
+ (Thanks to Tim Parenti).
+
+ There is new commentary about contemporary timekeeping in Ethiopia.
+
+ Obsolete comments about a 2007 proposal for DST in Kuwait has been removed.
+
+ There is new commentary about time in Poland in 1919.
+
+ Proper credit has been given to DST inventor George Vernon Hudson.
+
+ Commentary about time in Metlakatla, AK and Resolute, NU has been
+ improved, with a new source for the former.
+
+ In zone.tab, Pacific/Easter no longer mentions Salas y Gómez, as it
+ is uninhabited.
+
+ Commentary about permanent Antarctic bases has been updated.
+
+ Several typos have been corrected. (Thanks to Tim Parenti for
+ contributing some of these fixes.)
+
+ tz-link.htm now mentions the JavaScript libraries Moment Timezone,
+ TimezoneJS.Date, Walltime-js, and Timezone. (Thanks to a heads-up
+ from Matt Johnson.) Also, it mentions the Go 'latlong' package.
+ (Thanks to a heads-up from Dirkjan Ochtman.)
+
+ The files usno1988, usno1989, usno1989a, usno1995, usno1997, and usno1998
+ have been removed. These obsolescent US Naval Observatory entries were no
+ longer helpful for maintenance. (Thanks to Tim Parenti for the suggestion.)
+
+
+Release 2014e - 2014-06-12 21:53:52 -0700
+
+ Changes affecting near-future time stamps
+
+ Egypt's 2014 Ramadan-based transitions are June 26 and July 31 at 24:00.
+ (Thanks to Imed Chihi.) Guess that from 2015 on Egypt will temporarily
+ switch to standard time at 24:00 the last Thursday before Ramadan, and
+ back to DST at 00:00 the first Friday after Ramadan.
+
+ Similarly, Morocco's are June 28 at 03:00 and August 2 at 02:00. (Thanks
+ to Milamber Space Network.) Guess that from 2015 on Morocco will
+ temporarily switch to standard time at 03:00 the last Saturday before
+ Ramadan, and back to DST at 02:00 the first Saturday after Ramadan.
+
+ Changes affecting past time stamps
+
+ The abbreviation "MSM" (Moscow Midsummer Time) is now used instead of
+ "MSD" for Moscow's double daylight time in summer 1921. Also, a typo
+ "VLASST" has been repaired to be "VLAST" for Vladivostok summer time
+ in 1991. (Thanks to Hank W. for reporting the problems.)
+
+ Changes affecting commentary
+
+ tz-link.htm now cites RFC 7265 for jCal, mentions PTP and the
+ draft CalDAV extension, updates URLs for TSP, TZInfo, IATA, and
+ removes stale pointers to World Time Explorer and WORLDTIME.
+
+
+Release 2014d - 2014-05-27 21:34:40 -0700
+
+ Changes affecting code
+
+ zic no longer generates files containing time stamps before the Big Bang.
+ This works around GNOME bug 730332
+ <https://bugzilla.gnome.org/show_bug.cgi?id=730332>.
+ (Thanks to Leonardo Chiquitto for reporting the bug, and to
+ Arthur David Olson and James Cloos for suggesting improvements to the fix.)
+
+ Changes affecting documentation
+
+ tz-link.htm now mentions GNOME.
+
+
+Release 2014c - 2014-05-13 07:44:13 -0700
+
+ Changes affecting near-future time stamps
+
+ Egypt observes DST starting 2014-05-15 at 24:00.
+ (Thanks to Ahmad El-Dardiry and Gunther Vermier.)
+ Details have not been announced, except that DST will not be observed
+ during Ramadan. Guess that DST will stop during the same Ramadan dates as
+ Morocco, and that Egypt's future spring and fall transitions will be the
+ same as 2010 when it last observed DST, namely April's last Friday at
+ 00:00 to September's last Thursday at 23:00 standard time. Also, guess
+ that Ramadan transitions will be at 00:00 standard time.
+
+ Changes affecting code
+
+ zic now generates transitions for minimum time values, eliminating guesswork
+ when handling low-valued time stamps. (Thanks to Arthur David Olson.)
+
+ Port to Cygwin sans glibc. (Thanks to Arthur David Olson.)
+
+ Changes affecting commentary and documentation
+
+ Remove now-confusing comment about Jordan. (Thanks to Oleksii Nochovnyi.)
+
+
+Release 2014b - 2014-03-24 21:28:50 -0700
+
+ Changes affecting near-future time stamps
+
+ Crimea switches to Moscow time on 2014-03-30 at 02:00 local time.
+ (Thanks to Alexander Krivenyshev.) Move its zone.tab entry from UA to RU.
+
+ New entry for Troll station, Antarctica. (Thanks to Paul-Inge Flakstad and
+ Bengt-Inge Larsson.) This is currently an approximation; a better version
+ will require the zic and localtime fixes mentioned below, and the plan is
+ to wait for a while until at least the zic fixes propagate.
+
+ Changes affecting code
+
+ 'zic' and 'localtime' no longer reject locations needing four transitions
+ per year for the foreseeable future. (Thanks to Andrew Main (Zefram).)
+ Also, 'zic' avoids some unlikely failures due to integer overflow.
+
+ Changes affecting build procedure
+
+ 'make check' now detects Rule lines defined but never used.
+ The NZAQ rules, an instance of this problem, have been removed.
+
+ Changes affecting commentary and documentation
+
+ Fix Tuesday/Thursday typo in description of time in Israel.
+ (Thanks to Bert Katz via Pavel Kharitonov and Mike Frysinger.)
+
+ Microsoft Windows 8.1 doesn't support tz database names. (Thanks
+ to Donald MacQueen.) Instead, the Microsoft Windows Store app
+ library supports them.
+
+ Add comments about Johnston Island time in the 1960s.
+ (Thanks to Lyle McElhaney.)
+
+ Morocco's 2014 DST start will be as predicted.
+ (Thanks to Sebastien Willemijns.)
+
+
+Release 2014a - 2014-03-07 23:30:29 -0800
+
+ Changes affecting near-future time stamps
+
+ Turkey begins DST on 2014-03-31, not 03-30. (Thanks to Faruk Pasin for
+ the heads-up, and to Tim Parenti for simplifying the update.)
+
+ Changes affecting past time stamps
+
+ Fiji ended DST on 2014-01-19 at 02:00, not the previously-scheduled 03:00.
+ (Thanks to Steffen Thorsen.)
+
+ Ukraine switched from Moscow to Eastern European time on 1990-07-01
+ (not 1992-01-01), and observed DST during the entire next winter.
+ (Thanks to Vladimir in Moscow via Alois Treindl.)
+
+ In 1988 Israel observed DST from 04-10 to 09-04, not 04-09 to 09-03.
+ (Thanks to Avigdor Finkelstein.)
+
+ Changes affecting code
+
+ A uninitialized-storage bug in 'localtime' has been fixed.
+ (Thanks to Logan Chien.)
+
+ Changes affecting the build procedure
+
+ The settings for 'make check_web' now default to Ubuntu 13.10.
+
+ Changes affecting commentary and documentation
+
+ The boundary of the US Pacific time zone is given more accurately.
+ (Thanks to Alan Mintz.)
+
+ Chile's 2014 DST will be as predicted. (Thanks to José Miguel Garrido.)
+
+ Paraguay's 2014 DST will be as predicted. (Thanks to Carlos Raúl Perasso.)
+
+ Better descriptions of countries with same time zone history as
+ Trinidad and Tobago since 1970. (Thanks to Alan Barrett for suggestion.)
+
+ Several changes affect tz-link.htm, the main web page.
+
+ Mention Time.is (thanks to Even Scharning) and WX-now (thanks to
+ David Braverman).
+
+ Mention xCal (Internet RFC 6321) and jCal.
+
+ Microsoft has some support for tz database names.
+
+ CLDR data formats include both XML and JSON.
+
+ Mention Maggiolo's map of solar vs standard time.
+ (Thanks to Arthur David Olson.)
+
+ Mention TZ4Net. (Thanks to Matt Johnson.)
+
+ Mention the timezone-olson Haskell package.
+
+ Mention zeitverschiebung.net. (Thanks to Martin Jäger.)
+
+ Remove moribund links to daylight-savings-time.info and to
+ Simple Timer + Clocks.
+
+ Update two links. (Thanks to Oscar van Vlijmen.)
+
+ Fix some formatting glitches, e.g., remove random newlines from
+ abbr elements' title attributes.
+
+
+Release 2013i - 2013-12-17 07:25:23 -0800
+
+ Changes affecting near-future time stamps:
+
+ Jordan switches back to standard time at 00:00 on December 20, 2013.
+ The 2006-2011 transition schedule is planned to resume in 2014.
+ (Thanks to Steffen Thorsen.)
+
+ Changes affecting past time stamps:
+
+ In 2004, Cuba began DST on March 28, not April 4.
+ (Thanks to Steffen Thorsen.)
+
+ Changes affecting code
+
+ The compile-time flag NOSOLAR has been removed, as nowadays the
+ benefit of slightly shrinking runtime table size is outweighed by the
+ cost of disallowing potential future updates that exceed old limits.
+
+ Changes affecting documentation and commentary
+
+ The files solar87, solar88, and solar89 are no longer distributed.
+ They were a negative experiment - that is, a demonstration that
+ tz data can represent solar time only with some difficulty and error.
+ Their presence in the distribution caused confusion, as Riyadh
+ civil time was generally not solar time in those years.
+
+ tz-link.htm now mentions Noda Time. (Thanks to Matt Johnson.)
+
+
+Release 2013h - 2013-10-25 15:32:32 -0700
+
+ Changes affecting current and future time stamps:
+
+ Libya has switched its UT offset back to +02 without DST, instead
+ of +01 with DST. (Thanks to Even Scharning.)
+
+ Western Sahara (Africa/El_Aaiun) uses Morocco's DST rules.
+ (Thanks to Gwillim Law.)
+
+ Changes affecting future time stamps:
+
+ Acre and (we guess) western Amazonas will switch from UT -04 to -05
+ on 2013-11-10. This affects America/Rio_Branco and America/Eirunepe.
+ (Thanks to Steffen Thorsen.)
+
+ Add entries for DST transitions in Morocco in the year 2038.
+ This avoids some year-2038 glitches introduced in 2013g.
+ (Thanks to Yoshito Umaoka for reporting the problem.)
+
+ Changes affecting API
+
+ The 'tzselect' command no longer requires the 'select' command,
+ and should now work with /bin/sh on more platforms. It also works
+ around a bug in BusyBox awk before version 1.21.0. (Thanks to
+ Patrick 'P. J.' McDermott and Alan Barrett.)
+
+ Changes affecting code
+
+ Fix localtime overflow bugs with 32-bit unsigned time_t.
+
+ zdump no longer assumes sscanf returns maximal values on overflow.
+
+ Changes affecting the build procedure
+
+ The builder can specify which programs to use, if any, instead of
+ 'ar' and 'ranlib', and libtz.a is now built locally before being
+ installed. (Thanks to Michael Forney.)
+
+ A dependency typo in the 'zdump' rule has been fixed.
+ (Thanks to Andrew Paprocki.)
+
+ The Makefile has been simplified by assuming that 'mkdir -p' and 'cp -f'
+ work as specified by POSIX.2-1992 or later; this is portable nowadays.
+
+ 'make clean' no longer removes 'leapseconds', since it's
+ host-independent and is part of the distribution.
+
+ The unused makefile macros TZCSRCS, TZDSRCS, DATESRCS have been removed.
+
+ Changes affecting documentation and commentary
+
+ tz-link.htm now mentions TC TIMEZONE's draft time zone service protocol
+ (thanks to Mike Douglass) and TimezoneJS.Date (thanks to Jim Fehrle).
+
+ Update URLs in tz-link page. Add URLs for Microsoft Windows, since
+ 8.1 introduces tz support. Remove URLs for Tru64 and UnixWare (no
+ longer maintained) and for old advisories. SOFA now does C.
+
+Release 2013g - 2013-09-30 21:08:26 -0700
+
+ Changes affecting current and near-future time stamps
+
+ Morocco now observes DST from the last Sunday in March to the last
+ Sunday in October, not April to September respectively. (Thanks
+ to Steffen Thorsen.)
+
+ Changes affecting 'zic'
+
+ 'zic' now runs on platforms that lack both hard links and symlinks.
+ (Thanks to Theo Veenker for reporting the problem, for MinGW.)
+ Also, fix some bugs on platforms that lack hard links but have symlinks.
+
+ 'zic -v' again warns that Asia/Tehran has no POSIX environment variable
+ to predict the far future, fixing a bug introduced in 2013e.
+
+ Changes affecting the build procedure
+
+ The 'leapseconds' file is again put into the tzdata tarball.
+ Also, 'leapseconds.awk', so tzdata is self-contained. (Thanks to
+ Matt Burgess and Ian Abbott.) The timestamps of these and other
+ dependent files in tarballs are adjusted more consistently.
+
+ Changes affecting documentation and commentary
+
+ The README file is now part of the data tarball as well as the code.
+ It now states that files are public domain unless otherwise specified.
+ (Thanks to Andrew Main (Zefram) for asking for clarifications.)
+ Its details about the 1989 release moved to a place of honor near
+ the end of NEWS.
+
+
+Release 2013f - 2013-09-24 23:37:36 -0700
+
+ Changes affecting near-future time stamps
+
+ Tocantins will very likely not observe DST starting this spring.
+ (Thanks to Steffen Thorsen.)
+
+ Jordan will likely stay at UT +03 indefinitely, and will not fall
+ back this fall.
+
+ Palestine will fall back at 00:00, not 01:00. (Thanks to Steffen Thorsen.)
+
+ Changes affecting API
+
+ The types of the global variables 'timezone' and 'altzone' (if present)
+ have been changed back to 'long'. This is required for 'timezone'
+ by POSIX, and for 'altzone' by common practice, e.g., Solaris 11.
+ These variables were originally 'long' in the tz code, but were
+ mistakenly changed to 'time_t' in 1987; nobody reported the
+ incompatibility until now. The difference matters on x32, where
+ 'long' is 32 bits and 'time_t' is 64. (Thanks to Elliott Hughes.)
+
+ Changes affecting the build procedure
+
+ Avoid long strings in leapseconds.awk to work around a mawk bug.
+ (Thanks to Cyril Baurand.)
+
+ Changes affecting documentation and commentary
+
+ New file 'NEWS' that contains release notes like this one.
+
+ Paraguay's law does not specify DST transition time; 00:00 is customary.
+ (Thanks to Waldemar Villamayor-Venialbo.)
+
+ Minor capitalization fixes.
+
+ Changes affecting version-control only
+
+ The experimental GitHub repository now contains annotated and
+ signed tags for recent releases, e.g., '2013e' for Release 2013e.
+ Releases are tagged starting with 2012e; earlier releases were
+ done differently, and tags would either not have a simple name or
+ not exactly match what was released.
+
+ 'make set-timestamps' is now simpler and a bit more portable.
+
+
+Release 2013e - 2013-09-19 23:50:04 -0700
+
+ Changes affecting near-future time stamps
+
+ This year Fiji will start DST on October 27, not October 20.
+ (Thanks to David Wheeler for the heads-up.) For now, guess that
+ Fiji will continue to spring forward the Sunday before the fourth
+ Monday in October.
+
+ Changes affecting current and future time zone abbreviations
+
+ Use WIB/WITA/WIT rather than WIT/CIT/EIT for alphabetic Indonesian
+ time zone abbreviations since 1932. (Thanks to George Ziegler,
+ Priyadi Iman Nurcahyo, Zakaria, Jason Grimes, Martin Pitt, and
+ Benny Lin.) This affects Asia/Dili, Asia/Jakarta, Asia/Jayapura,
+ Asia/Makassar, and Asia/Pontianak.
+
+ Use ART (UT -03, standard time), rather than WARST (also -03, but
+ daylight saving time) for San Luis, Argentina since 2009.
+
+ Changes affecting Godthåb time stamps after 2037 if version mismatch
+
+ Allow POSIX-like TZ strings where the transition time's hour can
+ range from -167 through 167, instead of the POSIX-required 0
+ through 24. E.g., TZ='FJT-12FJST,M10.3.1/146,M1.3.4/75' for the
+ new Fiji rules. This is a more-compact way to represent
+ far-future time stamps for America/Godthab, America/Santiago,
+ Antarctica/Palmer, Asia/Gaza, Asia/Hebron, Asia/Jerusalem,
+ Pacific/Easter, and Pacific/Fiji. Other zones are unaffected by
+ this change. (Derived from a suggestion by Arthur David Olson.)
+
+ Allow POSIX-like TZ strings where daylight saving time is in
+ effect all year. E.g., TZ='WART4WARST,J1/0,J365/25' for Western
+ Argentina Summer Time all year. This supports a more-compact way
+ to represent the 2013d data for America/Argentina/San_Luis.
+ Because of the change for San Luis noted above this change does not
+ affect the current data. (Thanks to Andrew Main (Zefram) for
+ suggestions that improved this change.)
+
+ Where these two TZ changes take effect, there is a minor extension
+ to the tz file format in that it allows new values for the
+ embedded TZ-format string, and the tz file format version number
+ has therefore been increased from 2 to 3 as a precaution.
+ Version-2-based client code should continue to work as before for
+ all time stamps before 2038. Existing version-2-based client code
+ (tzcode, GNU/Linux, Solaris) has been tested on version-3-format
+ files, and typically works in practice even for time stamps after
+ 2037; the only known exception is America/Godthab.
+
+ Changes affecting time stamps before 1970
+
+ Pacific/Johnston is now a link to Pacific/Honolulu. This corrects
+ some errors before 1947.
+
+ Some zones have been turned into links, when they differ from existing
+ zones only in older data entries that were likely invented or that
+ differ only in LMT or transitions from LMT. These changes affect
+ only time stamps before 1943. The affected zones are:
+ Africa/Juba, America/Anguilla, America/Aruba, America/Dominica,
+ America/Grenada, America/Guadeloupe, America/Marigot,
+ America/Montserrat, America/St_Barthelemy, America/St_Kitts,
+ America/St_Lucia, America/St_Thomas, America/St_Vincent,
+ America/Tortola, and Europe/Vaduz. (Thanks to Alois Treindl for
+ confirming that the old Europe/Vaduz zone was wrong and the new
+ link is better for WWII-era times.)
+
+ Change Kingston Mean Time from -5:07:12 to -5:07:11. This affects
+ America/Cayman, America/Jamaica and America/Grand_Turk time stamps
+ from 1890 to 1912.
+
+ Change the UT offset of Bern Mean Time from 0:29:44 to 0:29:46.
+ This affects Europe/Zurich time stamps from 1853 to 1894. (Thanks
+ to Alois Treindl).
+
+ Change the date of the circa-1850 Zurich transition from 1849-09-12
+ to 1853-07-16, overriding Shanks with data from Messerli about
+ postal and telegraph time in Switzerland.
+
+ Changes affecting time zone abbreviations before 1970
+
+ For Asia/Jakarta, use BMT (not JMT) for mean time from 1923 to 1932,
+ as Jakarta was called Batavia back then.
+
+ Changes affecting API
+
+ The 'zic' command now outputs a dummy transition when far-future
+ data can't be summarized using a TZ string, and uses a 402-year
+ window rather than a 400-year window. For the current data, this
+ affects only the Asia/Tehran file. It does not affect any of the
+ time stamps that this file represents, so zdump outputs the same
+ information as before. (Thanks to Andrew Main (Zefram).)
+
+ The 'date' command has a new '-r' option, which lets you specify
+ the integer time to display, a la FreeBSD.
+
+ The 'tzselect' command has two new options '-c' and '-n', which lets you
+ select a zone based on latitude and longitude.
+
+ The 'zic' command's '-v' option now warns about constructs that
+ require the new version-3 binary file format. (Thanks to Arthur
+ David Olson for the suggestion.)
+
+ Support for floating-point time_t has been removed.
+ It was always dicey, and POSIX no longer requires it.
+ (Thanks to Eric Blake for suggesting to the POSIX committee to
+ remove it, and thanks to Alan Barrett, Clive D.W. Feather, Andy
+ Heninger, Arthur David Olson, and Alois Treindl, for reporting
+ bugs and elucidating some of the corners of the old floating-point
+ implementation.)
+
+ The signatures of 'offtime', 'timeoff', and 'gtime' have been
+ changed back to the old practice of using 'long' to represent UT
+ offsets. This had been inadvertently and mistakenly changed to
+ 'int_fast32_t'. (Thanks to Christos Zoulas.)
+
+ The code avoids undefined behavior on integer overflow in some
+ more places, including gmtime, localtime, mktime and zdump.
+
+ Changes affecting the zdump utility
+
+ zdump now outputs "UT" when referring to Universal Time, not "UTC".
+ "UTC" does not make sense for time stamps that predate the introduction
+ of UTC, whereas "UT", a more-generic term, does. (Thanks to Steve Allen
+ for clarifying UT vs UTC.)
+
+ Data changes affecting behavior of tzselect and similar programs
+
+ Country code BQ is now called the more-common name "Caribbean Netherlands"
+ rather than the more-official "Bonaire, St Eustatius & Saba".
+
+ Remove from zone.tab the names America/Montreal, America/Shiprock,
+ and Antarctica/South_Pole, as they are equivalent to existing
+ same-country-code zones for post-1970 time stamps. The data entries for
+ these names are unchanged, so the names continue to work as before.
+
+ Changes affecting code internals
+
+ zic -c now runs way faster on 64-bit hosts when given large numbers.
+
+ zic now uses vfprintf to avoid allocating and freeing some memory.
+
+ tzselect now computes the list of continents from the data,
+ rather than have it hard-coded.
+
+ Minor changes pacify GCC 4.7.3 and GCC 4.8.1.
+
+ Changes affecting the build procedure
+
+ The 'leapseconds' file is now generated automatically from a
+ new file 'leap-seconds.list', which is a copy of
+ <ftp://time.nist.gov/pub/leap-seconds.list>.
+ A new source file 'leapseconds.awk' implements this.
+ The goal is simplification of the future maintenance of 'leapseconds'.
+
+ When building the 'posix' or 'right' subdirectories, if the
+ subdirectory would be a copy of the default subdirectory, it is
+ now made a symbolic link if that is supported. This saves about
+ 2 MB of file system space.
+
+ The links America/Shiprock and Antarctica/South_Pole have been
+ moved to the 'backward' file. This affects only nondefault builds
+ that omit 'backward'.
+
+ Changes affecting version-control only
+
+ .gitignore now ignores 'date'.
+
+ Changes affecting documentation and commentary
+
+ Changes to the 'tzfile' man page
+
+ It now mentions that the binary file format may be extended in
+ future versions by appending data.
+
+ It now refers to the 'zdump' and 'zic' man pages.
+
+ Changes to the 'zic' man page
+
+ It lists conditions that elicit a warning with '-v'.
+
+ It says that the behavior is unspecified when duplicate names
+ are given, or if the source of one link is the target of another.
+
+ Its examples are updated to match the latest data.
+
+ The definition of white space has been clarified slightly.
+ (Thanks to Michael Deckers.)
+
+ Changes to the 'Theory' file
+
+ There is a new section about the accuracy of the tz database,
+ describing the many ways that errors can creep in, and
+ explaining why so many of the pre-1970 time stamps are wrong or
+ misleading (thanks to Steve Allen, Lester Caine, and Garrett
+ Wollman for discussions that contributed to this).
+
+ The 'Theory' file describes LMT better (this follows a
+ suggestion by Guy Harris).
+
+ It refers to the 2013 edition of POSIX rather than the 2004 edition.
+
+ It's mentioned that excluding 'backward' should not affect the
+ other data, and it suggests at least one zone.tab name per
+ inhabited country (thanks to Stephen Colebourne).
+
+ Some longstanding restrictions on names are documented, e.g.,
+ 'America/New_York' precludes 'America/New_York/Bronx'.
+
+ It gives more reasons for the 1970 cutoff.
+
+ It now mentions which time_t variants are supported, such as
+ signed integer time_t. (Thanks to Paul Goyette for reporting
+ typos in an experimental version of this change.)
+
+ (Thanks to Philip Newton for correcting typos in these changes.)
+
+ Documentation and commentary is more careful to distinguish UT in
+ general from UTC in particular. (Thanks to Steve Allen.)
+
+ Add a better source for the Zurich 1894 transition.
+ (Thanks to Pierre-Yves Berger.)
+
+ Update shapefile citations in tz-link.htm. (Thanks to Guy Harris.)
+
+
+Release 2013d - 2013-07-05 07:38:01 -0700
+
+ Changes affecting future time stamps:
+
+ Morocco's midsummer transitions this year are July 7 and August 10,
+ not July 9 and August 8. (Thanks to Andrew Paprocki.)
+
+ Israel now falls back on the last Sunday of October.
+ (Thanks to Ephraim Silverberg.)
+
+ Changes affecting past time stamps:
+
+ Specify Jerusalem's location more precisely; this changes the pre-1880
+ times by 2 s.
+
+ Changing affecting metadata only:
+
+ Fix typos in the entries for country codes BQ and SX.
+
+ Changes affecting code:
+
+ Rework the code to fix a bug with handling Australia/Macquarie on
+ 32-bit hosts (thanks to Arthur David Olson).
+
+ Port to platforms like NetBSD, where time_t can be wider than long.
+
+ Add support for testing time_t types other than the system's.
+ Run 'make check_time_t_alternatives' to try this out.
+ Currently, the tests fail for unsigned time_t;
+ this should get fixed at some point.
+
+ Changes affecting documentation and commentary:
+
+ Deemphasize the significance of national borders.
+
+ Update the zdump man page.
+
+ Remove obsolete NOID comment (thanks to Denis Excoffier).
+
+ Update several URLs and comments in the web pages.
+
+ Spelling fixes (thanks to Kevin Lyda and Jonathan Leffler).
+
+ Update URL for CLDR Zone->Tzid table (thanks to Yoshito Umaoka).
+
+
+Release 2013c - 2013-04-19 16:17:40 -0700
+
+ Changes affecting current and future time stamps:
+
+ Palestine observed DST starting March 29, 2013. (Thanks to
+ Steffen Thorsen.) From 2013 on, Gaza and Hebron both observe DST,
+ with the predicted rules being the last Thursday in March at 24:00
+ to the first Friday on or after September 21 at 01:00.
+
+ Assume that the recent change to Paraguay's DST rules is permanent,
+ by moving the end of DST to the 4th Sunday in March every year.
+ (Thanks to Carlos Raúl Perasso.)
+
+ Changes affecting past time stamps:
+
+ Fix some historical data for Palestine to agree with that of
+ timeanddate.com, as follows:
+
+ The spring 2008 change in Gaza and Hebron was on 00:00 Mar 28, not
+ 00:00 Apr 1.
+
+ The fall 2009 change in Gaza and Hebron on Sep 4 was at 01:00, not
+ 02:00.
+
+ The spring 2010 change in Hebron was 00:00 Mar 26, not 00:01 Mar 27.
+
+ The spring 2011 change in Gaza was 00:01 Apr 1, not 12:01 Apr 2.
+
+ The spring 2011 change in Hebron on Apr 1 was at 00:01, not 12:01.
+
+ The fall 2011 change in Hebron on Sep 30 was at 00:00, not 03:00.
+
+ Fix times of habitation for Macquarie to agree with the Tasmania
+ Parks & Wildlife Service history, which indicates that permanent
+ habitation was 1899-1919 and 1948 on.
+
+ Changing affecting metadata only:
+
+ Macquarie Island is politically part of Australia, not Antarctica.
+ (Thanks to Tobias Conradi.)
+
+ Sort Macquarie more-consistently with other parts of Australia.
+ (Thanks to Tim Parenti.)
+
+
+Release 2013b - 2013-03-10 22:33:40 -0700
+
+ Changes affecting current and future time stamps:
+
+ Haiti uses US daylight-saving rules this year, and presumably future years.
+ This changes time stamps starting today. (Thanks to Steffen Thorsen.)
+
+ Paraguay will end DST on March 24 this year.
+ (Thanks to Steffen Thorsen.) For now, assume it's just this year.
+
+ Morocco does not observe DST during Ramadan;
+ try to predict Ramadan in Morocco as best we can.
+ (Thanks to Erik Homoet for the heads-up.)
+
+ Changes affecting commentary:
+
+ Update URLs in tz-link page. Add URLs for webOS, BB10, iOS.
+ Update URL for Solaris. Mention Internet RFC 6557.
+ Update Internet RFCs 2445->5545, 2822->5322.
+ Switch from FTP to HTTP for Internet RFCs.
+
+
+Release 2013a - 2013-02-27 09:20:35 -0800
+
+ Change affecting binary data format:
+
+ The zone offset at the end of version-2-format zone files is now
+ allowed to be 24:00, as per POSIX.1-2008. (Thanks to Arthur David Olson.)
+
+ Changes affecting current and future time stamps:
+
+ Chile's 2013 rules, and we guess rules for 2014 and later, will be
+ the same as 2012, namely Apr Sun>=23 03:00 UTC to Sep Sun>=2 04:00 UTC.
+ (Thanks to Steffen Thorsen and Robert Elz.)
+
+ New Zones Asia/Khandyga, Asia/Ust-Nera, Europe/Busingen.
+ (Thanks to Tobias Conradi and Arthur David Olson.)
+
+ Many changes affect historical time stamps before 1940.
+ These were deduced from: Milne J. Civil time. Geogr J. 1899
+ Feb;13(2):173-94 <http://www.jstor.org/stable/1774359>.
+
+ Changes affecting the code:
+
+ Fix zic bug that mishandled Egypt's 2010 changes (this also affected
+ the data). (Thanks to Arthur David Olson.)
+
+ Fix localtime bug when time_t is unsigned and data files were generated
+ by a signed time_t system. (Thanks to Doug Bailey for reporting and
+ to Arthur David Olson for fixing.)
+
+ Allow the email address for bug reports to be set by the packager.
+ The default is tz@iana.org, as before. (Thanks to Joseph S. Myers.)
+
+ Update HTML checking to be compatible with Ubuntu 12.10.
+
+ Check that files are a safe subset of ASCII. At some point we may
+ relax this requirement to a safe subset of UTF-8. Without the
+ check, some non-UTF-8 encodings were leaking into the distribution.
+
+ Commentary changes:
+
+ Restore a comment about copyright notices that was inadvertently deleted.
+ (Thanks to Arthur David Olson.)
+
+ Improve the commentary about which districts observe what times
+ in Russia. (Thanks to Oscar van Vlijmen and Arthur David Olson).
+
+ Add web page links to tz.js.
+
+ Add "Run by the Monkeys" to tz-art. (Thanks to Arthur David Olson.)
+
+
+Release 2012j - 2012-11-12 18:34:49 -0800
+
+ Libya moved to CET this weekend, but with DST planned next year.
+ (Thanks to Even Scharning, Steffen Thorsen, and Tim Parenti.)
+
+ Signatures now have the extension .asc, not .sign, as that's more
+ standard. (Thanks to Phil Pennock.)
+
+ The output of 'zdump --version', and of 'zic --version', now
+ uses a format that is more typical for --version.
+ (Thanks to Joseph S. Myers.)
+
+ The output of 'tzselect --help', 'zdump --help', and 'zic --help'
+ now uses tz@iana.org rather than the old elsie address.
+
+ zic -v now complains about abbreviations that are less than 3
+ or more than 6 characters, as per Posix. Formerly, it checked
+ for abbreviations that were more than 3.
+
+ 'make public' no longer puts its temporary directory under /tmp,
+ and uses the just-built zic rather than the system zic.
+
+ Various fixes to documentation and commentary.
+
+
+Release 2012i - 2012-11-03 12:57:09 -0700
+
+ Cuba switches from DST tomorrow at 01:00. (Thanks to Steffen Thorsen.)
+
+ Linker flags can now be specified via LDFLAGS.
+ AWK now defaults to 'awk', not 'nawk'.
+ The shell in tzselect now defaults to /bin/bash, but this can
+ be overridden by specifying KSHELL.
+ The main web page now mentions the unofficial GitHub repository.
+ (Thanks to Mike Frysinger.)
+
+ Tarball signatures can now be built by running 'make signatures'.
+ There are also new makefile rules 'tarballs', 'check_public', and
+ separate makefile rules for each tarball and signature file.
+ A few makefile rules are now more portable to strict POSIX.
+
+ The main web page now lists the canonical IANA URL.
+
+
+Release 2012h - 2012-10-26 22:49:10 -0700
+
+ Bahia no longer has DST. (Thanks to Kelley Cook.)
+
+ Tocantins has DST. (Thanks to Rodrigo Severo.)
+
+ Israel has new DST rules next year. (Thanks to Ephraim Silverberg.)
+
+ Jordan stays on DST this winter. (Thanks to Steffen Thorsen.)
+
+ Web page updates.
+
+ More C modernization, except that at Arthur David Olson's suggestion
+ the instances of 'register' were kept.
+
+
+Release 2012g - 2012-10-17 20:59:45 -0700
+
+ Samoa fall 2012 and later. (Thanks to Nicholas Pereira and Robert Elz.)
+
+ Palestine fall 2012. (Thanks to Steffen Thorsen.)
+
+ Assume C89.
+
+ To attack the version-number problem, this release ships the file
+ 'Makefile' (which contains the release number) in both the tzcode and
+ the tzdata tarballs. The two Makefiles are identical, and should be
+ identical in any matching pair of tarballs, so it shouldn't matter
+ which order you extract the tarballs. Perhaps we can come up with a
+ better version-number scheme at some point; this scheme does have the
+ virtue of not adding more files.
+
+
+Release 2012f - 2012-09-12 23:17:03 -0700
+
+ * australasia (Pacific/Fiji): Fiji DST is October 21 through January
+ 20 this year. (Thanks to Steffen Thorsen.)
+
+
+Release 2012e - 2012-08-02 20:44:55 -0700
+
+ * australasia (Pacific/Fakaofo): Tokelau is UT +13, not +14.
+ (Thanks to Steffen Thorsen.)
+
+ * Use a single version number for both code and data.
+
+ * .gitignore: New file.
+
+ * Remove trailing white space.
+
+
+Release code2012c-data2012d - 2012-07-19 16:35:33 -0700
+
+ Changes for Morocco's time stamps, which take effect in a couple of
+ hours, along with infrastructure changes to accommodate how the tz
+ code and data are released on IANA.
+
+
+Release data2012c - 2012-03-27 12:17:25 -0400
+
+ africa
+ Summer time changes for Morocco (to start late April 2012)
+
+ asia
+ Changes for 2012 for Gaza & the West Bank (Hebron) and Syria
+
+ northamerica
+ Haiti following US/Canada rules for 2012 (and we're assuming,
+ for now anyway, for the future).
+
+
+Release 2012b - 2012-03-02 12:29:15 +0700
+
+ There is just one change to tzcode2012b (compared with 2012a):
+ the Makefile that was accidentally included with 2012a has been
+ replaced with the version that should have been there, which is
+ identical with the previous version (from tzcode2011i).
+
+ There are just two changes in tzdata2012b compared with 2012a.
+
+ Most significantly, summer time in Cuba has been delayed 3 weeks
+ (now starts April 1 rather than March 11). Since Mar 11 (the old start
+ date, as listed in 2012a) is just a little over a week away, this
+ change is urgent.
+
+ Less importantly, an excess tab in one of the changes in zone.tab
+ in 2012a has been removed.
+
+
+Release 2012a - 2012-03-01 18:28:10 +0700
+
+ The changes in tzcode2012a (compared to the previous version, 2011i)
+ are entirely to the README and tz-art.htm and tz-link.htm files, if
+ none of those concern you, you can ignore the code update. The changes
+ reflect the changed addresses for the mailing list and the code and
+ data distribution points & methods (and a link to DateTime::TimeZone::Tzfile
+ has been added to tz-link.htm).
+
+ In tzdata2012a (compared to the previous release, which was 2011n)
+ the major changes are:
+ Chile 2011/2012 and 2012/2013 summer time date adjustments.
+ Falkland Islands onto permanent summer time (we're assuming for the
+ foreseeable future, though 2012 is all we're fairly certain of.)
+ Armenia has abolished Summer Time.
+ Tokelau jumped the International Date Line back last December
+ (just the same as their near neighbour, Samoa).
+ America/Creston is a new zone for a small area of British Columbia
+ There will be a leapsecond 2012-06-30 23:59:60 UTC.
+
+ Other minor changes are:
+ Corrections to 1918 Canadian summer time end dates.
+ Updated URL for UK time zone history (in comments)
+ A few typos in Le Corre's list of free French place names (comments)
+
+
+Release data2011n - 2011-10-30 14:57:54 +0700
+
+ There are three changes of note - most urgently, Cuba (America/Havana)
+ has extended summer time by two weeks, now to end on Nov 13, rather than
+ the (already past) Oct 30. Second, the Pridnestrovian Moldavian Republic
+ (Europe/Tiraspol) decided not to split from the rest of Moldova after
+ all, and consequently that zone has been removed (again) and reinstated
+ in the "backward" file as a link to Europe/Chisinau. And third, the
+ end date for Fiji's summer time this summer was moved forward from the
+ earlier planned Feb 26, to Jan 22.
+
+ Apart from that, Moldova (MD) returns to a single entry in zone.tab
+ (and the incorrect syntax that was in the 2011m version of that file
+ is so fixed - it would have been fixed in a different way had this
+ change not happened - that's the "missing" sccs version id).
+
+
+Release data2011m - 2011-10-24 21:42:16 +0700
+
+ In particular, the typos in comments in the data (2011-11-17 should have
+ been 2011-10-17 as Alan Barrett noted, and spelling of Tiraspol that
+ Tim Parenti noted) have been fixed, and the change for Ukraine has been
+ made in all 4 Ukrainian zones, rather than just Kiev (again, thanks to
+ Tim Parenti, and also Denys Gavrysh)
+
+ In addition, I added Europe/Tiraspol to zone.tab.
+
+ This time, all the files have new version numbers... (including the files
+ otherwise unchanged in 2011m that were changed in 2011l but didn't get new
+ version numbers there...)
+
+
+Release data2011l - 2011-10-10 11:15:43 +0700
+
+ There are just 2 changes that cause different generated tzdata files from
+ zic, to Asia/Hebron and Pacific/Fiji - the possible change for Bahia, Brazil
+ is included, but commented out. Compared with the diff I sent out last week,
+ this version also includes attributions for the sources for the changes
+ (in much the same format as ado used, but the html tags have not been
+ checked, verified, or used in any way at all, so if there are errors there,
+ please let me know.)
+
+
+Release data2011k - 2011-09-20 17:54:03 -0400
+
+ [not summarized]
+
+
+Release data2011j - 2011-09-12 09:22:49 -0400
+
+ (contemporary changes for Samoa; past changes for Kenya, Uganda, and
+ Tanzania); there are also two spelling corrections to comments in
+ the australasia file (with thanks to Christos Zoulas).
+
+
+Release 2011i - 2011-08-29 05:56:32 -0400
+
+ [not summarized]
+
+
+Release data2011h - 2011-06-15 18:41:48 -0400
+
+ Russia and Curaçao changes
+
+
+Release 2011g - 2011-04-25 09:07:22 -0400
+
+ update the rules for Egypt to reflect its abandonment of DST this year
+
+
+Release 2011f - 2011-04-06 17:14:53 -0400
+
+ [not summarized]
+
+
+Release 2011e - 2011-03-31 16:04:38 -0400
+
+ Morocco, Chile, and tz-link changes
+
+
+Release 2011d - 2011-03-14 09:18:01 -0400
+
+ changes that impact present-day time stamps in Cuba, Samoa, and Turkey
+
+
+Release 2011c - 2011-03-07 09:30:09 -0500
+
+ These do affect current time stamps in Chile and Annette Island, Canada.
+
+
+Release 2011b - 2011-02-07 08:44:50 -0500
+
+ [not summarized]
+
+
+Release 2011a - 2011-01-24 10:30:16 -0500
+
+ [not summarized]
+
+
+Release data2010o - 2010-11-01 09:18:23 -0400
+
+ change to the end of DST in Fiji in 2011
+
+
+Release 2010n - 2010-10-25 08:19:17 -0400
+
+ [not summarized]
+
+
+Release 2010m - 2010-09-27 09:24:48 -0400
+
+ Hong Kong, Vostok, and zic.c changes
+
+
+Release 2010l - 2010-08-16 06:57:25 -0400
+
+ [not summarized]
+
+
+Release 2010k - 2010-07-26 10:42:27 -0400
+
+ [not summarized]
+
+
+Release 2010j - 2010-05-10 09:07:48 -0400
+
+ changes for Bahía de Banderas and for version naming
+
+
+Release data2010i - 2010-04-16 18:50:45 -0400
+
+ the end of DST in Morocco on 2010-08-08
+
+
+Release data2010h - 2010-04-05 09:58:56 -0400
+
+ [not summarized]
+
+
+Release data2010g - 2010-03-24 11:14:53 -0400
+
+ [not summarized]
+
+
+Release 2010f - 2010-03-22 09:45:46 -0400
+
+ [not summarized]
+
+
+Release data2010e - 2010-03-08 14:24:27 -0500
+
+ corrects the Dhaka bug found by Danvin Ruangchan
+
+
+Release data2010d - 2010-03-06 07:26:01 -0500
+
+ [not summarized]
+
+
+Release 2010c - 2010-03-01 09:20:58 -0500
+
+ changes including KRE's suggestion for earlier initialization of
+ "goahead" and "goback" structure elements
+
+
+Release code2010a - 2010-02-16 10:40:04 -0500
+
+ [not summarized]
+
+
+Release data2010b - 2010-01-20 12:37:01 -0500
+
+ Mexico changes
+
+
+Release data2010a - 2010-01-18 08:30:04 -0500
+
+ changes to Dhaka
+
+
+Release data2009u - 2009-12-26 08:32:28 -0500
+
+ changes to DST in Bangladesh
+
+
+Release 2009t - 2009-12-21 13:24:27 -0500
+
+ [not summarized]
+
+
+Release data2009s - 2009-11-14 10:26:32 -0500
+
+ (cosmetic) Antarctica change and the DST-in-Fiji-in-2009-and-2010 change
+
+
+Release 2009r - 2009-11-09 10:10:31 -0500
+
+ "antarctica" and "tz-link.htm" changes
+
+
+Release 2009q - 2009-11-02 09:12:40 -0500
+
+ with two corrections as reported by Eric Muller and Philip Newton
+
+
+Release data2009p - 2009-10-23 15:05:27 -0400
+
+ Argentina (including San Luis) changes (with the correction from
+ Mariano Absatz)
+
+
+Release data2009o - 2009-10-14 16:49:38 -0400
+
+ Samoa (commentary only), Pakistan, and Bangladesh changes
+
+
+Release data2009n - 2009-09-22 15:13:38 -0400
+
+ added commentary for Argentina and a change to the end of DST in
+ 2009 in Pakistan
+
+
+Release data2009m - 2009-09-03 10:23:43 -0400
+
+ Samoa and Palestine changes
+
+
+Release data2009l - 2009-08-14 09:13:07 -0400
+
+ Samoa (comments only) and Egypt
+
+
+Release 2009k - 2009-07-20 09:46:08 -0400
+
+ [not summarized]
+
+
+Release data2009j - 2009-06-15 06:43:59 -0400
+
+ Bangladesh change (with a short turnaround since the DST change is
+ impending)
+
+
+Release 2009i - 2009-06-08 09:21:22 -0400
+
+ updating for DST in Bangladesh this year
+
+
+Release 2009h - 2009-05-26 09:19:14 -0400
+
+ [not summarized]
+
+
+Release data2009g - 2009-04-20 16:34:07 -0400
+
+ Cairo
+
+
+Release data2009f - 2009-04-10 11:00:52 -0400
+
+ correct DST in Pakistan
+
+
+Release 2009e - 2009-04-06 09:08:11 -0400
+
+ [not summarized]
+
+
+Release 2009d - 2009-03-23 09:38:12 -0400
+
+ Morocco, Tunisia, Argentina, and American Astronomical Society changes
+
+
+Release data2009c - 2009-03-16 09:47:51 -0400
+
+ change to the start of Cuban DST
+
+
+Release 2009b - 2009-02-09 11:15:22 -0500
+
+ [not summarized]
+
+
+Release 2009a - 2009-01-21 10:09:39 -0500
+
+ [not summarized]
+
+
+Release data2008i - 2008-10-21 12:10:25 -0400
+
+ southamerica and zone.tab files, with Argentina DST rule changes and
+ United States zone reordering and recommenting
+
+
+Release 2008h - 2008-10-13 07:33:56 -0400
+
+ [not summarized]
+
+
+Release 2008g - 2008-10-06 09:03:18 -0400
+
+ Fix a broken HTML anchor and update Brazil's DST transitions;
+ there's also a slight reordering of information in tz-art.htm.
+
+
+Release data2008f - 2008-09-09 22:33:26 -0400
+
+ [not summarized]
+
+
+Release 2008e - 2008-07-28 14:11:17 -0400
+
+ changes by Arthur David Olson and Jesper Nørgaard Welen
+
+
+Release data2008d - 2008-07-07 09:51:38 -0400
+
+ changes by Arthur David Olson, Paul Eggert, and Rodrigo Severo
+
+
+Release data2008c - 2008-05-19 17:48:03 -0400
+
+ Pakistan, Morocco, and Mongolia
+
+
+Release data2008b - 2008-03-24 08:30:59 -0400
+
+ including renaming Asia/Calcutta to Asia/Kolkata, with a backward
+ link provided
+
+
+Release 2008a - 2008-03-08 05:42:16 -0500
+
+ [not summarized]
+
+
+Release 2007k - 2007-12-31 10:25:22 -0500
+
+ most importantly, changes to the "southamerica" file based on
+ Argentina's readoption of daylight saving time
+
+
+Release 2007j - 2007-12-03 09:51:01 -0500
+
+ 1. eliminate the "P" (parameter) macro;
+
+ 2. the "noncontroversial" changes circulated on the time zone
+ mailing list (less the changes to "logwtmp.c");
+
+ 3. eliminate "too many transition" errors when "min" is used in time
+ zone rules;
+
+ 4. changes by Paul Eggert (including updated information for Venezuela).
+
+
+Release data2007i - 2007-10-30 10:28:11 -0400
+
+ changes for Cuba and Syria
+
+
+Release 2007h - 2007-10-01 10:05:51 -0400
+
+ changes by Paul Eggert, as well as an updated link to the ICU
+ project in tz-link.htm
+
+
+Release 2007g - 2007-08-20 10:47:59 -0400
+
+ changes by Paul Eggert
+
+ The "leapseconds" file has been updated to incorporate the most
+ recent International Earth Rotation and Reference Systems Service
+ (IERS) bulletin.
+
+ There's an addition to tz-art.htm regarding the television show "Medium".
+
+
+Release 2007f - 2007-05-07 10:46:46 -0400
+
+ changes by Paul Eggert (including Haiti, Turks and Caicos, and New
+ Zealand)
+
+ changes to zic.c to allow hour values greater than 24 (along with
+ Paul's improved time value overflow checking)
+
+
+Release 2007e - 2007-04-02 10:11:52 -0400
+
+ Syria and Honduras changes by Paul Eggert
+
+ zic.c variable renaming changes by Arthur David Olson
+
+
+Release 2007d - 2007-03-20 08:48:30 -0400
+
+ changes by Paul Eggert
+
+ the elimination of white space at the ends of lines
+
+
+Release 2007c - 2007-02-26 09:09:37 -0500
+
+ changes by Paul Eggert
+
+
+Release 2007b - 2007-02-12 09:34:20 -0500
+
+ Paul Eggert's proposed change to the quotation handling logic in zic.c.
+
+ changes to the commentary in "leapseconds" reflecting the IERS
+ announcement that there is to be no positive leap second at the end
+ of June 2007.
+
+
+Release 2007a - 2007-01-08 12:28:29 -0500
+
+ changes by Paul Eggert
+
+ Derick Rethan's Asmara change
+
+ Oscar van Vlijmen's Easter Island local mean time change
+
+ symbolic link changes
+
+
+Release 2006p - 2006-11-27 08:54:27 -0500
+
+ changes by Paul Eggert
+
+
+Release 2006o - 2006-11-06 09:18:07 -0500
+
+ changes by Paul Eggert
+
+
+Release 2006n - 2006-10-10 11:32:06 -0400
+
+ changes by Paul Eggert
+
+
+Release 2006m - 2006-10-02 15:32:35 -0400
+
+ changes for Uruguay, Palestine, and Egypt by Paul Eggert
+
+ (minimalist) changes to zic.8 to clarify "until" information
+
+
+Release data2006l - 2006-09-18 12:58:11 -0400
+
+ Paul's best-effort work on this coming weekend's Egypt time change
+
+
+Release 2006k - 2006-08-28 12:19:09 -0400
+
+ changes by Paul Eggert
+
+
+Release 2006j - 2006-08-21 09:56:32 -0400
+
+ changes by Paul Eggert
+
+
+Release code2006i - 2006-08-07 12:30:55 -0400
+
+ localtime.c fixes
+
+ Ken Pizzini's conversion script
+
+
+Release code2006h - 2006-07-24 09:19:37 -0400
+
+ adds public domain notices to four files
+
+ includes a fix for transition times being off by a second
+
+ adds a new recording to the "arts" file (information courtesy Colin Bowern)
+
+
+Release 2006g - 2006-05-08 17:18:09 -0400
+
+ northamerica changes by Paul Eggert
+
+
+Release 2006f - 2006-05-01 11:46:00 -0400
+
+ a missing version number problem is fixed (with thanks to Bradley
+ White for catching the problem)
+
+
+Release 2006d - 2006-04-17 14:33:43 -0400
+
+ changes by Paul Eggert
+
+ added new items to tz-arts.htm that were found by Paul
+
+
+Release 2006c - 2006-04-03 10:09:32 -0400
+
+ two sets of data changes by Paul Eggert
+
+ a fencepost error fix in zic.c
+
+ changes to zic.c and the "europe" file to minimize differences
+ between output produced by the old 32-bit zic and the new 64-bit
+ version
+
+
+Release 2006b - 2006-02-20 10:08:18 -0500
+ [tz32code2006b + tz64code2006b + tzdata2006b]
+
+ 64-bit code
+
+ All SCCS IDs were bumped to "8.1" for this release.
+
+
+Release 2006a - 2006-01-30 08:59:31 -0500
+
+ changes by Paul Eggert (in particular, Indiana time zone moves)
+
+ an addition to the zic manual page to describe how special-case
+ transitions are handled
+
+
+Release 2005r - 2005-12-27 09:27:13 -0500
+
+ Canadian changes by Paul Eggert
+
+ They also add "<pre>" directives to time zone data files and reflect
+ changes to warning message logic in "zdump.c" (but with calls to
+ "gettext" kept unbundled at the suggestion of Ken Pizzini).
+
+
+Release 2005q - 2005-12-13 09:17:09 -0500
+
+ Nothing earth-shaking here:
+ 1. Electronic mail addresses have been removed.
+ 2. Casts of the return value of exit have been removed.
+ 3. Casts of the argument of is.* macros have been added.
+ 4. Indentation in one section of zic.c has been fixed.
+ 5. References to dead URLs in the data files have been dealt with.
+
+
+Release 2005p - 2005-12-05 10:30:53 -0500
+
+ "systemv", "tz-link.htm", and "zdump.c" changes
+ (less the casts of arguments to the is* macros)
+
+
+Release 2005o - 2005-11-28 10:55:26 -0500
+
+ Georgia, Cuba, Nicaragua, and Jordan changes by Paul Eggert
+
+ zdump.c lint fixes by Arthur David Olson
+
+
+Release 2005n - 2005-10-03 09:44:09 -0400
+
+ changes by Paul Eggert (both the Uruguay changes and the Kyrgyzstan
+ et al. changes)
+
+
+Release 2005m - 2005-08-29 12:15:40 -0400
+
+ changes by Paul Eggert (with a small tweak to the tz-art change)
+
+ a declaration of an unused variable has been removed from zdump.c
+
+
+Release 2005l - 2005-08-22 12:06:39 -0400
+
+ changes by Paul Eggert
+
+ overflow/underflow checks by Arthur David Olson, minus changes to
+ the "Theory" file about the pending addition of 64-bit data (I grow
+ less confident of the changes being accepted with each passing day,
+ and the changes no longer increase the data files nine-fold--there's
+ less than a doubling in size by my local Sun's reckoning)
+
+
+Release 2005k - 2005-07-14 14:14:24 -0400
+
+ The "leapseconds" file has been edited to reflect the recently
+ announced leap second at the end of 2005.
+
+ I've also deleted electronic mail addresses from the files as an
+ anti-spam measure.
+
+
+Release 2005j - 2005-06-13 14:34:13 -0400
+
+ These reflect changes to limit the length of time zone abbreviations
+ and the characters used in those abbreviations.
+
+ There are also changes to handle POSIX-style "quoted" time zone
+ environment variables.
+
+ The changes were circulated on the time zone mailing list; the only
+ change since then was the removal of a couple of minimum-length of
+ abbreviation checks.
+
+
+Release data2005i - 2005-04-21 15:04:16 -0400
+
+ changes (most importantly to Nicaragua and Haiti) by Paul Eggert
+
+
+Release 2005h - 2005-04-04 11:24:47 -0400
+
+ changes by Paul Eggert
+
+ minor changes to Makefile and zdump.c to produce more useful output
+ when doing a "make typecheck"
+
+
+Release 2005g - 2005-03-14 10:11:21 -0500
+
+ changes by Paul Eggert (a change to current DST rules in Uruguay and
+ an update to a link to time zone software)
+
+
+Release 2005f - 2005-03-01 08:45:32 -0500
+
+ data and documentation changes by Paul Eggert
+
+
+Release 2005e - 2005-02-10 15:59:44 -0500
+
+ [not summarized]
+
+
+Release code2005d - 2005-01-31 09:21:47 -0500
+
+ make zic complain about links to links if the -v flag is used
+
+ have "make public" do more code checking
+
+ add an include to "localtime.c" for the benefit of gcc systems
+
+
+Release 2005c - 2005-01-17 18:36:29 -0500
+
+ get better results when mktime runs on a system where time_t is double
+
+ changes to the data files (most importantly to Paraguay)
+
+
+Release 2005b - 2005-01-10 09:19:54 -0500
+
+ Get localtime and gmtime working on systems with exotic time_t types.
+
+ Update the leap second commentary in the "leapseconds" file.
+
+
+Release 2005a - 2005-01-01 13:13:44 -0500
+
+ [not summarized]
+
+
+Release code2004i - 2004-12-14 13:42:58 -0500
+
+ Deal with systems where time_t is unsigned.
+
+
+Release code2004h - 2004-12-07 11:40:18 -0500
+
+ 64-bit-time_t changes
+
+
+Release 2004g - 2004-11-02 09:06:01 -0500
+
+ update to Cuba (taking effect this weekend)
+
+ other changes by Paul Eggert
+
+ correction of the spelling of Oslo
+
+ changed versions of difftime.c and private.h
+
+
+Release code2004f - 2004-10-21 10:25:22 -0400
+
+ Cope with wide-ranging tm_year values.
+
+
+Release 2004e - 2004-10-11 14:47:21 -0400
+
+ Brazil/Argentina/Israel changes by Paul Eggert
+
+ changes to tz-link.htm by Paul
+
+ one small fix to Makefile
+
+
+Release 2004d - 2004-09-22 08:27:29 -0400
+
+ Avoid overflow problems when TM_YEAR_BASE is added to an integer.
+
+
+Release 2004c - 2004-08-11 12:06:26 -0400
+
+ asctime-related changes
+
+ (variants of) some of the documentation changes suggested by Paul Eggert
+
+
+Release 2004b - 2004-07-19 14:33:35 -0400
+
+ data changes by Paul Eggert - most importantly, updates for Argentina
+
+
+Release 2004a - 2004-05-27 12:00:47 -0400
+
+ changes by Paul Eggert
+
+ Handle DST transitions that occur at the end of a month in some
+ years but at the start of the following month in other years.
+
+ Add a copy of the correspondence that's the basis for claims about
+ DST in the Navajo Nation.
+
+
+Release 2003e - 2003-12-15 09:36:47 -0500
+
+ changes by Arthur David Olson (primarily code changes)
+
+ changes by Paul Eggert (primarily data changes)
+
+ minor changes to "Makefile" and "northamerica" (in the latter case,
+ optimization of the "Toronto" rules)
+
+
+Release 2003d - 2003-10-06 09:34:44 -0400
+
+ changes by Paul Eggert
+
+
+Release 2003c - 2003-09-16 10:47:05 -0400
+
+ Fix bad returns in zic.c's inleap function.
+ Thanks to Bradley White for catching the problem!
+
+
+Release 2003b - 2003-09-16 07:13:44 -0400
+
+ Add a "--version" option (and documentation) to the zic and zdump commands.
+
+ changes to overflow/underflow checking in zic
+
+ a localtime typo fix.
+
+ Update the leapseconds and tz-art.htm files.
+
+
+Release 2003a - 2003-03-24 09:30:54 -0500
+
+ changes by Paul Eggert
+
+ a few additions and modifications to the tz-art.htm file
+
+
+Release 2002d - 2002-10-15 13:12:42 -0400
+
+ changes by Paul Eggert, less the "Britain (UK)" change in iso3166.tab
+
+ There's also a new time zone quote in "tz-art.htm".
+
+
+Release 2002c - 2002-04-04 11:55:20 -0500
+
+ changes by Paul Eggert
+
+ Change zic.c to avoid creating symlinks to files that don't exist.
+
+
+Release 2002b - 2002-01-28 12:56:03 -0500
+
+ [These change notes are for Release 2002a, which was corrupted.
+ 2002b was a corrected version of 2002a.]
+
+ changes by Paul Eggert
+
+ Update the "leapseconds" file to note that there'll be no leap
+ second at the end of June, 2002.
+
+ Change "zic.c" to deal with a problem in handling the "Asia/Bishkek" zone.
+
+ Change to "difftime.c" to avoid sizeof problems.
+
+
+Release 2001d - 2001-10-09 13:31:32 -0400
+
+ changes by Paul Eggert
+
+
+Release 2001c - 2001-06-05 13:59:55 -0400
+
+ changes by Paul Eggert and Andrew Brown
+
+
+Release 2001b - 2001-04-05 16:44:38 -0400
+
+ changes by Paul Eggert (modulo jnorgard's typo fix)
+
+ tz-art.htm has been HTMLified.
+
+
+Release 2001a - 2001-03-13 12:57:44 -0500
+
+ changes by Paul Eggert
+
+ An addition to the "leapseconds" file: comments with the text of the
+ latest IERS leap second notice.
+
+ Trailing white space has been removed from data file lines, and
+ repeated spaces in "Rule Jordan" lines in the "asia" file have been
+ converted to tabs.
+
+
+Release 2000h - 2000-12-14 15:33:38 -0500
+
+ changes by Paul Eggert
+
+ one typo fix in the "art" file
+
+ With providence, this is the last update of the millennium.
+
+
+Release 2000g - 2000-10-10 11:35:22 -0400
+
+ changes by Paul Eggert
+
+ correction of John Mackin's name submitted by Robert Elz
+
+ Garry Shandling's Daylight Saving Time joke (!?!) from the recent
+ Emmy Awards broadcast.
+
+
+Release 2000f - 2000-08-10 09:31:58 -0400
+
+ changes by Paul Eggert
+
+ Added information in "tz-art.htm" on a Seinfeld reference to DST.
+
+ Error checking and messages in the "yearistype" script have been
+ improved.
+
+
+Release 2000e - 2000-07-31 09:27:54 -0400
+
+ data changes by Paul Eggert
+
+ a change to the default value of the defined constant HAVE_STRERROR
+
+ the addition of a Dave Barry quote on DST to the tz-arts file
+
+
+Release 2000d - 2000-04-20 15:43:04 -0400
+
+ changes to the documentation and code of strftime for C99 conformance
+
+ a bug fix for date.c
+
+ These are based on (though modified from) changes by Paul Eggert.
+
+
+Release 2000c - 2000-03-04 10:31:43 -0500
+
+ changes by Paul Eggert
+
+
+Release 2000b - 2000-02-21 12:16:29 -0500
+
+ changes by Paul Eggert and Joseph Myers
+
+ modest tweaks to the tz-art.htm and tz-link.htm files
+
+
+Release 2000a - 2000-01-18 09:21:26 -0500
+
+ changes by Paul Eggert
+
+ The two hypertext documents have also been renamed.
+
+
+Release code1999i-data1999j - 1999-11-15 18:43:22 -0500
+
+ Paul Eggert's changes
+
+ additions to the "zic" manual page and the "Arts.htm" file
+
+
+Release code1999h-data1999i - 1999-11-08 14:55:21 -0500
+
+ [not summarized]
+
+
+Release data1999h - 1999-10-07 03:50:29 -0400
+
+ changes by Paul Eggert to "europe" (most importantly, fixing
+ Lithuania and Estonia)
+
+
+Release 1999g - 1999-09-28 11:06:18 -0400
+
+ data changes by Paul Eggert (most importantly, the change for
+ Lebanon that buys correctness for this coming Sunday)
+
+ The "code" file contains changes to "Makefile" and "checktab.awk" to
+ allow better checking of time zone files before they are published.
+
+
+Release 1999f - 1999-09-23 09:48:14 -0400
+
+ changes by Arthur David Olson and Paul Eggert
+
+
+Release 1999e - 1999-08-17 15:20:54 -0400
+
+ changes circulated by Paul Eggert, although the change to handling
+ of DST-specifying time zone names has been commented out for now
+ (search for "XXX" in "localtime.c" for details). These files also
+ do not make any changes to the start of DST in Brazil.
+
+ In addition to Paul's changes, there are updates to "Arts.htm" and
+ cleanups of URLs.
+
+
+Release 1999d - 1999-03-30 11:31:07 -0500
+
+ changes by Paul Eggert
+
+ The Makefile's "make public" rule has also been changed to do a test
+ compile of each individual time zone data file (which should help
+ avoid problems such as the one we had with Nicosia).
+
+
+Release 1999c - 1999-03-25 09:47:47 -0500
+
+ changes by Paul Eggert, most importantly the change for Chile.
+
+
+Release 1999b - 1999-02-01 17:51:44 -0500
+
+ changes by Paul Eggert
+
+ code changes (suggested by Mani Varadarajan, mani at be.com) for
+ correct handling of symbolic links when building using a relative directory
+
+ code changes to generate correct messages for failed links
+
+ updates to the URLs in Arts.htm
+
+
+Release 1999a - 1999-01-19 16:20:29 -0500
+
+ error message internationalizations and corrections in zic.c and
+ zdump.c (as suggested by Vladimir Michl, vladimir.michl at upol.cz,
+ to whom thanks!)
+
+
+Release code1998h-data1998i - 1998-10-01 09:56:10 -0400
+
+ changes for Brazil, Chile, and Germany
+
+ support for use of "24:00" in the input files for the time zone compiler
+
+
+Release code1998g-data1998h - 1998-09-24 10:50:28 -0400
+
+ changes by Paul Eggert
+
+ correction to a define in the "private.h" file
+
+
+Release data1998g - 1998-08-11 03:28:35 -0000
+ [tzdata1998g.tar.gz is missing!]
+
+ Lithuanian change provided by mgedmin at pub.osf.it
+
+ Move creation of the GMT link with Etc/GMT to "etcetera" (from
+ "backward") to ensure that the GMT file is created even where folks
+ don't want the "backward" links (as suggested by Paul Eggert).
+
+
+Release data1998f - 1998-07-20 13:50:00 -0000
+ [tzdata1998f.tar.gz is missing!]
+
+ Update the "leapseconds" file to include the newly-announced
+ insertion at the end of 1998.
+
+
+Release code1998f - 1998-06-01 10:18:31 -0400
+
+ addition to localtime.c by Guy Harris
+
+
+Release 1998e - 1998-05-28 09:56:26 -0400
+
+ The Makefile is changed to produce zoneinfo-posix rather than
+ zoneinfo/posix, and to produce zoneinfo-leaps rather than
+ zoneinfo/right.
+
+ data changes by Paul Eggert
+
+ changes from Guy Harris to provide asctime_r and ctime_r
+
+ A usno1998 file (substantially identical to usno1997) has been added.
+
+
+Release 1998d - 1998-05-14 11:58:34 -0400
+
+ changes to comments (in particular, elimination of references to CIA maps).
+ "Arts.htm", "WWW.htm", "asia", and "australasia" are the only places
+ where changes occur.
+
+
+Release 1998c - 1998-02-28 12:32:26 -0500
+
+ changes by Paul Eggert (save the "French correction," on which I'll
+ wait for the dust to settle)
+
+ symlink changes
+
+ changes and additions to Arts.htm
+
+
+Release 1998b - 1998-01-17 14:31:51 -0500
+
+ URL cleanups and additions
+
+
+Release 1998a - 1998-01-13 12:37:35 -0500
+
+ changes by Paul Eggert
+
+
+Release code1997i-data1997k - 1997-12-29 09:53:41 -0500
+
+ changes by Paul Eggert, with minor modifications from Arthur David
+ Olson to make the files more browser friendly
+
+
+Release code1997h-data1997j - 1997-12-18 17:47:35 -0500
+
+ minor changes to put "TZif" at the start of each time zone information file
+
+ a rule has also been added to the Makefile so you can
+ make zones
+ to just recompile the zone information files (rather than doing a
+ full "make install" with its other effects).
+
+
+Release data1997i - 1997-10-07 08:45:38 -0400
+
+ changes to Africa by Paul Eggert
+
+
+Release code1997g-data1997h - 1997-09-04 16:56:54 -0400
+
+ corrections for Uruguay (and other locations)
+
+ Arthur David Olson's simple-minded fix allowing mktime to both
+ correctly handle leap seconds and correctly handle tm_sec values
+ upon which arithmetic has been performed.
+
+
+Release code1997f-data1997g - 1997-07-19 13:15:02 -0400
+
+ Paul Eggert's updates
+
+ a small change to a function prototype;
+
+ "Music" has been renamed "Arts.htm", HTMLified, and augmented to
+ include information on Around the World in Eighty Days.
+
+
+Release code1997e-data1997f - 1997-05-03 18:52:34 -0400
+
+ fixes to zic's error handling
+
+ changes inspired by the item circulated on Slovenia
+
+ The description of Web resources has been HTMLified for browsing
+ convenience.
+
+ A new piece of tz-related music has been added to the "Music" file.
+
+
+Release code1997d-data1997e - 1997-03-29 12:48:52 -0500
+
+ Paul Eggert's latest suggestions
+
+
+Release code1997c-data1997d - 1997-03-07 20:37:54 -0500
+
+ changes to "zic.c" to correct performance of the "-s" option
+
+ a new file "usno1997"
+
+
+Release data1997c - 1997-03-04 09:58:18 -0500
+
+ changes in Israel
+
+
+Release 1997b - 1997-02-27 18:34:19 -0500
+
+ The data file incorporates the 1997 leap second.
+
+ The code file incorporates Arthur David Olson's take on the
+ zic/multiprocessor/directory-creation situation.
+
+
+Release 1997a - 1997-01-21 09:11:10 -0500
+
+ Paul Eggert's Antarctica (and other changes)
+
+ Arthur David Olson finessed the "getopt" issue by checking against
+ both -1 and EOF (regardless of POSIX, SunOS 4.1.1's manual says -1
+ is returned while SunOS 5.5's manual says EOF is returned).
+
+
+Release code1996o-data1996n - 1996-12-27 21:42:05 -0500
+
+ Paul Eggert's latest changes
+
+
+Release code1996n - 1996-12-16 09:42:02 -0500
+
+ link snapping fix from Bruce Evans (via Garrett Wollman)
+
+
+Release data1996m - 1996-11-24 02:37:34 -0000
+ [tzdata1996m.tar.gz is missing!]
+
+ Paul Eggert's batch of changes
+
+
+Release code1996m-data1996l - 1996-11-05 14:00:12 -0500
+
+ No functional changes here; the files have simply been changed to
+ make more use of ISO style dates in comments. The names of the above
+ files now include the year in full.
+
+
+Release code96l - 1996-09-08 17:12:20 -0400
+
+ tzcode96k was missing a couple of pieces.
+
+
+Release 96k - 1996-09-08 16:06:22 -0400
+
+ the latest round of changes from Paul Eggert
+
+ the recent Year 2000 material
+
+
+Release code96j - 1996-07-30 13:18:53 -0400
+
+ Set sp->typecnt as suggested by Timothy Patrick Murphy.
+
+
+Release code96i - 1996-07-27 20:11:35 -0400
+
+ Paul's suggested patch for strftime %V week numbers
+
+
+Release data96i - 1996-07-01 18:13:04 -0400
+
+ "northamerica" and "europe" changes by Paul Eggert
+
+
+Release code96h - 1996-06-05 08:02:21 -0400
+
+ fix for handling transitions specified in Universal Time
+
+ Some "public domain" notices have also been added.
+
+
+Release code96g - 1996-05-16 14:00:26 -0400
+
+ fix for the simultaneous-DST-and-zone-change challenge
+
+
+Release data96h - 1996-05-09 17:40:51 -0400
+
+ changes by Paul Eggert
+
+
+Release code96f-data96g - 1996-05-03 03:09:59 -0000
+ [tzcode96f.tar.gz + tzdata96g.tar.gz are both missing!]
+
+ The changes get us some of the way to fixing the problems noted in Paul
+ Eggert's letter yesterday (in addition to a few others). The approach
+ has been to make zic a bit smarter about figuring out what time zone
+ abbreviations apply just after the time specified in the "UNTIL" part
+ of a zone line. Putting the smarts in zic means avoiding having
+ transition times show up in both "Zone" lines and "Rule" lines, which
+ in turn avoids multiple transition time entries in time zone files.
+ (This also makes the zic input files such as "europe" a bit shorter and
+ should ease maintenance.)
+
+
+Release data96f - 1996-04-19 19:20:03 -0000
+ [tzdata96f.tar.gz is missing!]
+
+ The only changes are to the "northamerica" file; the time zone
+ abbreviation for Denver is corrected to MST (and MDT), and the
+ comments for Mexico have been updated.
+
+
+Release data96e - 1996-03-19 17:37:26 -0500
+
+ Proposals by Paul Eggert, in particular the Portugal change that
+ comes into play at the end of this month.
+
+
+Release data96d - 1996-03-18 20:49:39 -0500
+
+ [not summarized]
+
+
+Release code96e - 1996-02-29 15:43:27 -0000
+ [tzcode96e.tar.gz is missing!]
+
+ internationalization changes and the fix to the documentation for strftime
+
+
+Release code96d-data96c - 1996-02-12 11:05:27 -0500
+
+ The "code" file simply updates Bob Kridle's electronic address.
+
+ The "data" file updates rules for Mexico.
+
+
+Release data96b - 1996-01-27 15:44:42 -0500
+
+ Kiribati change
+
+
+Release code96c - 1996-01-16 16:58:15 -0500
+
+ leap-year streamlining and binary-search changes
+
+ fix to newctime.3
+
+
+Release code96b - 1996-01-10 20:42:39 -0500
+
+ fixes and enhancements from Paul Eggert, including code that
+ emulates the behavior of recent versions of the SunOS "date"
+ command.
+
+
+Release 96a - 1996-01-06 09:08:24 -0500
+
+ Israel updates
+
+ fixes to strftime.c for correct ISO 8601 week number generation,
+ plus support for two new formats ('G' and 'g') to give ISO 8601 year
+ numbers (which are not necessarily the same as calendar year numbers)
+
+
+Release code95i-data95m - 1995-12-21 12:46:47 -0500
+
+ The latest revisions from Paul Eggert are included, the usno1995
+ file has been updated, and a new file ("WWW") covering useful URLs
+ has been added.
+
+
+Release code95h-data95l - 1995-12-19 18:10:12 -0500
+
+ A simplification of a macro definition, a change to data for Sudan,
+ and (for last minute shoppers) notes in the "Music" file on the CD
+ "Old Man Time".
+
+
+Release code95g-data95k - 1995-10-30 10:32:47 -0500
+
+ (slightly reformatted) 8-bit-clean proposed patch
+
+ minor patch: US/Eastern -> America/New_York
+
+ snapshot of the USNO's latest data ("usno1995")
+
+ some other minor cleanups
+
+
+Release code95f-data95j - 1995-10-28 21:01:34 -0000
+ [tzcode95f.tar.gz + tzdata95j.tar.gz are both missing!]
+
+ European cleanups
+
+ support for 64-bit time_t's
+
+ optimization in localtime.c
+
+
+Release code95e - 1995-10-13 13:23:57 -0400
+
+ the mktime change to scan from future to past when trying to find time zone
+ offsets
+
+
+Release data95i - 1995-09-26 10:43:26 -0400
+
+ For Canada/Central, guess that the Sun customer's "one week too
+ early" was just a approximation, and the true error is one month
+ too early. This is consistent with the rest of Canada.
+
+
+Release data95h - 1995-09-21 11:26:48 -0400
+
+ latest changes from Paul Eggert
+
+
+Release code95d - 1995-09-14 11:14:45 -0400
+
+ the addition of a "Music" file, which documents four recorded
+ versions of the tune "Save That Time".
+
+
+Release data95g - 1995-09-01 17:21:36 -0400
+
+ "yearistype" correction
+
+
+Release data95f - 1995-08-28 20:46:56 -0400
+
+ Paul Eggert's change to the australasia file
+
+
+Release data95e - 1995-07-08 18:02:34 -0400
+
+ The only change is a leap second at the end of this year.
+ Thanks to Bradley White for forwarding news on the leap second.
+
+
+Release data95d - 1995-07-03 13:26:22 -0400
+
+ Paul Eggert's changes
+
+
+Release data95c - 1995-07-02 19:19:28 -0400
+
+ changes to "asia", "backward", "europe", and "southamerica"
+ (read: northamericacentrics need not apply)
+
+
+Release code95c - 1995-03-13 14:00:46 -0500
+
+ one-line fix for sign extension problems in detzcode
+
+
+Release 95b - 1995-03-04 11:22:38 -0500
+
+ Minor changes in both:
+
+ The "code" file contains a workaround for the lack of "unistd.h" in
+ Microsoft C++ version 7.
+
+ The "data" file contains a fixed "Link" for America/Shiprock.
+
+
+Release 94h - 1994-12-10 12:51:14 -0500
+
+ The files:
+
+ * incorporate the changes to "zdump" and "date" to make changes to
+ the "TZ" environment variable permanent;
+
+ * incorporate the table changes by Paul Eggert;
+
+ * include (and document) support for universal time specifications in
+ data files - but do not (yet) include use of this feature in the
+ data files.
+
+ Think of this as "TZ Classic" - the software has been set up not to break if
+ universal time shows up in its input, and data entries have been
+ left as is so as not to break existing implementations.
+
+
+Release data94f - 1994-08-20 12:56:09 -0400
+
+ (with thanks!) the latest data updates from Paul Eggert
+
+
+Release data94e - 1994-06-04 13:13:53 -0400
+
+ [not summarized]
+
+
+Release code94g - 1994-05-05 12:14:07 -0400
+
+ fix missing "optind.c" and a reference to it in the Makefile
+
+
+Release code94f - 1994-05-05 13:00:33 -0000
+ [tzcode94f.tar.gz is missing!]
+
+ changes to avoid overflow in difftime, as well as changes to cope
+ with the 52/53 challenge in strftime
+
+
+Release code94e - 1994-03-30 23:32:59 -0500
+
+ change for the benefit of PCTS
+
+
+Release 94d - 1994-02-24 15:42:25 -0500
+
+ Avoid clashes with POSIX semantics for zones such as GMT+4.
+
+ Some other very minor housekeeping is also present.
+
+
+Release code94c - 1994-02-10 08:52:40 -0500
+
+ Fix bug where mkdirs was broken unless you compile with
+ -fwritable-strings (which is generally losing to do).
+
+
+Release 94b - 1994-02-07 10:04:33 -0500
+
+ work by Paul Eggert who notes:
+
+ I found another book of time zone histories by E W Whitman; it's not
+ as extensive as Shanks but has a few goodies of its own. I used it
+ to update the tables. I also fixed some more as a result of
+ correspondence with Adam David and Peter Ilieve, and move some stray
+ links from 'europe' to 'backward'. I corrected some scanning errors
+ in usno1989.
+
+ As far as the code goes, I fixed zic to allow years in the range
+ INT_MIN to INT_MAX; this fixed a few boundary conditions around 1900.
+ And I cleaned up the zic documentation a little bit.
+
+
+Release data94a - 1994-02-03 08:58:54 -0500
+
+ It simply incorporates the recently announced leap second into the
+ "leapseconds" file.
+
+
+Release 93g - 1993-11-22 17:28:27 -0500
+
+ Paul Eggert has provided a good deal of historic information (based
+ on Shanks), and there are some code changes to deal with the buglets
+ that crawled out in dealing with the new information.
+
+
+Release 93f - 1993-10-15 12:27:46 -0400
+
+ Paul Eggert's changes
+
+
+Release 93e - 1993-09-05 21:21:44 -0400
+
+ This has updated data for Israel, England, and Kwajalein. There's
+ also an update to "zdump" to cope with Kwajalein's 24-hour jump.
+ Thanks to Paul Eggert and Peter Ilieve for the changes.
+
+
+Release 93d - 1993-06-17 23:34:17 -0400
+
+ new fix and new data on Israel
+
+
+Release 93c - 1993-06-06 19:31:55 -0400
+
+ [not summarized]
+
+
+Release 93b - 1993-02-02 14:53:58 -0500
+
+ updated "leapseconds" file
+
+
+Release 93 - 1993-01-08 07:01:06 -0500
+
+ At kre's suggestion, the package has been split in two - a code piece
+ (which also includes documentation) that's only of use to folks who
+ want to recompile things and a data piece useful to anyone who can
+ run "zic".
+
+ The new version has a few changes to the data files, a few
+ portability changes, and an off-by-one fix (with thanks to
+ Tom Karzes at deshaw.com for providing a description and a
+ solution).
+
+
+Release 92c - 1992-11-21 17:35:36 -0000
+ [tz92c.tar.Z is missing!]
+
+ The fallout from the latest round of DST transitions.
+
+ There are changes for Portugal, Saskatchewan, and "Pacific-New";
+ there's also a change to "zic.c" that makes it portable to more systems.
+
+
+Release 92 - 1992-04-25 18:17:03 -0000
+ [tz92.tar.Z is missing!]
+
+ By popular demand (well, at any rate, following a request by kre at munnari)
+
+
+The 1989 update of the time zone package featured:
+
+ * POSIXization (including interpretation of POSIX-style TZ environment
+ variables, provided by Guy Harris),
+ * ANSIfication (including versions of "mktime" and "difftime"),
+ * SVIDulation (an "altzone" variable)
+ * MACHination (the "gtime" function)
+ * corrections to some time zone data (including corrections to the rules
+ for Great Britain and New Zealand)
+ * reference data from the United States Naval Observatory for folks who
+ want to do additional time zones
+ * and the 1989 data for Saudi Arabia.
+
+ (Since this code will be treated as "part of the implementation" in some
+ places and as "part of the application" in others, there's no good way to
+ name functions, such as timegm, that are not part of the proposed ANSI C
+ standard; such functions have kept their old, underscore-free names in this
+ update.)
+
+ And the "dysize" function has disappeared; it was present to allow
+ compilation of the "date" command on old BSD systems, and a version of "date"
+ is now provided in the package. The "date" command is not created when you
+ "make all" since it may lack options provided by the version distributed with
+ your operating system, or may not interact with the system in the same way
+ the native version does.
+
+ Since POSIX frowns on correct leap second handling, the default behavior of
+ the "zic" command (in the absence of a "-L" option) has been changed to omit
+ leap second information from its output files.
+
+
+-----
+Notes
+
+This file contains copies of the part of each release announcement
+that talks about the changes in that release. The text has been
+adapted and reformatted for the purposes of this file.
+
+Traditionally a release R consists of a pair of tarball files,
+tzcodeR.tar.gz and tzdataR.tar.gz. However, some releases (e.g.,
+code2010a, data2012c) consist of just one or the other tarball, and a
+few (e.g., code2012c-data2012d) have tarballs with mixed version
+numbers. Recent releases also come in an experimental format
+consisting of a single tarball tzdb-R.tar.lz with extra data.
+
+Release time stamps are taken from the release's commit (for newer,
+Git-based releases), from the newest file in the tarball (for older
+releases, where this info is available) or from the email announcing
+the release (if all else fails; these are marked with a time zone of
+-0000 and an "is missing!" comment).
+
+Earlier versions of the code and data were not announced on the tz
+list and are not summarized here.
+
+This file is in the public domain.
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/contrib/tzdata/README b/contrib/tzdata/README
new file mode 100644
index 0000000..8a09aa2
--- /dev/null
+++ b/contrib/tzdata/README
@@ -0,0 +1,71 @@
+README for the tz distribution
+
+"What time is it?" -- Richard Deacon as The King
+"Any time you want it to be." -- Frank Baxter as The Scientist
+ (from the Bell System film "About Time")
+
+The Time Zone Database (often called tz or zoneinfo) contains code and
+data that represent the history of local time for many representative
+locations around the globe. It is updated periodically to reflect
+changes made by political bodies to time zone boundaries, UTC offsets,
+and daylight-saving rules.
+
+Here is a recipe for acquiring, building, installing, and testing the
+tz distribution on a GNU/Linux or similar host.
+
+To acquire the distribution, run the following shell commands:
+
+ mkdir tz
+ cd tz
+ wget --retr-symlinks 'ftp://ftp.iana.org/tz/tz*-latest.tar.gz'
+ gzip -dc tzcode-latest.tar.gz | tar -xf -
+ gzip -dc tzdata-latest.tar.gz | tar -xf -
+
+Alternatively, the following shell commands acquire the same
+distribution, with extra data useful for regression testing:
+
+ wget --retr-symlinks 'ftp://ftp.iana.org/tz/tzdb-latest.tar.lz'
+ lzip -dc tzdb-latest.tar.lz | tar -xf -
+
+Be sure to read the comments in "Makefile" and make any changes needed
+to make things right for your system, especially if you are using some
+platform other than GNU/Linux. Then run the following commands,
+substituting your desired installation directory for "$HOME/tzdir":
+
+ make TOPDIR=$HOME/tzdir install
+ $HOME/tzdir/etc/zdump -v America/Los_Angeles
+
+Historical local time information has been included here to:
+
+* provide a compendium of data about the history of civil time
+ that is useful even if not 100% accurate;
+
+* give an idea of the variety of local time rules that have
+ existed in the past and thus an idea of the variety that may be
+ expected in the future;
+
+* provide a test of the generality of the local time rule description
+ system.
+
+The information in the time zone data files is by no means authoritative;
+fixes and enhancements are welcome. Please see the file CONTRIBUTING
+for details.
+
+Thanks to these Time Zone Caballeros who've made major contributions to the
+time conversion package: Keith Bostic; Bob Devine; Paul Eggert; Robert Elz;
+Guy Harris; Mark Horton; John Mackin; and Bradley White. Thanks also to
+Michael Bloom, Art Neilson, Stephen Prince, John Sovereign, and Frank Wales
+for testing work, and to Gwillim Law for checking local mean time data.
+Thanks in particular to Arthur David Olson, the project's founder and first
+maintainer, to whom the time zone community owes the greatest debt of all.
+None of them are responsible for remaining errors.
+
+Look in <ftp://ftp.iana.org/tz/releases/> for updated versions of these files.
+
+Please send comments or information to tz@iana.org.
+
+-----
+
+This file is in the public domain, so clarified as of 2009-05-17 by
+Arthur David Olson. The other files in this distribution are either
+public domain or BSD licensed; see the file LICENSE for details.
diff --git a/contrib/tzdata/Theory b/contrib/tzdata/Theory
new file mode 100644
index 0000000..677baf6
--- /dev/null
+++ b/contrib/tzdata/Theory
@@ -0,0 +1,840 @@
+Theory and pragmatics of the tz code and data
+
+
+----- Outline -----
+
+ Scope of the tz database
+ Names of time zone rules
+ Time zone abbreviations
+ Accuracy of the tz database
+ Time and date functions
+ Calendrical issues
+ Time and time zones on Mars
+
+
+----- Scope of the tz database -----
+
+The tz database attempts to record the history and predicted future of
+all computer-based clocks that track civil time. To represent this
+data, the world is partitioned into regions whose clocks all agree
+about time stamps that occur after the somewhat-arbitrary cutoff point
+of the POSIX Epoch (1970-01-01 00:00:00 UTC). For each such region,
+the database records all known clock transitions, and labels the region
+with a notable location. Although 1970 is a somewhat-arbitrary
+cutoff, there are significant challenges to moving the cutoff earlier
+even by a decade or two, due to the wide variety of local practices
+before computer timekeeping became prevalent.
+
+Clock transitions before 1970 are recorded for each such location,
+because most systems support time stamps before 1970 and could
+misbehave if data entries were omitted for pre-1970 transitions.
+However, the database is not designed for and does not suffice for
+applications requiring accurate handling of all past times everywhere,
+as it would take far too much effort and guesswork to record all
+details of pre-1970 civil timekeeping.
+
+As described below, reference source code for using the tz database is
+also available. The tz code is upwards compatible with POSIX, an
+international standard for UNIX-like systems. As of this writing, the
+current edition of POSIX is:
+
+ The Open Group Base Specifications Issue 7
+ IEEE Std 1003.1, 2013 Edition
+ <http://pubs.opengroup.org/onlinepubs/9699919799/>
+
+
+
+----- Names of time zone rules -----
+
+Each of the database's time zone rules has a unique name.
+Inexperienced users are not expected to select these names unaided.
+Distributors should provide documentation and/or a simple selection
+interface that explains the names; for one example, see the 'tzselect'
+program in the tz code. The Unicode Common Locale Data Repository
+<http://cldr.unicode.org/> contains data that may be useful for other
+selection interfaces.
+
+The time zone rule naming conventions attempt to strike a balance
+among the following goals:
+
+ * Uniquely identify every region where clocks have agreed since 1970.
+ This is essential for the intended use: static clocks keeping local
+ civil time.
+
+ * Indicate to experts where that region is.
+
+ * Be robust in the presence of political changes. For example, names
+ of countries are ordinarily not used, to avoid incompatibilities
+ when countries change their name (e.g. Zaire->Congo) or when
+ locations change countries (e.g. Hong Kong from UK colony to
+ China).
+
+ * Be portable to a wide variety of implementations.
+
+ * Use a consistent naming conventions over the entire world.
+
+Names normally have the form AREA/LOCATION, where AREA is the name
+of a continent or ocean, and LOCATION is the name of a specific
+location within that region. North and South America share the same
+area, 'America'. Typical names are 'Africa/Cairo', 'America/New_York',
+and 'Pacific/Honolulu'.
+
+Here are the general rules used for choosing location names,
+in decreasing order of importance:
+
+ Use only valid POSIX file name components (i.e., the parts of
+ names other than '/'). Do not use the file name
+ components '.' and '..'. Within a file name component,
+ use only ASCII letters, '.', '-' and '_'. Do not use
+ digits, as that might create an ambiguity with POSIX
+ TZ strings. A file name component must not exceed 14
+ characters or start with '-'. E.g., prefer 'Brunei'
+ to 'Bandar_Seri_Begawan'. Exceptions: see the discussion
+ of legacy names below.
+ A name must not be empty, or contain '//', or start or end with '/'.
+ Do not use names that differ only in case. Although the reference
+ implementation is case-sensitive, some other implementations
+ are not, and they would mishandle names differing only in case.
+ If one name A is an initial prefix of another name AB (ignoring case),
+ then B must not start with '/', as a regular file cannot have
+ the same name as a directory in POSIX. For example,
+ 'America/New_York' precludes 'America/New_York/Bronx'.
+ Uninhabited regions like the North Pole and Bouvet Island
+ do not need locations, since local time is not defined there.
+ There should typically be at least one name for each ISO 3166-1
+ officially assigned two-letter code for an inhabited country
+ or territory.
+ If all the clocks in a region have agreed since 1970,
+ don't bother to include more than one location
+ even if subregions' clocks disagreed before 1970.
+ Otherwise these tables would become annoyingly large.
+ If a name is ambiguous, use a less ambiguous alternative;
+ e.g. many cities are named San José and Georgetown, so
+ prefer 'Costa_Rica' to 'San_Jose' and 'Guyana' to 'Georgetown'.
+ Keep locations compact. Use cities or small islands, not countries
+ or regions, so that any future time zone changes do not split
+ locations into different time zones. E.g. prefer 'Paris'
+ to 'France', since France has had multiple time zones.
+ Use mainstream English spelling, e.g. prefer 'Rome' to 'Roma', and
+ prefer 'Athens' to the Greek 'Αθήνα' or the Romanized 'Athína'.
+ The POSIX file name restrictions encourage this rule.
+ Use the most populous among locations in a zone,
+ e.g. prefer 'Shanghai' to 'Beijing'. Among locations with
+ similar populations, pick the best-known location,
+ e.g. prefer 'Rome' to 'Milan'.
+ Use the singular form, e.g. prefer 'Canary' to 'Canaries'.
+ Omit common suffixes like '_Islands' and '_City', unless that
+ would lead to ambiguity. E.g. prefer 'Cayman' to
+ 'Cayman_Islands' and 'Guatemala' to 'Guatemala_City',
+ but prefer 'Mexico_City' to 'Mexico' because the country
+ of Mexico has several time zones.
+ Use '_' to represent a space.
+ Omit '.' from abbreviations in names, e.g. prefer 'St_Helena'
+ to 'St._Helena'.
+ Do not change established names if they only marginally
+ violate the above rules. For example, don't change
+ the existing name 'Rome' to 'Milan' merely because
+ Milan's population has grown to be somewhat greater
+ than Rome's.
+ If a name is changed, put its old spelling in the 'backward' file.
+ This means old spellings will continue to work.
+
+The file 'zone1970.tab' lists geographical locations used to name time
+zone rules. It is intended to be an exhaustive list of names for
+geographic regions as described above; this is a subset of the names
+in the data. Although a 'zone1970.tab' location's longitude
+corresponds to its LMT offset with one hour for every 15 degrees east
+longitude, this relationship is not exact.
+
+Older versions of this package used a different naming scheme,
+and these older names are still supported.
+See the file 'backward' for most of these older names
+(e.g., 'US/Eastern' instead of 'America/New_York').
+The other old-fashioned names still supported are
+'WET', 'CET', 'MET', and 'EET' (see the file 'europe').
+
+Older versions of this package defined legacy names that are
+incompatible with the first rule of location names, but which are
+still supported. These legacy names are mostly defined in the file
+'etcetera'. Also, the file 'backward' defines the legacy names
+'GMT0', 'GMT-0', 'GMT+0' and 'Canada/East-Saskatchewan', and the file
+'northamerica' defines the legacy names 'EST5EDT', 'CST6CDT',
+'MST7MDT', and 'PST8PDT'.
+
+Excluding 'backward' should not affect the other data. If
+'backward' is excluded, excluding 'etcetera' should not affect the
+remaining data.
+
+
+----- Time zone abbreviations -----
+
+When this package is installed, it generates time zone abbreviations
+like 'EST' to be compatible with human tradition and POSIX.
+Here are the general rules used for choosing time zone abbreviations,
+in decreasing order of importance:
+
+ Use three or more characters that are ASCII alphanumerics or '+' or '-'.
+ Previous editions of this database also used characters like
+ ' ' and '?', but these characters have a special meaning to
+ the shell and cause commands like
+ set `date`
+ to have unexpected effects.
+ Previous editions of this rule required upper-case letters,
+ but the Congressman who introduced Chamorro Standard Time
+ preferred "ChST", so lower-case letters are now allowed.
+ Also, POSIX from 2001 on relaxed the rule to allow '-', '+',
+ and alphanumeric characters from the portable character set
+ in the current locale. In practice ASCII alphanumerics and
+ '+' and '-' are safe in all locales.
+
+ In other words, in the C locale the POSIX extended regular
+ expression [-+[:alnum:]]{3,} should match the abbreviation.
+ This guarantees that all abbreviations could have been
+ specified by a POSIX TZ string.
+
+ Use abbreviations that are in common use among English-speakers,
+ e.g. 'EST' for Eastern Standard Time in North America.
+ We assume that applications translate them to other languages
+ as part of the normal localization process; for example,
+ a French application might translate 'EST' to 'HNE'.
+
+ For zones whose times are taken from a city's longitude, use the
+ traditional xMT notation, e.g. 'PMT' for Paris Mean Time.
+ The only name like this in current use is 'GMT'.
+
+ Use 'LMT' for local mean time of locations before the introduction
+ of standard time; see "Scope of the tz database".
+
+ If there is no common English abbreviation, use numeric offsets like
+ -05 and +0830 that are generated by zic's %z notation.
+
+ [The remaining guidelines predate the introduction of %z.
+ They are problematic as they mean tz data entries invent
+ notation rather than record it. These guidelines are now
+ deprecated and the plan is to gradually move to %z for
+ inhabited locations and to "-00" for uninhabited locations.]
+
+ If there is no common English abbreviation, abbreviate the English
+ translation of the usual phrase used by native speakers.
+ If this is not available or is a phrase mentioning the country
+ (e.g. "Cape Verde Time"), then:
+
+ When a country is identified with a single or principal zone,
+ append 'T' to the country's ISO code, e.g. 'CVT' for
+ Cape Verde Time. For summer time append 'ST';
+ for double summer time append 'DST'; etc.
+ Otherwise, take the first three letters of an English place
+ name identifying each zone and append 'T', 'ST', etc.
+ as before; e.g. 'VLAST' for VLAdivostok Summer Time.
+
+ Use UT (with time zone abbreviation '-00') for locations while
+ uninhabited. The leading '-' is a flag that the time
+ zone is in some sense undefined; this notation is
+ derived from Internet RFC 3339.
+
+Application writers should note that these abbreviations are ambiguous
+in practice: e.g. 'CST' has a different meaning in China than
+it does in the United States. In new applications, it's often better
+to use numeric UT offsets like '-0600' instead of time zone
+abbreviations like 'CST'; this avoids the ambiguity.
+
+
+----- Accuracy of the tz database -----
+
+The tz database is not authoritative, and it surely has errors.
+Corrections are welcome and encouraged; see the file CONTRIBUTING.
+Users requiring authoritative data should consult national standards
+bodies and the references cited in the database's comments.
+
+Errors in the tz database arise from many sources:
+
+ * The tz database predicts future time stamps, and current predictions
+ will be incorrect after future governments change the rules.
+ For example, if today someone schedules a meeting for 13:00 next
+ October 1, Casablanca time, and tomorrow Morocco changes its
+ daylight saving rules, software can mess up after the rule change
+ if it blithely relies on conversions made before the change.
+
+ * The pre-1970 entries in this database cover only a tiny sliver of how
+ clocks actually behaved; the vast majority of the necessary
+ information was lost or never recorded. Thousands more zones would
+ be needed if the tz database's scope were extended to cover even
+ just the known or guessed history of standard time; for example,
+ the current single entry for France would need to split into dozens
+ of entries, perhaps hundreds. And in most of the world even this
+ approach would be misleading due to widespread disagreement or
+ indifference about what times should be observed. In her 2015 book
+ "The Global Transformation of Time, 1870-1950", Vanessa Ogle writes
+ "Outside of Europe and North America there was no system of time
+ zones at all, often not even a stable landscape of mean times,
+ prior to the middle decades of the twentieth century". See:
+ Timothy Shenk, Booked: A Global History of Time. Dissent 2015-12-17
+ https://www.dissentmagazine.org/blog/booked-a-global-history-of-time-vanessa-ogle
+
+ * Most of the pre-1970 data entries come from unreliable sources, often
+ astrology books that lack citations and whose compilers evidently
+ invented entries when the true facts were unknown, without
+ reporting which entries were known and which were invented.
+ These books often contradict each other or give implausible entries,
+ and on the rare occasions when they are checked they are
+ typically found to be incorrect.
+
+ * For the UK the tz database relies on years of first-class work done by
+ Joseph Myers and others; see <http://www.polyomino.org.uk/british-time/>.
+ Other countries are not done nearly as well.
+
+ * Sometimes, different people in the same city would maintain clocks
+ that differed significantly. Railway time was used by railroad
+ companies (which did not always agree with each other),
+ church-clock time was used for birth certificates, etc.
+ Often this was merely common practice, but sometimes it was set by law.
+ For example, from 1891 to 1911 the UT offset in France was legally
+ 0:09:21 outside train stations and 0:04:21 inside.
+
+ * Although a named location in the tz database stands for the
+ containing region, its pre-1970 data entries are often accurate for
+ only a small subset of that region. For example, Europe/London
+ stands for the United Kingdom, but its pre-1847 times are valid
+ only for locations that have London's exact meridian, and its 1847
+ transition to GMT is known to be valid only for the L&NW and the
+ Caledonian railways.
+
+ * The tz database does not record the earliest time for which a zone's
+ data entries are thereafter valid for every location in the region.
+ For example, Europe/London is valid for all locations in its
+ region after GMT was made the standard time, but the date of
+ standardization (1880-08-02) is not in the tz database, other than
+ in commentary. For many zones the earliest time of validity is
+ unknown.
+
+ * The tz database does not record a region's boundaries, and in many
+ cases the boundaries are not known. For example, the zone
+ America/Kentucky/Louisville represents a region around the city of
+ Louisville, the boundaries of which are unclear.
+
+ * Changes that are modeled as instantaneous transitions in the tz
+ database were often spread out over hours, days, or even decades.
+
+ * Even if the time is specified by law, locations sometimes
+ deliberately flout the law.
+
+ * Early timekeeping practices, even assuming perfect clocks, were
+ often not specified to the accuracy that the tz database requires.
+
+ * Sometimes historical timekeeping was specified more precisely
+ than what the tz database can handle. For example, from 1909 to
+ 1937 Netherlands clocks were legally UT +00:19:32.13, but the tz
+ database cannot represent the fractional second.
+
+ * Even when all the timestamp transitions recorded by the tz database
+ are correct, the tz rules that generate them may not faithfully
+ reflect the historical rules. For example, from 1922 until World
+ War II the UK moved clocks forward the day following the third
+ Saturday in April unless that was Easter, in which case it moved
+ clocks forward the previous Sunday. Because the tz database has no
+ way to specify Easter, these exceptional years are entered as
+ separate tz Rule lines, even though the legal rules did not change.
+
+ * The tz database models pre-standard time using the proleptic Gregorian
+ calendar and local mean time (LMT), but many people used other
+ calendars and other timescales. For example, the Roman Empire used
+ the Julian calendar, and had 12 varying-length daytime hours with a
+ non-hour-based system at night.
+
+ * Early clocks were less reliable, and data entries do not represent
+ this unreliability.
+
+ * As for leap seconds, civil time was not based on atomic time before
+ 1972, and we don't know the history of earth's rotation accurately
+ enough to map SI seconds to historical solar time to more than
+ about one-hour accuracy. See: Morrison LV, Stephenson FR.
+ Historical values of the Earth's clock error Delta T and the
+ calculation of eclipses. J Hist Astron. 2004;35:327-36
+ <http://adsabs.harvard.edu/full/2004JHA....35..327M>;
+ Historical values of the Earth's clock error. J Hist Astron. 2005;36:339
+ <http://adsabs.harvard.edu/full/2005JHA....36..339M>.
+
+ * The relationship between POSIX time (that is, UTC but ignoring leap
+ seconds) and UTC is not agreed upon after 1972. Although the POSIX
+ clock officially stops during an inserted leap second, at least one
+ proposed standard has it jumping back a second instead; and in
+ practice POSIX clocks more typically either progress glacially during
+ a leap second, or are slightly slowed while near a leap second.
+
+ * The tz database does not represent how uncertain its information is.
+ Ideally it would contain information about when data entries are
+ incomplete or dicey. Partial temporal knowledge is a field of
+ active research, though, and it's not clear how to apply it here.
+
+In short, many, perhaps most, of the tz database's pre-1970 and future
+time stamps are either wrong or misleading. Any attempt to pass the
+tz database off as the definition of time should be unacceptable to
+anybody who cares about the facts. In particular, the tz database's
+LMT offsets should not be considered meaningful, and should not prompt
+creation of zones merely because two locations differ in LMT or
+transitioned to standard time at different dates.
+
+
+----- Time and date functions -----
+
+The tz code contains time and date functions that are upwards
+compatible with those of POSIX.
+
+POSIX has the following properties and limitations.
+
+* In POSIX, time display in a process is controlled by the
+ environment variable TZ. Unfortunately, the POSIX TZ string takes
+ a form that is hard to describe and is error-prone in practice.
+ Also, POSIX TZ strings can't deal with other (for example, Israeli)
+ daylight saving time rules, or situations where more than two
+ time zone abbreviations are used in an area.
+
+ The POSIX TZ string takes the following form:
+
+ stdoffset[dst[offset][,date[/time],date[/time]]]
+
+ where:
+
+ std and dst
+ are 3 or more characters specifying the standard
+ and daylight saving time (DST) zone names.
+ Starting with POSIX.1-2001, std and dst may also be
+ in a quoted form like "<UTC+10>"; this allows
+ "+" and "-" in the names.
+ offset
+ is of the form '[+-]hh:[mm[:ss]]' and specifies the
+ offset west of UT. 'hh' may be a single digit; 0<=hh<=24.
+ The default DST offset is one hour ahead of standard time.
+ date[/time],date[/time]
+ specifies the beginning and end of DST. If this is absent,
+ the system supplies its own rules for DST, and these can
+ differ from year to year; typically US DST rules are used.
+ time
+ takes the form 'hh:[mm[:ss]]' and defaults to 02:00.
+ This is the same format as the offset, except that a
+ leading '+' or '-' is not allowed.
+ date
+ takes one of the following forms:
+ Jn (1<=n<=365)
+ origin-1 day number not counting February 29
+ n (0<=n<=365)
+ origin-0 day number counting February 29 if present
+ Mm.n.d (0[Sunday]<=d<=6[Saturday], 1<=n<=5, 1<=m<=12)
+ for the dth day of week n of month m of the year,
+ where week 1 is the first week in which day d appears,
+ and '5' stands for the last week in which day d appears
+ (which may be either the 4th or 5th week).
+ Typically, this is the only useful form;
+ the n and Jn forms are rarely used.
+
+ Here is an example POSIX TZ string, for US Pacific time using rules
+ appropriate from 1987 through 2006:
+
+ TZ='PST8PDT,M4.1.0/02:00,M10.5.0/02:00'
+
+ This POSIX TZ string is hard to remember, and mishandles time stamps
+ before 1987 and after 2006. With this package you can use this
+ instead:
+
+ TZ='America/Los_Angeles'
+
+* POSIX does not define the exact meaning of TZ values like "EST5EDT".
+ Typically the current US DST rules are used to interpret such values,
+ but this means that the US DST rules are compiled into each program
+ that does time conversion. This means that when US time conversion
+ rules change (as in the United States in 1987), all programs that
+ do time conversion must be recompiled to ensure proper results.
+
+* The TZ environment variable is process-global, which makes it hard
+ to write efficient, thread-safe applications that need access
+ to multiple time zones.
+
+* In POSIX, there's no tamper-proof way for a process to learn the
+ system's best idea of local wall clock. (This is important for
+ applications that an administrator wants used only at certain times -
+ without regard to whether the user has fiddled the "TZ" environment
+ variable. While an administrator can "do everything in UTC" to get
+ around the problem, doing so is inconvenient and precludes handling
+ daylight saving time shifts - as might be required to limit phone
+ calls to off-peak hours.)
+
+* POSIX provides no convenient and efficient way to determine the UT
+ offset and time zone abbreviation of arbitrary time stamps,
+ particularly for time zone settings that do not fit into the
+ POSIX model.
+
+* POSIX requires that systems ignore leap seconds.
+
+* The tz code attempts to support all the time_t implementations
+ allowed by POSIX. The time_t type represents a nonnegative count of
+ seconds since 1970-01-01 00:00:00 UTC, ignoring leap seconds.
+ In practice, time_t is usually a signed 64- or 32-bit integer; 32-bit
+ signed time_t values stop working after 2038-01-19 03:14:07 UTC, so
+ new implementations these days typically use a signed 64-bit integer.
+ Unsigned 32-bit integers are used on one or two platforms,
+ and 36-bit and 40-bit integers are also used occasionally.
+ Although earlier POSIX versions allowed time_t to be a
+ floating-point type, this was not supported by any practical
+ systems, and POSIX.1-2013 and the tz code both require time_t
+ to be an integer type.
+
+These are the extensions that have been made to the POSIX functions:
+
+* The "TZ" environment variable is used in generating the name of a file
+ from which time zone information is read (or is interpreted a la
+ POSIX); "TZ" is no longer constrained to be a three-letter time zone
+ name followed by a number of hours and an optional three-letter
+ daylight time zone name. The daylight saving time rules to be used
+ for a particular time zone are encoded in the time zone file;
+ the format of the file allows U.S., Australian, and other rules to be
+ encoded, and allows for situations where more than two time zone
+ abbreviations are used.
+
+ It was recognized that allowing the "TZ" environment variable to
+ take on values such as "America/New_York" might cause "old" programs
+ (that expect "TZ" to have a certain form) to operate incorrectly;
+ consideration was given to using some other environment variable
+ (for example, "TIMEZONE") to hold the string used to generate the
+ time zone information file name. In the end, however, it was decided
+ to continue using "TZ": it is widely used for time zone purposes;
+ separately maintaining both "TZ" and "TIMEZONE" seemed a nuisance;
+ and systems where "new" forms of "TZ" might cause problems can simply
+ use TZ values such as "EST5EDT" which can be used both by
+ "new" programs (a la POSIX) and "old" programs (as zone names and
+ offsets).
+
+* The code supports platforms with a UT offset member in struct tm,
+ e.g., tm_gmtoff.
+
+* The code supports platforms with a time zone abbreviation member in
+ struct tm, e.g., tm_zone.
+
+* Since the "TZ" environment variable can now be used to control time
+ conversion, the "daylight" and "timezone" variables are no longer
+ needed. (These variables are defined and set by "tzset"; however, their
+ values will not be used by "localtime.")
+
+* Functions tzalloc, tzfree, localtime_rz, and mktime_z for
+ more-efficient thread-safe applications that need to use
+ multiple time zones. The tzalloc and tzfree functions
+ allocate and free objects of type timezone_t, and localtime_rz
+ and mktime_z are like localtime_r and mktime with an extra
+ timezone_t argument. The functions were inspired by NetBSD.
+
+* A function "tzsetwall" has been added to arrange for the system's
+ best approximation to local wall clock time to be delivered by
+ subsequent calls to "localtime." Source code for portable
+ applications that "must" run on local wall clock time should call
+ "tzsetwall();" if such code is moved to "old" systems that don't
+ provide tzsetwall, you won't be able to generate an executable program.
+ (These time zone functions also arrange for local wall clock time to be
+ used if tzset is called - directly or indirectly - and there's no "TZ"
+ environment variable; portable applications should not, however, rely
+ on this behavior since it's not the way SVR2 systems behave.)
+
+* Negative time_t values are supported, on systems where time_t is signed.
+
+* These functions can account for leap seconds, thanks to Bradley White.
+
+Points of interest to folks with other systems:
+
+* Code compatible with this package is already part of many platforms,
+ including GNU/Linux, Android, the BSDs, Chromium OS, Cygwin, AIX, iOS,
+ BlackBery 10, macOS, Microsoft Windows, OpenVMS, and Solaris.
+ On such hosts, the primary use of this package
+ is to update obsolete time zone rule tables.
+ To do this, you may need to compile the time zone compiler
+ 'zic' supplied with this package instead of using the system 'zic',
+ since the format of zic's input is occasionally extended,
+ and a platform may still be shipping an older zic.
+
+* The UNIX Version 7 "timezone" function is not present in this package;
+ it's impossible to reliably map timezone's arguments (a "minutes west
+ of GMT" value and a "daylight saving time in effect" flag) to a
+ time zone abbreviation, and we refuse to guess.
+ Programs that in the past used the timezone function may now examine
+ tzname[localtime(&clock)->tm_isdst] to learn the correct time
+ zone abbreviation to use. Alternatively, use
+ localtime(&clock)->tm_zone if this has been enabled.
+
+* The 4.2BSD gettimeofday function is not used in this package.
+ This formerly let users obtain the current UTC offset and DST flag,
+ but this functionality was removed in later versions of BSD.
+
+* In SVR2, time conversion fails for near-minimum or near-maximum
+ time_t values when doing conversions for places that don't use UT.
+ This package takes care to do these conversions correctly.
+ A comment in the source code tells how to get compatibly wrong
+ results.
+
+The functions that are conditionally compiled if STD_INSPIRED is defined
+should, at this point, be looked on primarily as food for thought. They are
+not in any sense "standard compatible" - some are not, in fact, specified in
+*any* standard. They do, however, represent responses of various authors to
+standardization proposals.
+
+Other time conversion proposals, in particular the one developed by folks at
+Hewlett Packard, offer a wider selection of functions that provide capabilities
+beyond those provided here. The absence of such functions from this package
+is not meant to discourage the development, standardization, or use of such
+functions. Rather, their absence reflects the decision to make this package
+contain valid extensions to POSIX, to ensure its broad acceptability. If
+more powerful time conversion functions can be standardized, so much the
+better.
+
+
+----- Interface stability -----
+
+The tz code and data supply the following interfaces:
+
+ * A set of zone names as per "Names of time zone rules" above.
+
+ * Library functions described in "Time and date functions" above.
+
+ * The programs tzselect, zdump, and zic, documented in their man pages.
+
+ * The format of zic input files, documented in the zic man page.
+
+ * The format of zic output files, documented in the tzfile man page.
+
+ * The format of zone table files, documented in zone1970.tab.
+
+ * The format of the country code file, documented in iso3166.tab.
+
+When these interfaces are changed, an effort is made to preserve
+backward compatibility. For example, tz data files typically do not
+rely on recently-added zic features, so that users can run older zic
+versions to process newer data files.
+
+Interfaces not listed above are less stable. For example, users
+should not rely on particular UT offsets or abbreviations for time
+stamps, as data entries are often based on guesswork and these guesses
+may be corrected or improved.
+
+
+----- Calendrical issues -----
+
+Calendrical issues are a bit out of scope for a time zone database,
+but they indicate the sort of problems that we would run into if we
+extended the time zone database further into the past. An excellent
+resource in this area is Nachum Dershowitz and Edward M. Reingold,
+Calendrical Calculations: Third Edition, Cambridge University Press (2008)
+<http://emr.cs.iit.edu/home/reingold/calendar-book/third-edition/>.
+Other information and sources are given below. They sometimes disagree.
+
+
+France
+
+Gregorian calendar adopted 1582-12-20.
+French Revolutionary calendar used 1793-11-24 through 1805-12-31,
+and (in Paris only) 1871-05-06 through 1871-05-23.
+
+
+Russia
+
+From Chris Carrier (1996-12-02):
+On 1929-10-01 the Soviet Union instituted an "Eternal Calendar"
+with 30-day months plus 5 holidays, with a 5-day week.
+On 1931-12-01 it changed to a 6-day week; in 1934 it reverted to the
+Gregorian calendar while retaining the 6-day week; on 1940-06-27 it
+reverted to the 7-day week. With the 6-day week the usual days
+off were the 6th, 12th, 18th, 24th and 30th of the month.
+(Source: Evitiar Zerubavel, _The Seven Day Circle_)
+
+
+Mark Brader reported a similar story in "The Book of Calendars", edited
+by Frank Parise (1982, Facts on File, ISBN 0-8719-6467-8), page 377. But:
+
+From: Petteri Sulonen (via Usenet)
+Date: 14 Jan 1999 00:00:00 GMT
+...
+
+If your source is correct, how come documents between 1929 and 1940 were
+still dated using the conventional, Gregorian calendar?
+
+I can post a scan of a document dated December 1, 1934, signed by
+Yenukidze, the secretary, on behalf of Kalinin, the President of the
+Executive Committee of the Supreme Soviet, if you like.
+
+
+
+Sweden (and Finland)
+
+From: Mark Brader
+Subject: Re: Gregorian reform - a part of locale?
+<news:1996Jul6.012937.29190@sq.com>
+Date: 1996-07-06
+
+In 1700, Denmark made the transition from Julian to Gregorian. Sweden
+decided to *start* a transition in 1700 as well, but rather than have one of
+those unsightly calendar gaps :-), they simply decreed that the next leap
+year after 1696 would be in 1744 - putting the whole country on a calendar
+different from both Julian and Gregorian for a period of 40 years.
+
+However, in 1704 something went wrong and the plan was not carried through;
+they did, after all, have a leap year that year. And one in 1708. In 1712
+they gave it up and went back to Julian, putting 30 days in February that
+year!...
+
+Then in 1753, Sweden made the transition to Gregorian in the usual manner,
+getting there only 13 years behind the original schedule.
+
+(A previous posting of this story was challenged, and Swedish readers
+produced the following references to support it: "Tideräkning och historia"
+by Natanael Beckman (1924) and "Tid, en bok om tideräkning och
+kalenderväsen" by Lars-Olof Lodén (1968).
+
+
+Grotefend's data
+
+From: "Michael Palmer" [with one obvious typo fixed]
+Subject: Re: Gregorian Calendar (was Re: Another FHC related question
+Newsgroups: soc.genealogy.german
+Date: Tue, 9 Feb 1999 02:32:48 -800
+...
+
+The following is a(n incomplete) listing, arranged chronologically, of
+European states, with the date they converted from the Julian to the
+Gregorian calendar:
+
+04/15 Oct 1582 - Italy (with exceptions), Spain, Portugal, Poland (Roman
+ Catholics and Danzig only)
+09/20 Dec 1582 - France, Lorraine
+
+21 Dec 1582/
+ 01 Jan 1583 - Holland, Brabant, Flanders, Hennegau
+10/21 Feb 1583 - bishopric of Liege (Lüttich)
+13/24 Feb 1583 - bishopric of Augsburg
+04/15 Oct 1583 - electorate of Trier
+05/16 Oct 1583 - Bavaria, bishoprics of Freising, Eichstedt, Regensburg,
+ Salzburg, Brixen
+13/24 Oct 1583 - Austrian Oberelsaß and Breisgau
+20/31 Oct 1583 - bishopric of Basel
+02/13 Nov 1583 - duchy of Jülich-Berg
+02/13 Nov 1583 - electorate and city of Köln
+04/15 Nov 1583 - bishopric of Würzburg
+11/22 Nov 1583 - electorate of Mainz
+16/27 Nov 1583 - bishopric of Strassburg and the margraviate of Baden
+17/28 Nov 1583 - bishopric of Münster and duchy of Cleve
+14/25 Dec 1583 - Steiermark
+
+06/17 Jan 1584 - Austria and Bohemia
+11/22 Jan 1584 - Lucerne, Uri, Schwyz, Zug, Freiburg, Solothurn
+12/23 Jan 1584 - Silesia and the Lausitz
+22 Jan/
+ 02 Feb 1584 - Hungary (legally on 21 Oct 1587)
+ Jun 1584 - Unterwalden
+01/12 Jul 1584 - duchy of Westfalen
+
+16/27 Jun 1585 - bishopric of Paderborn
+
+14/25 Dec 1590 - Transylvania
+
+22 Aug/
+ 02 Sep 1612 - duchy of Prussia
+
+13/24 Dec 1614 - Pfalz-Neuburg
+
+ 1617 - duchy of Kurland (reverted to the Julian calendar in
+ 1796)
+
+ 1624 - bishopric of Osnabrück
+
+ 1630 - bishopric of Minden
+
+15/26 Mar 1631 - bishopric of Hildesheim
+
+ 1655 - Kanton Wallis
+
+05/16 Feb 1682 - city of Strassburg
+
+18 Feb/
+ 01 Mar 1700 - Protestant Germany (including Swedish possessions in
+ Germany), Denmark, Norway
+30 Jun/
+ 12 Jul 1700 - Gelderland, Zutphen
+10 Nov/
+ 12 Dec 1700 - Utrecht, Overijssel
+
+31 Dec 1700/
+ 12 Jan 1701 - Friesland, Groningen, Zürich, Bern, Basel, Geneva,
+ Turgau, and Schaffhausen
+
+ 1724 - Glarus, Appenzell, and the city of St. Gallen
+
+01 Jan 1750 - Pisa and Florence
+
+02/14 Sep 1752 - Great Britain
+
+17 Feb/
+ 01 Mar 1753 - Sweden
+
+1760-1812 - Graubünden
+
+The Russian empire (including Finland and the Baltic states) did not
+convert to the Gregorian calendar until the Soviet revolution of 1917.
+
+Source: H. Grotefend, _Taschenbuch der Zeitrechnung des deutschen
+Mittelalters und der Neuzeit_, herausgegeben von Dr. O. Grotefend
+(Hannover: Hahnsche Buchhandlung, 1941), pp. 26-28.
+
+
+----- Time and time zones on Mars -----
+
+Some people's work schedules use Mars time. Jet Propulsion Laboratory
+(JPL) coordinators have kept Mars time on and off at least since 1997
+for the Mars Pathfinder mission. Some of their family members have
+also adapted to Mars time. Dozens of special Mars watches were built
+for JPL workers who kept Mars time during the Mars Exploration
+Rovers mission (2004). These timepieces look like normal Seikos and
+Citizens but use Mars seconds rather than terrestrial seconds.
+
+A Mars solar day is called a "sol" and has a mean period equal to
+about 24 hours 39 minutes 35.244 seconds in terrestrial time. It is
+divided into a conventional 24-hour clock, so each Mars second equals
+about 1.02749125 terrestrial seconds.
+
+The prime meridian of Mars goes through the center of the crater
+Airy-0, named in honor of the British astronomer who built the
+Greenwich telescope that defines Earth's prime meridian. Mean solar
+time on the Mars prime meridian is called Mars Coordinated Time (MTC).
+
+Each landed mission on Mars has adopted a different reference for
+solar time keeping, so there is no real standard for Mars time zones.
+For example, the Mars Exploration Rover project (2004) defined two
+time zones "Local Solar Time A" and "Local Solar Time B" for its two
+missions, each zone designed so that its time equals local true solar
+time at approximately the middle of the nominal mission. Such a "time
+zone" is not particularly suited for any application other than the
+mission itself.
+
+Many calendars have been proposed for Mars, but none have achieved
+wide acceptance. Astronomers often use Mars Sol Date (MSD) which is a
+sequential count of Mars solar days elapsed since about 1873-12-29
+12:00 GMT.
+
+The tz database does not currently support Mars time, but it is
+documented here in the hopes that support will be added eventually.
+
+Sources:
+
+Michael Allison and Robert Schmunk,
+"Technical Notes on Mars Solar Time as Adopted by the Mars24 Sunclock"
+<http://www.giss.nasa.gov/tools/mars24/help/notes.html> (2012-08-08).
+
+Jia-Rui Chong, "Workdays Fit for a Martian", Los Angeles Times
+<http://articles.latimes.com/2004/jan/14/science/sci-marstime14>
+(2004-01-14), pp A1, A20-A21.
+
+Tom Chmielewski, "Jet Lag Is Worse on Mars", The Atlantic (2015-02-26)
+<http://www.theatlantic.com/technology/archive/2015/02/jet-lag-is-worse-on-mars/386033/>
+
+-----
+
+This file is in the public domain, so clarified as of 2009-05-17 by
+Arthur David Olson.
+
+-----
+Local Variables:
+coding: utf-8
+End:
diff --git a/contrib/tzdata/antarctica b/contrib/tzdata/antarctica
index 0995835..6da1aef 100644
--- a/contrib/tzdata/antarctica
+++ b/contrib/tzdata/antarctica
@@ -64,13 +64,18 @@
# Background:
# http://www.timeanddate.com/news/time/antartica-time-changes-2010.html
+# From Steffen Thorsen (2016-10-28):
+# Australian Antarctica Division informed us that Casey changed time
+# zone to UTC+11 in "the morning of 22nd October 2016".
+
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Casey 0 - -00 1969
8:00 - +08 2009 Oct 18 2:00
11:00 - +11 2010 Mar 5 2:00
8:00 - +08 2011 Oct 28 2:00
11:00 - +11 2012 Feb 21 17:00u
- 8:00 - +08
+ 8:00 - +08 2016 Oct 22
+ 11:00 - +11
Zone Antarctica/Davis 0 - -00 1957 Jan 13
7:00 - +07 1964 Nov
0 - -00 1969 Feb
diff --git a/contrib/tzdata/asia b/contrib/tzdata/asia
index b2c9930..67164b3 100644
--- a/contrib/tzdata/asia
+++ b/contrib/tzdata/asia
@@ -771,9 +771,19 @@ Zone Asia/Macau 7:34:20 - LMT 1912 Jan 1
###############################################################################
# Cyprus
-#
+
# Milne says the Eastern Telegraph Company used 2:14:00. Stick with LMT.
+# IATA SSIM (1998-09) has Cyprus using EU rules for the first time.
+
+# From Paul Eggert (2016-09-09):
+# Yesterday's Cyprus Mail reports that Northern Cyprus followed Turkey's
+# lead and switched from +02/+03 to +03 year-round.
+# http://cyprus-mail.com/2016/09/08/two-time-zones-cyprus-turkey-will-not-turn-clocks-back-next-month/
#
+# From Even Scharning (2016-10-31):
+# Looks like the time zone split in Cyprus went through last night.
+# http://cyprus-mail.com/2016/10/30/cyprus-new-division-two-time-zones-now-reality/
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Cyprus 1975 only - Apr 13 0:00 1:00 S
Rule Cyprus 1975 only - Oct 12 0:00 0 -
@@ -788,7 +798,10 @@ Rule Cyprus 1981 1998 - Mar lastSun 0:00 1:00 S
Zone Asia/Nicosia 2:13:28 - LMT 1921 Nov 14
2:00 Cyprus EE%sT 1998 Sep
2:00 EUAsia EE%sT
-# IATA SSIM (1998-09) has Cyprus using EU rules for the first time.
+Zone Asia/Famagusta 2:15:48 - LMT 1921 Nov 14
+ 2:00 Cyprus EE%sT 1998 Sep
+ 2:00 EUAsia EE%sT 2016 Sep 8
+ 3:00 - +03
# Classically, Cyprus belongs to Asia; e.g. see Herodotus, Histories, I.72.
# However, for various reasons many users expect to find it under Europe.
diff --git a/contrib/tzdata/australasia b/contrib/tzdata/australasia
index 85d3632..0bca53e 100644
--- a/contrib/tzdata/australasia
+++ b/contrib/tzdata/australasia
@@ -702,11 +702,13 @@ Rule Tonga 1999 only - Oct 7 2:00s 1:00 S
Rule Tonga 2000 only - Mar 19 2:00s 0 -
Rule Tonga 2000 2001 - Nov Sun>=1 2:00 1:00 S
Rule Tonga 2001 2002 - Jan lastSun 2:00 0 -
+Rule Tonga 2016 max - Nov Sun>=1 2:00 1:00 S
+Rule Tonga 2017 max - Jan Sun>=15 3:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Pacific/Tongatapu 12:19:20 - LMT 1901
- 12:20 - TOT 1941 # Tonga Time
- 13:00 - TOT 1999
- 13:00 Tonga TO%sT
+ 12:20 - +1220 1941
+ 13:00 - +13 1999
+ 13:00 Tonga +13/+14
# Tuvalu
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
@@ -1712,9 +1714,17 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901
# of January the standard time in the Kingdom shall be moved backward by one
# hour to 1:00am.
-# From Pulu 'Anau (2002-11-05):
+# From Pulu ʻAnau (2002-11-05):
# The law was for 3 years, supposedly to get renewed. It wasn't.
+# From Pulu ʻAnau (2016-10-27):
+# http://mic.gov.to/news-today/press-releases/6375-daylight-saving-set-to-run-from-6-november-2016-to-15-january-2017
+# Cannot find anyone who knows the rules, has seen the duration or has seen
+# the cabinet decision, but it appears we are following Fiji's rule set.
+#
+# From Tim Parenti (2016-10-26):
+# Assume Tonga will observe DST from the first Sunday in November at 02:00
+# through the third Sunday in January at 03:00, like Fiji, for now.
# Wake
diff --git a/contrib/tzdata/backzone b/contrib/tzdata/backzone
new file mode 100644
index 0000000..4a5085f
--- /dev/null
+++ b/contrib/tzdata/backzone
@@ -0,0 +1,677 @@
+# Zones that go back beyond the scope of the tz database
+
+# This file is in the public domain.
+
+# This file is by no means authoritative; if you think you know
+# better, go ahead and edit it (and please send any changes to
+# tz@iana.org for general use in the future). For more, please see
+# the file CONTRIBUTING in the tz distribution.
+
+
+# From Paul Eggert (2014-10-31):
+
+# This file contains data outside the normal scope of the tz database,
+# in that its zones do not differ from normal tz zones after 1970.
+# Links in this file point to zones in this file, superseding links in
+# the file 'backward'.
+
+# Although zones in this file may be of some use for analyzing
+# pre-1970 time stamps, they are less reliable, cover only a tiny
+# sliver of the pre-1970 era, and cannot feasibly be improved to cover
+# most of the era. Because the zones are out of normal scope for the
+# database, less effort is put into maintaining this file. Many of
+# the zones were formerly in other source files, but were removed or
+# replaced by links as their data entries were questionable and/or they
+# differed from other zones only in pre-1970 time stamps.
+
+# Unless otherwise specified, the source for data through 1990 is:
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
+# San Diego: ACS Publications, Inc. (2003).
+# Unfortunately this book contains many errors and cites no sources.
+
+# This file is not intended to be compiled standalone, as it
+# assumes rules from other files. In the tz distribution, use
+# 'make PACKRATDATA=backzone zones' to compile and install this file.
+
+# Zones are sorted by zone name. Each zone is preceded by the
+# name of the country that the zone is in, along with any other
+# commentary and rules associated with the entry.
+#
+# As explained in the zic man page, the zone columns are:
+# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+
+# Ethiopia
+# From Paul Eggert (2014-07-31):
+# Like the Swahili of Kenya and Tanzania, many Ethiopians keep a
+# 12-hour clock starting at our 06:00, so their "8 o'clock" is our
+# 02:00 or 14:00. Keep this in mind when you ask the time in Amharic.
+#
+# Shanks & Pottenger write that Ethiopia had six narrowly-spaced time
+# zones between 1870 and 1890, that they merged to 38E50 (2:35:20) in
+# 1890, and that they switched to 3:00 on 1936-05-05. Perhaps 38E50
+# was for Adis Dera. Quite likely the Shanks data entries are wrong
+# anyway.
+Zone Africa/Addis_Ababa 2:34:48 - LMT 1870
+ 2:35:20 - ADMT 1936 May 5 # Adis Dera MT
+ 3:00 - EAT
+
+# Eritrea
+Zone Africa/Asmara 2:35:32 - LMT 1870
+ 2:35:32 - AMT 1890 # Asmara Mean Time
+ 2:35:20 - ADMT 1936 May 5 # Adis Dera MT
+ 3:00 - EAT
+Link Africa/Asmara Africa/Asmera
+
+# Mali (southern)
+Zone Africa/Bamako -0:32:00 - LMT 1912
+ 0:00 - GMT 1934 Feb 26
+ -1:00 - WAT 1960 Jun 20
+ 0:00 - GMT
+
+# Central African Republic
+Zone Africa/Bangui 1:14:20 - LMT 1912
+ 1:00 - WAT
+
+# Gambia
+Zone Africa/Banjul -1:06:36 - LMT 1912
+ -1:06:36 - BMT 1935 # Banjul Mean Time
+ -1:00 - WAT 1964
+ 0:00 - GMT
+
+# Malawi
+Zone Africa/Blantyre 2:20:00 - LMT 1903 Mar
+ 2:00 - CAT
+
+# Republic of the Congo
+Zone Africa/Brazzaville 1:01:08 - LMT 1912
+ 1:00 - WAT
+
+# Burundi
+Zone Africa/Bujumbura 1:57:28 - LMT 1890
+ 2:00 - CAT
+
+# Guinea
+Zone Africa/Conakry -0:54:52 - LMT 1912
+ 0:00 - GMT 1934 Feb 26
+ -1:00 - WAT 1960
+ 0:00 - GMT
+
+# Senegal
+Zone Africa/Dakar -1:09:44 - LMT 1912
+ -1:00 - WAT 1941 Jun
+ 0:00 - GMT
+
+# Tanzania
+Zone Africa/Dar_es_Salaam 2:37:08 - LMT 1931
+ 3:00 - EAT 1948
+ 2:45 - BEAUT 1961
+ 3:00 - EAT
+
+# Djibouti
+Zone Africa/Djibouti 2:52:36 - LMT 1911 Jul
+ 3:00 - EAT
+
+# Cameroon
+# Whitman says they switched to 1:00 in 1920; go with Shanks & Pottenger.
+Zone Africa/Douala 0:38:48 - LMT 1912
+ 1:00 - WAT
+# Sierra Leone
+# From Paul Eggert (2014-08-12):
+# The following table is from Shanks & Pottenger, but it can't be right.
+# Whitman gives Mar 31 - Aug 31 for 1931 on.
+# The International Hydrographic Bulletin, 1932-33, p 63 says that
+# Sierra Leone would advance its clocks by 20 minutes on 1933-10-01.
+# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+Rule SL 1935 1942 - Jun 1 0:00 0:40 SLST
+Rule SL 1935 1942 - Oct 1 0:00 0 WAT
+Rule SL 1957 1962 - Jun 1 0:00 1:00 SLST
+Rule SL 1957 1962 - Sep 1 0:00 0 GMT
+Zone Africa/Freetown -0:53:00 - LMT 1882
+ -0:53:00 - FMT 1913 Jun # Freetown Mean Time
+ -1:00 SL %s 1957
+ 0:00 SL %s
+
+# Botswana
+# From Paul Eggert (2013-02-21):
+# Milne says they were regulated by the Cape Town Signal in 1899;
+# assume they switched to 2:00 when Cape Town did.
+Zone Africa/Gaborone 1:43:40 - LMT 1885
+ 1:30 - SAST 1903 Mar
+ 2:00 - CAT 1943 Sep 19 2:00
+ 2:00 1:00 CAST 1944 Mar 19 2:00
+ 2:00 - CAT
+
+# Zimbabwe
+Zone Africa/Harare 2:04:12 - LMT 1903 Mar
+ 2:00 - CAT
+
+# South Sudan
+Zone Africa/Juba 2:06:24 - LMT 1931
+ 2:00 Sudan CA%sT 2000 Jan 15 12:00
+ 3:00 - EAT
+
+# Uganda
+Zone Africa/Kampala 2:09:40 - LMT 1928 Jul
+ 3:00 - EAT 1930
+ 2:30 - BEAT 1948
+ 2:45 - BEAUT 1957
+ 3:00 - EAT
+
+# Rwanda
+Zone Africa/Kigali 2:00:16 - LMT 1935 Jun
+ 2:00 - CAT
+
+# Democratic Republic of the Congo (west)
+Zone Africa/Kinshasa 1:01:12 - LMT 1897 Nov 9
+ 1:00 - WAT
+
+# Gabon
+Zone Africa/Libreville 0:37:48 - LMT 1912
+ 1:00 - WAT
+
+# Togo
+Zone Africa/Lome 0:04:52 - LMT 1893
+ 0:00 - GMT
+
+# Angola
+#
+# Shanks gives 1911-05-26 for the transition to WAT,
+# evidently confusing the date of the Portuguese decree
+# http://dre.pt/pdf1sdip/1911/05/12500/23132313.pdf
+# with the date that it took effect, namely 1912-01-01.
+#
+Zone Africa/Luanda 0:52:56 - LMT 1892
+ 0:52:04 - AOT 1912 Jan 1 # Angola Time
+ 1:00 - WAT
+
+# Democratic Republic of the Congo (east)
+Zone Africa/Lubumbashi 1:49:52 - LMT 1897 Nov 9
+ 2:00 - CAT
+
+# Zambia
+Zone Africa/Lusaka 1:53:08 - LMT 1903 Mar
+ 2:00 - CAT
+
+# Equatorial Guinea
+#
+# Although Shanks says that Malabo switched from UT +00 to +01 on 1963-12-15,
+# a Google Books search says that London Calling, Issues 432-465 (1948), p 19,
+# says that Spanish Guinea was at +01 back then. The Shanks data entries
+# are most likely wrong, but we have nothing better; use them here for now.
+#
+Zone Africa/Malabo 0:35:08 - LMT 1912
+ 0:00 - GMT 1963 Dec 15
+ 1:00 - WAT
+
+# Lesotho
+Zone Africa/Maseru 1:50:00 - LMT 1903 Mar
+ 2:00 - SAST 1943 Sep 19 2:00
+ 2:00 1:00 SAST 1944 Mar 19 2:00
+ 2:00 - SAST
+
+# Swaziland
+Zone Africa/Mbabane 2:04:24 - LMT 1903 Mar
+ 2:00 - SAST
+
+# Somalia
+Zone Africa/Mogadishu 3:01:28 - LMT 1893 Nov
+ 3:00 - EAT 1931
+ 2:30 - BEAT 1957
+ 3:00 - EAT
+
+# Niger
+Zone Africa/Niamey 0:08:28 - LMT 1912
+ -1:00 - WAT 1934 Feb 26
+ 0:00 - GMT 1960
+ 1:00 - WAT
+
+# Mauritania
+Zone Africa/Nouakchott -1:03:48 - LMT 1912
+ 0:00 - GMT 1934 Feb 26
+ -1:00 - WAT 1960 Nov 28
+ 0:00 - GMT
+
+# Burkina Faso
+Zone Africa/Ouagadougou -0:06:04 - LMT 1912
+ 0:00 - GMT
+
+# Benin
+# Whitman says they switched to 1:00 in 1946, not 1934;
+# go with Shanks & Pottenger.
+Zone Africa/Porto-Novo 0:10:28 - LMT 1912 Jan 1
+ 0:00 - GMT 1934 Feb 26
+ 1:00 - WAT
+
+# São Tomé and Príncipe
+Zone Africa/Sao_Tome 0:26:56 - LMT 1884
+ -0:36:32 - LMT 1912 # Lisbon Mean Time
+ 0:00 - GMT
+
+# Mali (northern)
+Zone Africa/Timbuktu -0:12:04 - LMT 1912
+ 0:00 - GMT
+
+# Anguilla
+Zone America/Anguilla -4:12:16 - LMT 1912 Mar 2
+ -4:00 - AST
+
+# Antigua and Barbuda
+Zone America/Antigua -4:07:12 - LMT 1912 Mar 2
+ -5:00 - EST 1951
+ -4:00 - AST
+
+# Chubut, Argentina
+# The name "Comodoro Rivadavia" exceeds the 14-byte POSIX limit.
+Zone America/Argentina/ComodRivadavia -4:30:00 - LMT 1894 Oct 31
+ -4:16:48 - CMT 1920 May
+ -4:00 - ART 1930 Dec
+ -4:00 Arg AR%sT 1969 Oct 5
+ -3:00 Arg AR%sT 1991 Mar 3
+ -4:00 - WART 1991 Oct 20
+ -3:00 Arg AR%sT 1999 Oct 3
+ -4:00 Arg AR%sT 2000 Mar 3
+ -3:00 - ART 2004 Jun 1
+ -4:00 - WART 2004 Jun 20
+ -3:00 - ART
+
+# Aruba
+Zone America/Aruba -4:40:24 - LMT 1912 Feb 12 # Oranjestad
+ -4:30 - ANT 1965 # Netherlands Antilles Time
+ -4:00 - AST
+
+# Cayman Is
+Zone America/Cayman -5:25:32 - LMT 1890 # Georgetown
+ -5:07:11 - KMT 1912 Feb # Kingston Mean Time
+ -5:00 - EST
+
+# Canada
+Zone America/Coral_Harbour -5:32:40 - LMT 1884
+ -5:00 NT_YK E%sT 1946
+ -5:00 - EST
+
+# Dominica
+Zone America/Dominica -4:05:36 - LMT 1911 Jul 1 0:01 # Roseau
+ -4:00 - AST
+
+# Baja California
+# See 'northamerica' for why this entry is here rather than there.
+Zone America/Ensenada -7:46:28 - LMT 1922 Jan 1 0:13:32
+ -8:00 - PST 1927 Jun 10 23:00
+ -7:00 - MST 1930 Nov 16
+ -8:00 - PST 1942 Apr
+ -7:00 - MST 1949 Jan 14
+ -8:00 - PST 1996
+ -8:00 Mexico P%sT
+
+# Grenada
+Zone America/Grenada -4:07:00 - LMT 1911 Jul # St George's
+ -4:00 - AST
+
+# Guadeloupe
+Zone America/Guadeloupe -4:06:08 - LMT 1911 Jun 8 # Pointe-à-Pitre
+ -4:00 - AST
+
+# Canada
+#
+# From Paul Eggert (2015-03-24):
+# Since 1970 most of Quebec has been like Toronto; see
+# America/Toronto. However, earlier versions of the tz database
+# mistakenly relied on data from Shanks & Pottenger saying that Quebec
+# differed from Ontario after 1970, and the following rules and zone
+# were created for most of Quebec from the incorrect Shanks &
+# Pottenger data. The post-1970 entries have been corrected, but the
+# pre-1970 entries are unchecked and probably have errors.
+#
+# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+Rule Mont 1917 only - Mar 25 2:00 1:00 D
+Rule Mont 1917 only - Apr 24 0:00 0 S
+Rule Mont 1919 only - Mar 31 2:30 1:00 D
+Rule Mont 1919 only - Oct 25 2:30 0 S
+Rule Mont 1920 only - May 2 2:30 1:00 D
+Rule Mont 1920 1922 - Oct Sun>=1 2:30 0 S
+Rule Mont 1921 only - May 1 2:00 1:00 D
+Rule Mont 1922 only - Apr 30 2:00 1:00 D
+Rule Mont 1924 only - May 17 2:00 1:00 D
+Rule Mont 1924 1926 - Sep lastSun 2:30 0 S
+Rule Mont 1925 1926 - May Sun>=1 2:00 1:00 D
+Rule Mont 1927 1937 - Apr lastSat 24:00 1:00 D
+Rule Mont 1927 1937 - Sep lastSat 24:00 0 S
+Rule Mont 1938 1940 - Apr lastSun 0:00 1:00 D
+Rule Mont 1938 1939 - Sep lastSun 0:00 0 S
+Rule Mont 1946 1973 - Apr lastSun 2:00 1:00 D
+Rule Mont 1945 1948 - Sep lastSun 2:00 0 S
+Rule Mont 1949 1950 - Oct lastSun 2:00 0 S
+Rule Mont 1951 1956 - Sep lastSun 2:00 0 S
+Rule Mont 1957 1973 - Oct lastSun 2:00 0 S
+Zone America/Montreal -4:54:16 - LMT 1884
+ -5:00 Mont E%sT 1918
+ -5:00 Canada E%sT 1919
+ -5:00 Mont E%sT 1942 Feb 9 2:00s
+ -5:00 Canada E%sT 1946
+ -5:00 Mont E%sT 1974
+ -5:00 Canada E%sT
+
+# Montserrat
+# From Paul Eggert (2006-03-22):
+# In 1995 volcanic eruptions forced evacuation of Plymouth, the capital.
+# world.gazetteer.com says Cork Hill is the most populous location now.
+Zone America/Montserrat -4:08:52 - LMT 1911 Jul 1 0:01 # Cork Hill
+ -4:00 - AST
+
+# Argentina
+# This entry was intended for the following areas, but has been superseded by
+# more detailed zones.
+# Santa Fe (SF), Entre Ríos (ER), Corrientes (CN), Misiones (MN), Chaco (CC),
+# Formosa (FM), La Pampa (LP), Chubut (CH)
+Zone America/Rosario -4:02:40 - LMT 1894 Nov
+ -4:16:44 - CMT 1920 May
+ -4:00 - ART 1930 Dec
+ -4:00 Arg AR%sT 1969 Oct 5
+ -3:00 Arg AR%sT 1991 Jul
+ -3:00 - ART 1999 Oct 3 0:00
+ -4:00 Arg AR%sT 2000 Mar 3 0:00
+ -3:00 - ART
+
+# St Kitts-Nevis
+Zone America/St_Kitts -4:10:52 - LMT 1912 Mar 2 # Basseterre
+ -4:00 - AST
+
+# St Lucia
+Zone America/St_Lucia -4:04:00 - LMT 1890 # Castries
+ -4:04:00 - CMT 1912 # Castries Mean Time
+ -4:00 - AST
+
+# Virgin Is
+Zone America/St_Thomas -4:19:44 - LMT 1911 Jul # Charlotte Amalie
+ -4:00 - AST
+
+# St Vincent and the Grenadines
+Zone America/St_Vincent -4:04:56 - LMT 1890 # Kingstown
+ -4:04:56 - KMT 1912 # Kingstown Mean Time
+ -4:00 - AST
+
+# British Virgin Is
+Zone America/Tortola -4:18:28 - LMT 1911 Jul # Road Town
+ -4:00 - AST
+
+# McMurdo, Ross Island, since 1955-12
+Zone Antarctica/McMurdo 0 - -00 1956
+ 12:00 NZ NZ%sT
+Link Antarctica/McMurdo Antarctica/South_Pole
+
+# Yemen
+# Milne says 2:59:54 was the meridian of the saluting battery at Aden,
+# and that Yemen was at 1:55:56, the meridian of the Hagia Sophia.
+Zone Asia/Aden 2:59:54 - LMT 1950
+ 3:00 - AST
+
+# Bahrain
+Zone Asia/Bahrain 3:22:20 - LMT 1920 # Manamah
+ 4:00 - GST 1972 Jun
+ 3:00 - AST
+
+# India
+#
+# From Paul Eggert (2014-09-06):
+# The 1876 Report of the Secretary of the [US] Navy, p 305 says that Madras
+# civil time was 5:20:57.3.
+#
+# From Paul Eggert (2014-08-21):
+# In tomorrow's The Hindu, Nitya Menon reports that India had two civil time
+# zones starting in 1884, one in Bombay and one in Calcutta, and that railways
+# used a third time zone based on Madras time (80 deg. 18'30" E). Also,
+# in 1881 Bombay briefly switched to Madras time, but switched back. See:
+# http://www.thehindu.com/news/cities/chennai/madras-375-when-madras-clocked-the-time/article6339393.ece
+#Zone Asia/Chennai [not enough info to complete]
+
+# China
+# Long-shu Time (probably due to Long and Shu being two names of that area)
+# Guangxi, Guizhou, Hainan, Ningxia, Sichuan, Shaanxi, and Yunnan;
+# most of Gansu; west Inner Mongolia; west Qinghai; and the Guangdong
+# counties Deqing, Enping, Kaiping, Luoding, Taishan, Xinxing,
+# Yangchun, Yangjiang, Yu'nan, and Yunfu.
+Zone Asia/Chongqing 7:06:20 - LMT 1928 # or Chungking
+ 7:00 - LONT 1980 May # Long-shu Time
+ 8:00 PRC C%sT
+Link Asia/Chongqing Asia/Chungking
+
+# Vietnam
+# From Paul Eggert (2014-10-13):
+# See Asia/Ho_Chi_Minh for the source for this data.
+# Trần's book says the 1954-55 transition to 07:00 in Hanoi was in
+# October 1954, with exact date and time unspecified.
+Zone Asia/Hanoi 7:03:24 - LMT 1906 Jul 1
+ 7:06:30 - PLMT 1911 May 1
+ 7:00 - ICT 1942 Dec 31 23:00
+ 8:00 - IDT 1945 Mar 14 23:00
+ 9:00 - JST 1945 Sep 2
+ 7:00 - ICT 1947 Apr 1
+ 8:00 - IDT 1954 Oct
+ 7:00 - ICT
+
+# China
+# Changbai Time ("Long-white Time", Long-white = Heilongjiang area)
+# Heilongjiang (except Mohe county), Jilin
+Zone Asia/Harbin 8:26:44 - LMT 1928 # or Haerbin
+ 8:30 - CHAT 1932 Mar # Changbai Time
+ 8:00 - CST 1940
+ 9:00 - CHAT 1966 May
+ 8:30 - CHAT 1980 May
+ 8:00 PRC C%sT
+
+# far west China
+Zone Asia/Kashgar 5:03:56 - LMT 1928 # or Kashi or Kaxgar
+ 5:30 - KAST 1940 # Kashgar Time
+ 5:00 - KAST 1980 May
+ 8:00 PRC C%sT
+
+# Kuwait
+Zone Asia/Kuwait 3:11:56 - LMT 1950
+ 3:00 - AST
+
+
+# Oman
+# Milne says 3:54:24 was the meridian of the Muscat Tidal Observatory.
+Zone Asia/Muscat 3:54:24 - LMT 1920
+ 4:00 - GST
+
+# India
+# From Paul Eggert (2014-08-11), after a heads-up from Stephen Colebourne:
+# According to a Portuguese decree (1911-05-26)
+# http://dre.pt/pdf1sdip/1911/05/12500/23132313.pdf
+# Portuguese India switched to UT +05 on 1912-01-01.
+#Zone Asia/Panaji [not enough info to complete]
+
+# Cambodia
+# From Paul Eggert (2014-10-11):
+# See Asia/Ho_Chi_Minh for the source for most of this data. Also, guess
+# (1) Cambodia reverted to UT +07 on 1945-09-02, when Vietnam did, and
+# (2) they also reverted to +07 on 1953-11-09, the date of independence.
+# These guesses are probably wrong but they're better than guessing no
+# transitions there.
+Zone Asia/Phnom_Penh 6:59:40 - LMT 1906 Jul 1
+ 7:06:30 - PLMT 1911 May 1
+ 7:00 - ICT 1942 Dec 31 23:00
+ 8:00 - IDT 1945 Mar 14 23:00
+ 9:00 - JST 1945 Sep 2
+ 7:00 - ICT 1947 Apr 1
+ 8:00 - IDT 1953 Nov 9
+ 7:00 - ICT
+
+# Israel
+Zone Asia/Tel_Aviv 2:19:04 - LMT 1880
+ 2:21 - JMT 1918
+ 2:00 Zion I%sT
+
+# Laos
+# From Paul Eggert (2014-10-11):
+# See Asia/Ho_Chi_Minh for the source for most of this data.
+# Trần's book says that Laos reverted to UT +07 on 1955-04-15.
+# Also, guess that Laos reverted to +07 on 1945-09-02, when Vietnam did;
+# this is probably wrong but it's better than guessing no transition.
+Zone Asia/Vientiane 6:50:24 - LMT 1906 Jul 1
+ 7:06:30 - PLMT 1911 May 1
+ 7:00 - ICT 1942 Dec 31 23:00
+ 8:00 - IDT 1945 Mar 14 23:00
+ 9:00 - JST 1945 Sep 2
+ 7:00 - ICT 1947 Apr 1
+ 8:00 - IDT 1955 Apr 15
+ 7:00 - ICT
+
+# Jan Mayen
+# From Whitman:
+Zone Atlantic/Jan_Mayen -1:00 - EGT
+
+# St Helena
+Zone Atlantic/St_Helena -0:22:48 - LMT 1890 # Jamestown
+ -0:22:48 - JMT 1951 # Jamestown Mean Time
+ 0:00 - GMT
+
+# Northern Ireland
+Zone Europe/Belfast -0:23:40 - LMT 1880 Aug 2
+ -0:25:21 - DMT 1916 May 21 2:00
+ # DMT = Dublin/Dunsink MT
+ -0:25:21 1:00 IST 1916 Oct 1 2:00s
+ # IST = Irish Summer Time
+ 0:00 GB-Eire %s 1968 Oct 27
+ 1:00 - BST 1971 Oct 31 2:00u
+ 0:00 GB-Eire %s 1996
+ 0:00 EU GMT/BST
+
+# Guernsey
+# Data from Joseph S. Myers
+# http://mm.icann.org/pipermail/tz/2013-September/019883.html
+# References to be added
+# LMT Location - 49.27N -2.33E - St.Peter Port
+Zone Europe/Guernsey -0:09:19 - LMT 1913 Jun 18
+ 0:00 GB-Eire %s 1940 Jul 2
+ 1:00 C-Eur CE%sT 1945 May 8
+ 0:00 GB-Eire %s 1968 Oct 27
+ 1:00 - BST 1971 Oct 31 2:00u
+ 0:00 GB-Eire %s 1996
+ 0:00 EU GMT/BST
+
+# Isle of Man
+#
+# From Lester Caine (2013-09-04):
+# The Isle of Man legislation is now on-line at
+# <http://www.legislation.gov.im>, starting with the original Statutory
+# Time Act in 1883 and including additional confirmation of some of
+# the dates of the 'Summer Time' orders originating at
+# Westminster. There is a little uncertainty as to the starting date
+# of the first summer time in 1916 which may have be announced a
+# couple of days late. There is still a substantial number of
+# documents to work through, but it is thought that every GB change
+# was also implemented on the island.
+#
+# AT4 of 1883 - The Statutory Time et cetera Act 1883 -
+# LMT Location - 54.1508N -4.4814E - Tynwald Hill ( Manx parliament )
+Zone Europe/Isle_of_Man -0:17:55 - LMT 1883 Mar 30 0:00s
+ 0:00 GB-Eire %s 1968 Oct 27
+ 1:00 - BST 1971 Oct 31 2:00u
+ 0:00 GB-Eire %s 1996
+ 0:00 EU GMT/BST
+
+# Jersey
+# Data from Joseph S. Myers
+# http://mm.icann.org/pipermail/tz/2013-September/019883.html
+# References to be added
+# LMT Location - 49.187N -2.107E - St. Helier
+Zone Europe/Jersey -0:08:25 - LMT 1898 Jun 11 16:00u
+ 0:00 GB-Eire %s 1940 Jul 2
+ 1:00 C-Eur CE%sT 1945 May 8
+ 0:00 GB-Eire %s 1968 Oct 27
+ 1:00 - BST 1971 Oct 31 2:00u
+ 0:00 GB-Eire %s 1996
+ 0:00 EU GMT/BST
+
+# Slovenia
+Zone Europe/Ljubljana 0:58:04 - LMT 1884
+ 1:00 - CET 1941 Apr 18 23:00
+ 1:00 C-Eur CE%sT 1945 May 8 2:00s
+ 1:00 1:00 CEST 1945 Sep 16 2:00s
+ 1:00 - CET 1982 Nov 27
+ 1:00 EU CE%sT
+
+# Bosnia and Herzegovina
+Zone Europe/Sarajevo 1:13:40 - LMT 1884
+ 1:00 - CET 1941 Apr 18 23:00
+ 1:00 C-Eur CE%sT 1945 May 8 2:00s
+ 1:00 1:00 CEST 1945 Sep 16 2:00s
+ 1:00 - CET 1982 Nov 27
+ 1:00 EU CE%sT
+
+# Macedonia
+Zone Europe/Skopje 1:25:44 - LMT 1884
+ 1:00 - CET 1941 Apr 18 23:00
+ 1:00 C-Eur CE%sT 1945 May 8 2:00s
+ 1:00 1:00 CEST 1945 Sep 16 2:00s
+ 1:00 - CET 1982 Nov 27
+ 1:00 EU CE%sT
+
+# Moldova / Transnistria
+Zone Europe/Tiraspol 1:58:32 - LMT 1880
+ 1:55 - CMT 1918 Feb 15 # Chisinau MT
+ 1:44:24 - BMT 1931 Jul 24 # Bucharest MT
+ 2:00 Romania EE%sT 1940 Aug 15
+ 2:00 1:00 EEST 1941 Jul 17
+ 1:00 C-Eur CE%sT 1944 Aug 24
+ 3:00 Russia MSK/MSD 1991 Mar 31 2:00
+ 2:00 Russia EE%sT 1992 Jan 19 2:00
+ 3:00 Russia MSK/MSD
+
+# Liechtenstein
+Zone Europe/Vaduz 0:38:04 - LMT 1894 Jun
+ 1:00 - CET 1981
+ 1:00 EU CE%sT
+
+# Croatia
+Zone Europe/Zagreb 1:03:52 - LMT 1884
+ 1:00 - CET 1941 Apr 18 23:00
+ 1:00 C-Eur CE%sT 1945 May 8 2:00s
+ 1:00 1:00 CEST 1945 Sep 16 2:00s
+ 1:00 - CET 1982 Nov 27
+ 1:00 EU CE%sT
+
+# Madagascar
+Zone Indian/Antananarivo 3:10:04 - LMT 1911 Jul
+ 3:00 - EAT 1954 Feb 27 23:00s
+ 3:00 1:00 EAST 1954 May 29 23:00s
+ 3:00 - EAT
+
+# Comoros
+Zone Indian/Comoro 2:53:04 - LMT 1911 Jul # Moroni, Gran Comoro
+ 3:00 - EAT
+
+# Mayotte
+Zone Indian/Mayotte 3:00:56 - LMT 1911 Jul # Mamoutzou
+ 3:00 - EAT
+
+# US minor outlying islands
+Zone Pacific/Johnston -10:00 - HST
+
+# US minor outlying islands
+#
+# From Mark Brader (2005-01-23):
+# [Fallacies and Fantasies of Air Transport History, by R.E.G. Davies,
+# published 1994 by Paladwr Press, McLean, VA, USA; ISBN 0-9626483-5-3]
+# reproduced a Pan American Airways timetable from 1936, for their weekly
+# "Orient Express" flights between San Francisco and Manila, and connecting
+# flights to Chicago and the US East Coast. As it uses some time zone
+# designations that I've never seen before:....
+# Fri. 6:30A Lv. HONOLOLU (Pearl Harbor), H.I. H.L.T. Ar. 5:30P Sun.
+# " 3:00P Ar. MIDWAY ISLAND . . . . . . . . . M.L.T. Lv. 6:00A "
+#
+Zone Pacific/Midway -11:49:28 - LMT 1901
+ -11:00 - NST 1956 Jun 3
+ -11:00 1:00 NDT 1956 Sep 2
+ -11:00 - NST 1967 Apr # N=Nome
+ -11:00 - BST 1983 Nov 30 # B=Bering
+ -11:00 - SST # S=Samoa
+
+# N Mariana Is
+Zone Pacific/Saipan -14:17:00 - LMT 1844 Dec 31
+ 9:43:00 - LMT 1901
+ 9:00 - MPT 1969 Oct # N Mariana Is Time
+ 10:00 - MPT 2000 Dec 23
+ 10:00 - ChST # Chamorro Standard Time
diff --git a/contrib/tzdata/checklinks.awk b/contrib/tzdata/checklinks.awk
new file mode 100644
index 0000000..5b3e157
--- /dev/null
+++ b/contrib/tzdata/checklinks.awk
@@ -0,0 +1,48 @@
+# Check links in tz tables.
+
+# Contributed by Paul Eggert. This file is in the public domain.
+
+BEGIN {
+ # Special marker indicating that the name is defined as a Zone.
+ # It is a newline so that it cannot match a valid name.
+ # It is not null so that its slot does not appear unset.
+ Zone = "\n"
+}
+
+/^Zone/ {
+ if (defined[$2]) {
+ if (defined[$2] == Zone) {
+ printf "%s: Zone has duplicate definition\n", $2
+ } else {
+ printf "%s: Link with same name as Zone\n", $2
+ }
+ status = 1
+ }
+ defined[$2] = Zone
+}
+
+/^Link/ {
+ if (defined[$3]) {
+ if (defined[$3] == Zone) {
+ printf "%s: Link with same name as Zone\n", $3
+ } else if (defined[$3] == $2) {
+ printf "%s: Link has duplicate definition\n", $3
+ } else {
+ printf "%s: Link to both %s and %s\n", $3, defined[$3], $2
+ }
+ status = 1
+ }
+ used[$2] = 1
+ defined[$3] = $2
+}
+
+END {
+ for (tz in used) {
+ if (defined[tz] != Zone) {
+ printf "%s: Link to non-zone\n", tz
+ status = 1
+ }
+ }
+
+ exit status
+}
diff --git a/contrib/tzdata/checktab.awk b/contrib/tzdata/checktab.awk
new file mode 100644
index 0000000..2397673
--- /dev/null
+++ b/contrib/tzdata/checktab.awk
@@ -0,0 +1,177 @@
+# Check tz tables for consistency.
+
+# Contributed by Paul Eggert. This file is in the public domain.
+
+BEGIN {
+ FS = "\t"
+
+ if (!iso_table) iso_table = "iso3166.tab"
+ if (!zone_table) zone_table = "zone1970.tab"
+ if (!want_warnings) want_warnings = -1
+
+ while (getline <iso_table) {
+ iso_NR++
+ if ($0 ~ /^#/) continue
+ if (NF != 2) {
+ printf "%s:%d: wrong number of columns\n", \
+ iso_table, iso_NR >>"/dev/stderr"
+ status = 1
+ }
+ cc = $1
+ name = $2
+ if (cc !~ /^[A-Z][A-Z]$/) {
+ printf "%s:%d: invalid country code '%s'\n", \
+ iso_table, iso_NR, cc >>"/dev/stderr"
+ status = 1
+ }
+ if (cc <= cc0) {
+ if (cc == cc0) {
+ s = "duplicate";
+ } else {
+ s = "out of order";
+ }
+
+ printf "%s:%d: country code '%s' is %s\n", \
+ iso_table, iso_NR, cc, s \
+ >>"/dev/stderr"
+ status = 1
+ }
+ cc0 = cc
+ if (name2cc[name]) {
+ printf "%s:%d: '%s' and '%s' have the same name\n", \
+ iso_table, iso_NR, name2cc[name], cc \
+ >>"/dev/stderr"
+ status = 1
+ }
+ name2cc[name] = cc
+ cc2name[cc] = name
+ cc2NR[cc] = iso_NR
+ }
+
+ cc0 = ""
+
+ while (getline <zone_table) {
+ zone_NR++
+ if ($0 ~ /^#/) continue
+ if (NF != 3 && NF != 4) {
+ printf "%s:%d: wrong number of columns\n", \
+ zone_table, zone_NR >>"/dev/stderr"
+ status = 1
+ }
+ split($1, cca, /,/)
+ cc = cca[1]
+ coordinates = $2
+ tz = $3
+ comments = $4
+ if (cc < cc0) {
+ printf "%s:%d: country code '%s' is out of order\n", \
+ zone_table, zone_NR, cc >>"/dev/stderr"
+ status = 1
+ }
+ cc0 = cc
+ tztab[tz] = 1
+ tz2comments[tz] = comments
+ tz2NR[tz] = zone_NR
+ for (i in cca) {
+ cc = cca[i]
+ cctz = cc tz
+ cctztab[cctz] = 1
+ if (cc2name[cc]) {
+ cc_used[cc]++
+ } else {
+ printf "%s:%d: %s: unknown country code\n", \
+ zone_table, zone_NR, cc >>"/dev/stderr"
+ status = 1
+ }
+ }
+ if (coordinates !~ /^[-+][0-9][0-9][0-5][0-9][-+][01][0-9][0-9][0-5][0-9]$/ \
+ && coordinates !~ /^[-+][0-9][0-9][0-5][0-9][0-5][0-9][-+][01][0-9][0-9][0-5][0-9][0-5][0-9]$/) {
+ printf "%s:%d: %s: invalid coordinates\n", \
+ zone_table, zone_NR, coordinates >>"/dev/stderr"
+ status = 1
+ }
+ }
+
+ for (cctz in cctztab) {
+ cc = substr (cctz, 1, 2)
+ tz = substr (cctz, 3)
+ if (1 < cc_used[cc]) {
+ comments_needed[tz] = cc
+ }
+ }
+ for (cctz in cctztab) {
+ cc = substr (cctz, 1, 2)
+ tz = substr (cctz, 3)
+ if (!comments_needed[tz] && tz2comments[tz]) {
+ printf "%s:%d: unnecessary comment '%s'\n", \
+ zone_table, tz2NR[tz], tz2comments[tz] \
+ >>"/dev/stderr"
+ tz2comments[tz] = 0
+ status = 1
+ } else if (comments_needed[tz] && !tz2comments[tz]) {
+ printf "%s:%d: missing comment for %s\n", \
+ zone_table, tz2NR[tz], comments_needed[tz] \
+ >>"/dev/stderr"
+ tz2comments[tz] = 1
+ status = 1
+ }
+ }
+ FS = " "
+}
+
+$1 ~ /^#/ { next }
+
+{
+ tz = rules = ""
+ if ($1 == "Zone") {
+ tz = $2
+ ruleUsed[$4] = 1
+ } else if ($1 == "Link" && zone_table == "zone.tab") {
+ # Ignore Link commands if source and destination basenames
+ # are identical, e.g. Europe/Istanbul versus Asia/Istanbul.
+ src = $2
+ dst = $3
+ while ((i = index(src, "/"))) src = substr(src, i+1)
+ while ((i = index(dst, "/"))) dst = substr(dst, i+1)
+ if (src != dst) tz = $3
+ } else if ($1 == "Rule") {
+ ruleDefined[$2] = 1
+ } else {
+ ruleUsed[$2] = 1
+ }
+ if (tz && tz ~ /\//) {
+ if (!tztab[tz]) {
+ printf "%s: no data for '%s'\n", zone_table, tz \
+ >>"/dev/stderr"
+ status = 1
+ }
+ zoneSeen[tz] = 1
+ }
+}
+
+END {
+ for (tz in ruleDefined) {
+ if (!ruleUsed[tz]) {
+ printf "%s: Rule never used\n", tz
+ status = 1
+ }
+ }
+ for (tz in tztab) {
+ if (!zoneSeen[tz]) {
+ printf "%s:%d: no Zone table for '%s'\n", \
+ zone_table, tz2NR[tz], tz >>"/dev/stderr"
+ status = 1
+ }
+ }
+ if (0 < want_warnings) {
+ for (cc in cc2name) {
+ if (!cc_used[cc]) {
+ printf "%s:%d: warning: " \
+ "no Zone entries for %s (%s)\n", \
+ iso_table, cc2NR[cc], cc, cc2name[cc]
+ }
+ }
+ }
+
+ exit status
+}
diff --git a/contrib/tzdata/europe b/contrib/tzdata/europe
index a7dc350..4709cc7 100644
--- a/contrib/tzdata/europe
+++ b/contrib/tzdata/europe
@@ -1500,73 +1500,84 @@ Zone Atlantic/Reykjavik -1:28 - LMT 1908
# But these events all occurred before the 1970 cutoff,
# so record only the time in Rome.
#
-# From Paul Eggert (2006-03-22):
-# For Italian DST we have three sources: Shanks & Pottenger, Whitman, and
-# F. Pollastri
-# Day-light Saving Time in Italy (2006-02-03)
-# http://toi.iriti.cnr.it/uk/ienitlt.html
-# ('FP' below), taken from an Italian National Electrotechnical Institute
-# publication. When the three sources disagree, guess who's right, as follows:
-#
-# year FP Shanks&P. (S) Whitman (W) Go with:
-# 1916 06-03 06-03 24:00 06-03 00:00 FP & W
-# 09-30 09-30 24:00 09-30 01:00 FP; guess 24:00s
-# 1917 04-01 03-31 24:00 03-31 00:00 FP & S
-# 09-30 09-29 24:00 09-30 01:00 FP & W
-# 1918 03-09 03-09 24:00 03-09 00:00 FP & S
-# 10-06 10-05 24:00 10-06 01:00 FP & W
-# 1919 03-01 03-01 24:00 03-01 00:00 FP & S
-# 10-04 10-04 24:00 10-04 01:00 FP; guess 24:00s
-# 1920 03-20 03-20 24:00 03-20 00:00 FP & S
-# 09-18 09-18 24:00 10-01 01:00 FP; guess 24:00s
-# 1944 04-02 04-03 02:00 S (see C-Eur)
-# 09-16 10-02 03:00 FP; guess 24:00s
-# 1945 09-14 09-16 24:00 FP; guess 24:00s
-# 1970 05-21 05-31 00:00 S
-# 09-20 09-27 00:00 S
+# From Michael Deckers (2016-10-24):
+# http://www.ac-ilsestante.it/MERIDIANE/ora_legale quotes a law of 1893-08-10
+# ... [translated as] "The preceding dispositions will enter into
+# force at the instant at which, according to the time specified in
+# the 1st article, the 1st of November 1893 will begin...."
+#
+# From Pierpaolo Bernardi (2016-10-20):
+# The authoritative source for time in Italy is the national metrological
+# institute, which has a summary page of historical DST data at
+# http://www.inrim.it/res/tf/ora_legale_i.shtml
+# (2016-10-24):
+# http://www.renzobaldini.it/le-ore-legali-in-italia/
+# has still different data for 1944. It divides Italy in two, as
+# there were effectively two governments at the time, north of Gothic
+# Line German controlled territory, official government RSI, and south
+# of the Gothic Line, controlled by allied armies.
+#
+# From Brian Inglis (2016-10-23):
+# Viceregal LEGISLATIVE DECREE. 14 September 1944, no. 219.
+# Restoration of Standard Time. (044U0219) (OJ 62 of 30.9.1944) ...
+# Given the R. law decreed on 1944-03-29, no. 92, by which standard time is
+# advanced to sixty minutes later starting at hour two on 1944-04-02; ...
+# Starting at hour three on the date 1944-09-17 standard time will be resumed.
+#
+# From Paul Eggert (2016-10-27):
+# Go with INRiM for DST rules, except as corrected by Inglis for 1944
+# for the Kingdom of Italy. This is consistent with Renzo Baldini.
+# Model Rome's occupation by using using C-Eur rules from 1943-09-10
+# to 1944-06-04; although Rome was an open city during this period, it
+# was effectively controlled by Germany.
#
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
-Rule Italy 1916 only - Jun 3 0:00s 1:00 S
-Rule Italy 1916 only - Oct 1 0:00s 0 -
-Rule Italy 1917 only - Apr 1 0:00s 1:00 S
-Rule Italy 1917 only - Sep 30 0:00s 0 -
-Rule Italy 1918 only - Mar 10 0:00s 1:00 S
-Rule Italy 1918 1919 - Oct Sun>=1 0:00s 0 -
-Rule Italy 1919 only - Mar 2 0:00s 1:00 S
-Rule Italy 1920 only - Mar 21 0:00s 1:00 S
-Rule Italy 1920 only - Sep 19 0:00s 0 -
-Rule Italy 1940 only - Jun 15 0:00s 1:00 S
-Rule Italy 1944 only - Sep 17 0:00s 0 -
-Rule Italy 1945 only - Apr 2 2:00 1:00 S
-Rule Italy 1945 only - Sep 15 0:00s 0 -
-Rule Italy 1946 only - Mar 17 2:00s 1:00 S
-Rule Italy 1946 only - Oct 6 2:00s 0 -
-Rule Italy 1947 only - Mar 16 0:00s 1:00 S
-Rule Italy 1947 only - Oct 5 0:00s 0 -
-Rule Italy 1948 only - Feb 29 2:00s 1:00 S
-Rule Italy 1948 only - Oct 3 2:00s 0 -
-Rule Italy 1966 1968 - May Sun>=22 0:00 1:00 S
-Rule Italy 1966 1969 - Sep Sun>=22 0:00 0 -
-Rule Italy 1969 only - Jun 1 0:00 1:00 S
-Rule Italy 1970 only - May 31 0:00 1:00 S
-Rule Italy 1970 only - Sep lastSun 0:00 0 -
-Rule Italy 1971 1972 - May Sun>=22 0:00 1:00 S
-Rule Italy 1971 only - Sep lastSun 1:00 0 -
-Rule Italy 1972 only - Oct 1 0:00 0 -
-Rule Italy 1973 only - Jun 3 0:00 1:00 S
-Rule Italy 1973 1974 - Sep lastSun 0:00 0 -
-Rule Italy 1974 only - May 26 0:00 1:00 S
-Rule Italy 1975 only - Jun 1 0:00s 1:00 S
-Rule Italy 1975 1977 - Sep lastSun 0:00s 0 -
-Rule Italy 1976 only - May 30 0:00s 1:00 S
-Rule Italy 1977 1979 - May Sun>=22 0:00s 1:00 S
-Rule Italy 1978 only - Oct 1 0:00s 0 -
-Rule Italy 1979 only - Sep 30 0:00s 0 -
+Rule Italy 1916 only - Jun 3 24:00 1:00 S
+Rule Italy 1916 1917 - Sep 30 24:00 0 -
+Rule Italy 1917 only - Mar 31 24:00 1:00 S
+Rule Italy 1918 only - Mar 9 24:00 1:00 S
+Rule Italy 1918 only - Oct 6 24:00 0 -
+Rule Italy 1919 only - Mar 1 24:00 1:00 S
+Rule Italy 1919 only - Oct 4 24:00 0 -
+Rule Italy 1920 only - Mar 20 24:00 1:00 S
+Rule Italy 1920 only - Sep 18 24:00 0 -
+Rule Italy 1940 only - Jun 14 24:00 1:00 S
+Rule Italy 1942 only - Nov 2 2:00s 0 -
+Rule Italy 1943 only - Mar 29 2:00s 1:00 S
+Rule Italy 1943 only - Oct 4 2:00s 0 -
+Rule Italy 1944 only - Apr 2 2:00s 1:00 S
+Rule Italy 1944 only - Sep 17 2:00s 0 -
+Rule Italy 1945 only - Apr 2 2:00 1:00 S
+Rule Italy 1945 only - Sep 15 1:00 0 -
+Rule Italy 1946 only - Mar 17 2:00s 1:00 S
+Rule Italy 1946 only - Oct 6 2:00s 0 -
+Rule Italy 1947 only - Mar 16 0:00s 1:00 S
+Rule Italy 1947 only - Oct 5 0:00s 0 -
+Rule Italy 1948 only - Feb 29 2:00s 1:00 S
+Rule Italy 1948 only - Oct 3 2:00s 0 -
+Rule Italy 1966 1968 - May Sun>=22 0:00s 1:00 S
+Rule Italy 1966 only - Sep 24 24:00 0 -
+Rule Italy 1967 1969 - Sep Sun>=22 0:00s 0 -
+Rule Italy 1969 only - Jun 1 0:00s 1:00 S
+Rule Italy 1970 only - May 31 0:00s 1:00 S
+Rule Italy 1970 only - Sep lastSun 0:00s 0 -
+Rule Italy 1971 1972 - May Sun>=22 0:00s 1:00 S
+Rule Italy 1971 only - Sep lastSun 0:00s 0 -
+Rule Italy 1972 only - Oct 1 0:00s 0 -
+Rule Italy 1973 only - Jun 3 0:00s 1:00 S
+Rule Italy 1973 1974 - Sep lastSun 0:00s 0 -
+Rule Italy 1974 only - May 26 0:00s 1:00 S
+Rule Italy 1975 only - Jun 1 0:00s 1:00 S
+Rule Italy 1975 1977 - Sep lastSun 0:00s 0 -
+Rule Italy 1976 only - May 30 0:00s 1:00 S
+Rule Italy 1977 1979 - May Sun>=22 0:00s 1:00 S
+Rule Italy 1978 only - Oct 1 0:00s 0 -
+Rule Italy 1979 only - Sep 30 0:00s 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Europe/Rome 0:49:56 - LMT 1866 Sep 22
- 0:49:56 - RMT 1893 Nov 1 0:00s # Rome Mean
- 1:00 Italy CE%sT 1942 Nov 2 2:00s
- 1:00 C-Eur CE%sT 1944 Jul
+ 0:49:56 - RMT 1893 Oct 31 23:49:56 # Rome Mean
+ 1:00 Italy CE%sT 1943 Sep 10
+ 1:00 C-Eur CE%sT 1944 Jun 4
1:00 Italy CE%sT 1980
1:00 EU CE%sT
@@ -1765,6 +1776,10 @@ Zone Europe/Luxembourg 0:24:36 - LMT 1904 Jun
# See Europe/Belgrade.
# Malta
+#
+# From Paul Eggert (2016-10-21):
+# Assume 1900-1972 was like Rome, overriding Shanks.
+#
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Malta 1973 only - Mar 31 0:00s 1:00 S
Rule Malta 1973 only - Sep 29 0:00s 0 -
@@ -1775,8 +1790,6 @@ Rule Malta 1975 1980 - Sep Sun>=15 2:00 0 -
Rule Malta 1980 only - Mar 31 2:00 1:00 S
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Europe/Malta 0:58:04 - LMT 1893 Nov 2 0:00s # Valletta
- 1:00 Italy CE%sT 1942 Nov 2 2:00s
- 1:00 C-Eur CE%sT 1945 Apr 2 2:00s
1:00 Italy CE%sT 1973 Mar 31
1:00 Malta CE%sT 1981
1:00 EU CE%sT
@@ -1908,7 +1921,7 @@ Zone Europe/Monaco 0:29:32 - LMT 1891 Mar 15
# Amsterdam mean time.
# The data entries before 1945 are taken from
-# http://www.staff.science.uu.nl/~gent0113/idl/idl.htm
+# http://www.staff.science.uu.nl/~gent0113/wettijd/wettijd.htm
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Neth 1916 only - May 1 0:00 1:00 NST # Netherlands Summer Time
diff --git a/contrib/tzdata/leapseconds.awk b/contrib/tzdata/leapseconds.awk
new file mode 100644
index 0000000..21fe540
--- /dev/null
+++ b/contrib/tzdata/leapseconds.awk
@@ -0,0 +1,76 @@
+# Generate the 'leapseconds' file from 'leap-seconds.list'.
+
+# This file is in the public domain.
+
+BEGIN {
+ print "# Allowance for leap seconds added to each time zone file."
+ print ""
+ print "# This file is in the public domain."
+ print ""
+ print "# This file is generated automatically from the data in the public-domain"
+ print "# leap-seconds.list file available from most NIST time servers."
+ print "# If the URL <ftp://time.nist.gov/pub/leap-seconds.list> does not work,"
+ print "# you should be able to pick up leap-seconds.list from a secondary NIST server."
+ print "# See <http://tf.nist.gov/tf-cgi/servers.cgi> for a list of secondary servers."
+ print "# For more about leap-seconds.list, please see"
+ print "# The NTP Timescale and Leap Seconds"
+ print "# http://www.eecis.udel.edu/~mills/leap.html"
+ print ""
+ print "# The International Earth Rotation and Reference Systems Service"
+ print "# periodically uses leap seconds to keep UTC to within 0.9 s of UT1"
+ print "# (which measures the true angular orientation of the earth in space); see"
+ print "# Terry J Quinn, The BIPM and the accurate measure of time,"
+ print "# Proc IEEE 79, 7 (July 1991), 894-905 <http://dx.doi.org/10.1109/5.84965>."
+ print "# There were no leap seconds before 1972, because the official mechanism"
+ print "# accounting for the discrepancy between atomic time and the earth's rotation"
+ print "# did not exist until the early 1970s."
+ print ""
+ print "# The correction (+ or -) is made at the given time, so lines"
+ print "# will typically look like:"
+ print "# Leap YEAR MON DAY 23:59:60 + R/S"
+ print "# or"
+ print "# Leap YEAR MON DAY 23:59:59 - R/S"
+ print ""
+ print "# If the leapsecond is Rolling (R) the given time is local time."
+ print "# If the leapsecond is Stationary (S) the given time is UTC."
+ print ""
+ print "# Leap YEAR MONTH DAY HH:MM:SS CORR R/S"
+}
+
+/^ *$/ { next }
+
+/^#\tUpdated through/ || /^#\tFile expires on:/ {
+ last_lines = last_lines $0 "\n"
+}
+
+/^#/ { next }
+
+{
+ NTP_timestamp = $1
+ TAI_minus_UTC = $2
+ hash_mark = $3
+ one = $4
+ month = $5
+ year = $6
+ if (old_TAI_minus_UTC) {
+ if (old_TAI_minus_UTC < TAI_minus_UTC) {
+ sign = "23:59:60\t+"
+ } else {
+ sign = "23:59:59\t-"
+ }
+ if (month == "Jan") {
+ year--;
+ month = "Dec";
+ day = 31
+ } else if (month == "Jul") {
+ month = "Jun";
+ day = 30
+ }
+ printf "Leap\t%s\t%s\t%s\t%s\tS\n", year, month, day, sign
+ }
+ old_TAI_minus_UTC = TAI_minus_UTC
+}
+
+END {
+ printf "\n%s", last_lines
+}
diff --git a/contrib/tzdata/version b/contrib/tzdata/version
new file mode 100644
index 0000000..bc96124
--- /dev/null
+++ b/contrib/tzdata/version
@@ -0,0 +1 @@
+2016i
diff --git a/contrib/tzdata/zone.tab b/contrib/tzdata/zone.tab
index cf774b5..f4969d2 100644
--- a/contrib/tzdata/zone.tab
+++ b/contrib/tzdata/zone.tab
@@ -152,7 +152,8 @@ CU +2308-08222 America/Havana
CV +1455-02331 Atlantic/Cape_Verde
CW +1211-06900 America/Curacao
CX -1025+10543 Indian/Christmas
-CY +3510+03322 Asia/Nicosia
+CY +3510+03322 Asia/Nicosia Cyprus (most areas)
+CY +3507+03357 Asia/Famagusta Northern Cyprus
CZ +5005+01426 Europe/Prague
DE +5230+01322 Europe/Berlin Germany (most areas)
DE +4742+00841 Europe/Busingen Busingen
diff --git a/contrib/tzdata/zone1970.tab b/contrib/tzdata/zone1970.tab
index 8286303..5598d560 100644
--- a/contrib/tzdata/zone1970.tab
+++ b/contrib/tzdata/zone1970.tab
@@ -145,7 +145,8 @@ CU +2308-08222 America/Havana
CV +1455-02331 Atlantic/Cape_Verde
CW,AW,BQ,SX +1211-06900 America/Curacao
CX -1025+10543 Indian/Christmas
-CY +3510+03322 Asia/Nicosia
+CY +3510+03322 Asia/Nicosia Cyprus (most areas)
+CY +3507+03357 Asia/Famagusta Northern Cyprus
CZ,SK +5005+01426 Europe/Prague
DE +5230+01322 Europe/Berlin Germany (most areas)
DK +5540+01235 Europe/Copenhagen
diff --git a/contrib/tzdata/zoneinfo2tdf.pl b/contrib/tzdata/zoneinfo2tdf.pl
new file mode 100755
index 0000000..e05ec01
--- /dev/null
+++ b/contrib/tzdata/zoneinfo2tdf.pl
@@ -0,0 +1,52 @@
+#! /usr/bin/perl -w
+
+# Courtesy Ken Pizzini.
+
+use strict;
+
+#This file released to the public domain.
+
+# Note: error checking is poor; trust the output only if the input
+# has been checked by zic.
+
+my $contZone = '';
+while (<>) {
+ my $origline = $_;
+ my @fields = ();
+ while (s/^\s*((?:"[^"]*"|[^\s#])+)//) {
+ push @fields, $1;
+ }
+ next unless @fields;
+
+ my $type = lc($fields[0]);
+ if ($contZone) {
+ @fields >= 3 or warn "bad continuation line";
+ unshift @fields, '+', $contZone;
+ $type = 'zone';
+ }
+
+ $contZone = '';
+ if ($type eq 'zone') {
+ # Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL]
+ my $nfields = @fields;
+ $nfields >= 5 or warn "bad zone line";
+ if ($nfields > 6) {
+ #this splice is optional, depending on one's preference
+ #(one big date-time field, or componentized date and time):
+ splice(@fields, 5, $nfields-5, "@fields[5..$nfields-1]");
+ }
+ $contZone = $fields[1] if @fields > 5;
+ } elsif ($type eq 'rule') {
+ # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+ @fields == 10 or warn "bad rule line";
+ } elsif ($type eq 'link') {
+ # Link TARGET LINK-NAME
+ @fields == 3 or warn "bad link line";
+ } elsif ($type eq 'leap') {
+ # Leap YEAR MONTH DAY HH:MM:SS CORR R/S
+ @fields == 7 or warn "bad leap line";
+ } else {
+ warn "Fubar at input line $.: $origline";
+ }
+ print join("\t", @fields), "\n";
+}
diff --git a/etc/Makefile b/etc/Makefile
index b41a806..fe518d2 100644
--- a/etc/Makefile
+++ b/etc/Makefile
@@ -459,7 +459,7 @@ distrib-dirs: ${MTREES:N/*} distrib-cleanup .PHONY
.endif
etc-examples-install: ${META_DEPS}
- cd ${.CURDIR}; ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 444 \
+ cd ${.CURDIR}; ${INSTALL} ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 \
${BIN1} ${BIN2} nsmb.conf opieaccess \
${DESTDIR}${SHAREDIR}/examples/etc
diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile
index eb66c7b..320e550 100644
--- a/etc/rc.d/Makefile
+++ b/etc/rc.d/Makefile
@@ -317,6 +317,7 @@ FILES+= wpa_supplicant
.if ${MK_ZFS} != "no"
FILESGROUPS+= ZFS
ZFS+= zfs
+ZFS+= zfsbe
ZFS+= zfsd
ZFS+= zvol
ZFSPACKAGE= zfs
diff --git a/etc/rc.d/zfs b/etc/rc.d/zfs
index a98487c..2d35f9b 100755
--- a/etc/rc.d/zfs
+++ b/etc/rc.d/zfs
@@ -4,7 +4,7 @@
#
# PROVIDE: zfs
-# REQUIRE: mountcritlocal
+# REQUIRE: zfsbe
# BEFORE: FILESYSTEMS var
. /etc/rc.subr
diff --git a/etc/rc.d/zfsbe b/etc/rc.d/zfsbe
new file mode 100755
index 0000000..3c85201
--- /dev/null
+++ b/etc/rc.d/zfsbe
@@ -0,0 +1,71 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+# PROVIDE: zfsbe
+# REQUIRE: mountcritlocal
+
+# Handle boot environment subordinate filesystems
+# that may have canmount property set to noauto.
+# For these filesystems mountpoint relative to /
+# must be the same as their dataset name relative
+# to BE root dataset.
+
+. /etc/rc.subr
+
+name="zfsbe"
+rcvar="zfs_enable"
+start_cmd="be_start"
+stop_cmd="be_stop"
+required_modules="zfs"
+
+mount_subordinate()
+{
+ local _be
+
+ _be=$1
+ zfs list -rH -o mountpoint,name,canmount,mounted -s mountpoint -t filesystem $_be | \
+ while read _mp _name _canmount _mounted ; do
+ # skip filesystems that must not be mounted
+ [ "$_canmount" = "off" ] && continue
+ # skip filesystems that are already mounted
+ [ "$_mounted" = "yes" ] && continue
+ case "$_mp" in
+ "none" | "legacy" | "/" | "/$_be")
+ # do nothing for filesystems with unset or legacy mountpoint
+ # or those that would be mounted over /
+ ;;
+ "/$_be/"*)
+ # filesystems with mountpoint relative to BE
+ mount -t zfs $_name ${_mp#/$_be}
+ ;;
+ *)
+ # filesystems with mountpoint elsewhere
+ zfs mount $_name
+ ;;
+ esac
+ done
+}
+
+be_start()
+{
+ if [ `$SYSCTL_N security.jail.jailed` -eq 1 ]; then
+ :
+ else
+ mount -p | while read _dev _mp _type _rest; do
+ [ $_mp = "/" ] || continue
+ if [ $_type = "zfs" ] ; then
+ mount_subordinate $_dev
+ fi
+ break
+ done
+ fi
+}
+
+be_stop()
+{
+}
+
+load_rc_config $name
+run_rc_command "$1"
diff --git a/gnu/lib/libgcc/Makefile b/gnu/lib/libgcc/Makefile
index a47bd33..a6d14f9 100644
--- a/gnu/lib/libgcc/Makefile
+++ b/gnu/lib/libgcc/Makefile
@@ -393,11 +393,11 @@ _libinstall: _lib-eh-install
_lib-eh-install:
.if ${MK_INSTALLLIB} != "no"
- ${INSTALL} -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
+ ${INSTALL} ${TAG_ARGS} -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
${_INSTALLFLAGS} libgcc_eh.a ${DESTDIR}${LIBDIR}
.endif
.if ${MK_PROFILE} != "no"
- ${INSTALL} -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
+ ${INSTALL} ${TAG_ARGS} -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
${_INSTALLFLAGS} libgcc_eh_p.a ${DESTDIR}${LIBDIR}
.endif
diff --git a/lib/libc/sys/getloginclass.2 b/lib/libc/sys/getloginclass.2
index 6817330..6249d83 100644
--- a/lib/libc/sys/getloginclass.2
+++ b/lib/libc/sys/getloginclass.2
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 6, 2011
+.Dd July 12, 2016
.Dt GETLOGINCLASS 2
.Os
.Sh NAME
@@ -87,7 +87,10 @@ The caller tried to set the login class and was not the super-user.
The size of the buffer is smaller than the result to be returned.
.El
.Sh SEE ALSO
-.Xr setusercontext 3
+.Xr ps 1 ,
+.Xr setusercontext 3 ,
+.Xr login.conf 5 ,
+.Xr rctl 8
.Sh HISTORY
The
.Fn getloginclass
diff --git a/libexec/ftpd/blacklist.c b/libexec/ftpd/blacklist.c
index b66a1cd..85f90b5 100644
--- a/libexec/ftpd/blacklist.c
+++ b/libexec/ftpd/blacklist.c
@@ -37,16 +37,20 @@
#include <blacklist.h>
static struct blacklist *blstate;
+extern int use_blacklist;
void
blacklist_init(void)
{
- blstate = blacklist_open();
+
+ if (use_blacklist)
+ blstate = blacklist_open();
}
void
blacklist_notify(int action, int fd, char *msg)
{
+
if (blstate == NULL)
return;
(void)blacklist_r(blstate, action, fd, msg);
diff --git a/libexec/ftpd/blacklist_client.h b/libexec/ftpd/blacklist_client.h
index 596b2bc..7ac6fd1 100644
--- a/libexec/ftpd/blacklist_client.h
+++ b/libexec/ftpd/blacklist_client.h
@@ -28,5 +28,26 @@
/* $FreeBSD$ */
-void blacklist_notify(int, int, char *);
+#ifndef BLACKLIST_CLIENT_H
+#define BLACKLIST_CLIENT_H
+
+enum {
+ BLACKLIST_AUTH_OK = 0,
+ BLACKLIST_AUTH_FAIL
+};
+
+#ifdef USE_BLACKLIST
void blacklist_init(void);
+void blacklist_notify(int, int, char *);
+
+#define BLACKLIST_INIT() blacklist_init()
+#define BLACKLIST_NOTIFY(x, y, z) blacklist_notify(x, y, z)
+
+#else
+
+#define BLACKLIST_INIT()
+#define BLACKLIST_NOTIFY(x, y, z)
+
+#endif
+
+#endif /* BLACKLIST_CLIENT_H */
diff --git a/libexec/ftpd/ftpd.8 b/libexec/ftpd/ftpd.8
index 50565e9..0cd6289 100644
--- a/libexec/ftpd/ftpd.8
+++ b/libexec/ftpd/ftpd.8
@@ -36,7 +36,7 @@
.Nd Internet File Transfer Protocol server
.Sh SYNOPSIS
.Nm
-.Op Fl 468ADdEhMmOoRrSUvW
+.Op Fl 468ABDdEhMmOoRrSUvW
.Op Fl l Op Fl l
.Op Fl a Ar address
.Op Fl P Ar port
@@ -95,6 +95,14 @@ When
.Fl D
is specified, accept connections only on the specified
.Ar address .
+.It Fl B
+With this option set,
+.Nm
+sends authentication success and failure messages to the
+.Xr blacklistd 8
+daemon. If this option is not specified, no communcation with the
+.Xr blacklistd 8
+daemon is attempted.
.It Fl D
With this option set,
.Nm
diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c
index 16c7523..95682d5 100644
--- a/libexec/ftpd/ftpd.c
+++ b/libexec/ftpd/ftpd.c
@@ -144,6 +144,7 @@ int noretr = 0; /* RETR command is disabled. */
int noguestretr = 0; /* RETR command is disabled for anon users. */
int noguestmkd = 0; /* MKD command is disabled for anon users. */
int noguestmod = 1; /* anon users may not modify existing files. */
+int use_blacklist = 0;
off_t file_size;
off_t byte_count;
@@ -305,7 +306,7 @@ main(int argc, char *argv[], char **envp)
openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
while ((ch = getopt(argc, argv,
- "468a:AdDEhlmMoOp:P:rRSt:T:u:UvW")) != -1) {
+ "468a:ABdDEhlmMoOp:P:rRSt:T:u:UvW")) != -1) {
switch (ch) {
case '4':
family = (family == AF_INET6) ? AF_UNSPEC : AF_INET;
@@ -327,6 +328,14 @@ main(int argc, char *argv[], char **envp)
anon_only = 1;
break;
+ case 'B':
+#ifdef USE_BLACKLIST
+ use_blacklist = 1;
+#else
+ syslog(LOG_WARNING, "not compiled with USE_BLACKLIST support");
+#endif
+ break;
+
case 'd':
ftpdebug++;
break;
@@ -644,9 +653,7 @@ gotchild:
reply(220, "%s FTP server (%s) ready.", hostname, version);
else
reply(220, "FTP server ready.");
-#ifdef USE_BLACKLIST
- blacklist_init();
-#endif
+ BLACKLIST_INIT();
for (;;)
(void) yyparse();
/* NOTREACHED */
@@ -1422,9 +1429,7 @@ skip:
*/
if (rval) {
reply(530, "Login incorrect.");
-#ifdef USE_BLACKLIST
- blacklist_notify(1, STDIN_FILENO, "Login incorrect");
-#endif
+ BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL, STDIN_FILENO, "Login incorrect");
if (logging) {
syslog(LOG_NOTICE,
"FTP LOGIN FAILED FROM %s",
@@ -1441,12 +1446,9 @@ skip:
exit(0);
}
return;
+ } else {
+ BLACKLIST_NOTIFY(BLACKLIST_AUTH_OK, STDIN_FILENO, "Login successful");
}
-#ifdef USE_BLACKLIST
- else {
- blacklist_notify(0, STDIN_FILENO, "Login successful");
- }
-#endif
}
login_attempts = 0; /* this time successful */
if (setegid(pw->pw_gid) < 0) {
diff --git a/release/arm/CUBIEBOARD.conf b/release/arm/CUBIEBOARD.conf
index f3bd0fb..181eb6a 100644
--- a/release/arm/CUBIEBOARD.conf
+++ b/release/arm/CUBIEBOARD.conf
@@ -7,7 +7,7 @@ EMBEDDEDBUILD=1
EMBEDDED_TARGET="arm"
EMBEDDED_TARGET_ARCH="armv6"
EMBEDDEDPORTS="sysutils/u-boot-cubieboard"
-KERNEL="CUBIEBOARD"
+KERNEL="ALLWINNER_UP"
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x42000000"
IMAGE_SIZE="1G"
PART_SCHEME="MBR"
diff --git a/release/doc/share/xml/security.xml b/release/doc/share/xml/security.xml
index 5054271..269e7b3 100644
--- a/release/doc/share/xml/security.xml
+++ b/release/doc/share/xml/security.xml
@@ -24,6 +24,14 @@
<entry>25&nbsp;October&nbsp;2016</entry>
<entry><para>Privilege escalation vulnerability</para></entry>
</row>
+
+ <row>
+ <entry><link
+ xlink:href="&security.url;/FreeBSD-SA-16:33.openssh.asc">FreeBSD-SA-16:33.openssh</link></entry>
+ <entry>2&nbsp;November&nbsp;2016</entry>
+ <entry><para>Remote Denial of Service
+ vulnerability</para></entry>
+ </row>
</tbody>
</tgroup>
</informaltable>
diff --git a/share/examples/Makefile b/share/examples/Makefile
index acb50c7..7bf606c 100644
--- a/share/examples/Makefile
+++ b/share/examples/Makefile
@@ -250,7 +250,7 @@ copies:
symlinks:
.for i in ${LDIRS}
rm -rf ${DESTDIR}${BINDIR}/$i
- ln -s ${.CURDIR}/$i ${DESTDIR}${BINDIR}/$i
+ ${INSTALL} ${TAG_ARGS} -l s ${.CURDIR}/$i ${DESTDIR}${BINDIR}/$i
.endfor
etc-examples:
diff --git a/share/man/man4/ddb.4 b/share/man/man4/ddb.4
index 3e88aa5..6b072ba 100644
--- a/share/man/man4/ddb.4
+++ b/share/man/man4/ddb.4
@@ -60,7 +60,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 6, 2016
+.Dd July 13, 2016
.Dt DDB 4
.Os
.Sh NAME
@@ -146,25 +146,32 @@ to be the same as
.Pp
The general command syntax is:
.Ar command Ns Op Li / Ns Ar modifier
-.Ar address Ns Op Li , Ns Ar count
+.Oo Ar addr Oc Ns Op Li , Ns Ar count
.Pp
A blank line repeats the previous command from the address
.Va next
with
count 1 and no modifiers.
Specifying
-.Ar address
+.Ar addr
sets
.Va dot
to the address.
Omitting
-.Ar address
+.Ar addr
uses
.Va dot .
A missing
.Ar count
is taken
to be 1 for printing commands or infinity for stack traces.
+A
+.Ar count
+of -1 is equivalent to a missing
+.Ar count .
+Options that are supplied but not supported by the given
+.Ar command
+are usually ignored.
.Pp
The
.Nm
@@ -204,8 +211,14 @@ browse through the history buffer, and move the cursor within the
current line.
.Sh COMMANDS
.Bl -tag -width indent -compact
-.It Ic examine
-.It Ic x
+.It Xo
+.Ic examine Ns Op Li / Ns Cm AISabcdghilmorsuxz ...
+.Oo Ar addr Oc Ns Op Li , Ns Ar count
+.Xc
+.It Xo
+.Ic x Ns Op Li / Ns Cm AISabcdghilmorsuxz ...
+.Oo Ar addr Oc Ns Op Li , Ns Ar count
+.Xc
Display the addressed locations according to the formats in the modifier.
Multiple modifier formats display multiple locations.
If no format is specified, the last format specified for this command
@@ -251,7 +264,9 @@ The location is also displayed in hex at the beginning of each line.
display as an instruction
.It Cm I
display as an instruction with possible alternate formats depending on the
-machine, but none of the supported architectures have an alternate format.
+machine.
+On i386, this selects the alternate format for the instruction decoding
+(16 bits in a 32-bit code segment and vice versa).
.It Cm S
display a symbol name for the pointer stored at the address
.El
@@ -328,16 +343,17 @@ Set the named variable or register with the value of
.Ar expr .
Valid variable names are described below.
.Pp
-.It Ic break Ns Op Li / Ns Cm u
-.It Ic b Ns Op Li / Ns Cm u
+.It Ic break Ns Oo Li / Ns Cm u Oc Oo Ar addr Oc Ns Op Li , Ns Ar count
+.It Ic b Ns Oo Li / Ns Cm u Oc Oo Ar addr Oc Ns Op Li , Ns Ar count
Set a break point at
.Ar addr .
If
.Ar count
-is supplied, continues
+is supplied, the
+.Ic continue
+command will not stop at this break point on the first
.Ar count
-\- 1 times before stopping at the
-break point.
+\- 1 times that it is hit.
If the break point is set, a break point number is
printed with
.Ql # .
@@ -361,21 +377,24 @@ user space break points may not work correctly.
Setting a break
point at the low-level code paths may also cause strange behavior.
.Pp
-.It Ic delete Ar addr
-.It Ic d Ar addr
+.It Ic delete Op Ar addr
+.It Ic d Op Ar addr
.It Ic delete Li # Ns Ar number
-.It Ic d Li # Ns Ar number
-Delete the break point.
-The target break point can be specified by a
+.It Ic d Li # Ns Ar number
+Delete the specified break point.
+The break point can be specified by a
break point number with
.Ql # ,
or by using the same
.Ar addr
specified in the original
.Ic break
-command.
+command, or by omitting
+.Ar addr
+to get the default address of
+.Va dot .
.Pp
-.It Ic watch Ar addr Ns Li , Ns Ar size
+.It Ic watch Oo Ar addr Oc Ns Op Li , Ns Ar size
Set a watchpoint for a region.
Execution stops when an attempt to modify the region occurs.
The
@@ -389,7 +408,7 @@ Attempts to watch wired kernel memory
may cause unrecoverable error in some systems such as i386.
Watchpoints on user addresses work best.
.Pp
-.It Ic hwatch Ar addr Ns Li , Ns Ar size
+.It Ic hwatch Oo Ar addr Oc Ns Op Li , Ns Ar size
Set a hardware watchpoint for a region if supported by the
architecture.
Execution stops when an attempt to modify the region occurs.
@@ -405,14 +424,14 @@ Use
for setting watchpoints on kernel address locations only, and avoid
its use on user mode address spaces.
.Pp
-.It Ic dhwatch Ar addr Ns Li , Ns Ar size
+.It Ic dhwatch Oo Ar addr Oc Ns Op Li , Ns Ar size
Delete specified hardware watchpoint.
.Pp
-.It Ic step Ns Op Li / Ns Cm p
-.It Ic s Ns Op Li / Ns Cm p
+.It Ic step Ns Oo Li / Ns Cm p Oc Ns Op Li , Ns Ar count
+.It Ic s Ns Oo Li / Ns Cm p Oc Ns Op Li , Ns Ar count
Single step
.Ar count
-times (the comma is a mandatory part of the syntax).
+times.
If the
.Cm p
modifier is specified, print each instruction at each step.
@@ -458,22 +477,22 @@ Otherwise, only print when the matching return is hit.
.Pp
.It Xo
.Ic trace Ns Op Li / Ns Cm u
-.Op Ar pid | tid
+.Op Ar pid | tid Ns
.Op Li , Ns Ar count
.Xc
.It Xo
.Ic t Ns Op Li / Ns Cm u
-.Op Ar pid | tid
+.Op Ar pid | tid Ns
.Op Li , Ns Ar count
.Xc
.It Xo
.Ic where Ns Op Li / Ns Cm u
-.Op Ar pid | tid
+.Op Ar pid | tid Ns
.Op Li , Ns Ar count
.Xc
.It Xo
.Ic bt Ns Op Li / Ns Cm u
-.Op Ar pid | tid
+.Op Ar pid | tid Ns
.Op Li , Ns Ar count
.Xc
Stack trace.
@@ -498,16 +517,11 @@ only if the machine dependent code supports it.
.Ic search Ns Op Li / Ns Cm bhl
.Ar addr
.Ar value
-.Op Ar mask
+.Op Ar mask Ns
.Op Li , Ns Ar count
.Xc
Search memory for
.Ar value .
-This command might fail in interesting
-ways if it does not find the searched-for value.
-This is because
-.Nm
-does not always recover from touching bad memory.
The optional
.Ar count
argument limits the search.
@@ -535,6 +549,10 @@ modifier will alter the display to show VM map
addresses for the process and not show other information.
.\"
.Pp
+.It Ic show Cm all trace
+.It Ic alltrace
+Show a stack trace for every thread in the system.
+.Pp
.It Ic show Cm all ttys
Show all TTY's within the system.
Output is similar to
diff --git a/share/man/man4/jedec_ts.4 b/share/man/man4/jedec_ts.4
new file mode 100644
index 0000000..567beb6
--- /dev/null
+++ b/share/man/man4/jedec_ts.4
@@ -0,0 +1,130 @@
+.\"
+.\" Copyright (c) 2016 Andriy Gapon <avg@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 ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd October 13, 2016
+.Dt JEDEC_TS 4
+.Os
+.Sh NAME
+.Nm jedec_ts
+.Nd driver for temperature sensors on memory modules
+.Sh SYNOPSIS
+.Bd -ragged -offset indent
+.Cd "device jedec_ts"
+.Cd "device smbus"
+.Ed
+.Pp
+Alternatively, to load the driver as a
+module at boot time, place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+jedec_ts_load="YES"
+.Ed
+.Pp
+In
+.Pa /boot/device.hints :
+.Bd -literal -offset indent
+.Cd hint.jedec_ts.0.at="smbus0"
+.Cd hint.jedec_ts.0.addr="0x30"
+.Cd hint.jedec_ts.1.at="smbus0"
+.Cd hint.jedec_ts.1.addr="0x32"
+.Cd hint.jedec_ts.2.at="smbus0"
+.Cd hint.jedec_ts.2.addr="0x34"
+.Cd hint.jedec_ts.3.at="smbus0"
+.Cd hint.jedec_ts.3.addr="0x36"
+.Cd hint.jedec_ts.4.at="smbus0"
+.Cd hint.jedec_ts.4.addr="0x38"
+.Cd hint.jedec_ts.5.at="smbus0"
+.Cd hint.jedec_ts.5.addr="0x3A"
+.Cd hint.jedec_ts.6.at="smbus0"
+.Cd hint.jedec_ts.6.addr="0x3C"
+.Cd hint.jedec_ts.7.at="smbus0"
+.Cd hint.jedec_ts.7.addr="0x3E"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver provides access to sensor data over the
+.Xr smbus 4 .
+The driver supports temperature sensors on memory modules that conform
+to JEDEC Standard 21-C, TSE2002 Specification.
+.Pp
+The access to
+.Nm
+data is made via the
+.Xr sysctl 8
+interface:
+.Bl -tag -width "dev.jedec_ts.%d.temp"
+.It Va dev.jedec_ts.%d.temp
+read-only value of the current temperature read by the sensor.
+.El
+.Pp
+On a system using
+.Xr device.hints 5 ,
+these values are configurable for
+.Nm :
+.Bl -tag -width "hint.jedec_ts.%d.addr"
+.It Va hint.jedec_ts.%d.at
+target
+.Xr smbus 4 .
+.It Va hint.jedec_ts.%d.addr
+.Nm
+SMBus address on the
+.Xr smbus 4 .
+.El
+.Pp
+.Nm
+temperature sensors can be wired to eight different addresses,
+allowing up to eight sensors on the same
+.Xr smbus 4 .
+.Pp
+If the sensors are on an I2C bus behind an
+.Xr iicbus 4
+controller, then the
+.Xr iicsmb 4
+bridge driver can be used to attach the
+.Xr smbus 4 .
+.Sh EXAMPLES
+.Ss Sensor read out for two memory modules:
+.Bd -literal
+dev.jedec_ts.0.temp: 40.2500C
+dev.jedec_ts.1.temp: 40.7500C
+.Ed
+.Sh SEE ALSO
+.Xr iicbus 4 ,
+.Xr iicsmb 4 ,
+.Xr smbus 4 ,
+.Xr sysctl 8
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Fx 12.0 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver and this manual page were written by
+.An Andriy Gapon Aq Mt avg@FreeBSD.org .
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 8aa21bb..5664b3d 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -273,7 +273,6 @@ cpu_startup(dummy)
*/
startrtclock();
printcpuinfo();
- panicifcpuunsupported();
#ifdef PERFMON
perfmon_init();
#endif
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 04c5dcc..024c1b3 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -144,14 +144,6 @@ static char *trap_msg[] = {
"DTrace pid return trap", /* 32 T_DTRACE_RET */
};
-#ifdef KDB
-static int kdb_on_nmi = 1;
-SYSCTL_INT(_machdep, OID_AUTO, kdb_on_nmi, CTLFLAG_RWTUN,
- &kdb_on_nmi, 0, "Go to KDB on NMI");
-#endif
-static int panic_on_nmi = 1;
-SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RWTUN,
- &panic_on_nmi, 0, "Panic on NMI");
static int prot_fault_translation;
SYSCTL_INT(_machdep, OID_AUTO, prot_fault_translation, CTLFLAG_RWTUN,
&prot_fault_translation, 0,
@@ -176,7 +168,10 @@ trap(struct trapframe *frame)
#endif
struct thread *td = curthread;
struct proc *p = td->td_proc;
- int i = 0, ucode = 0, code;
+#ifdef KDB
+ register_t dr6;
+#endif
+ int i = 0, ucode = 0;
u_int type;
register_t addr = 0;
ksiginfo_t ksi;
@@ -236,7 +231,7 @@ trap(struct trapframe *frame)
* interrupts disabled until they are accidentally
* enabled later.
*/
- if (ISPL(frame->tf_cs) == SEL_UPL)
+ if (TRAPF_USERMODE(frame))
uprintf(
"pid %ld (%s): trap %d with interrupts disabled\n",
(long)curproc->p_pid, curthread->td_name, type);
@@ -258,9 +253,7 @@ trap(struct trapframe *frame)
}
}
- code = frame->tf_err;
-
- if (ISPL(frame->tf_cs) == SEL_UPL) {
+ if (TRAPF_USERMODE(frame)) {
/* user trap */
td->td_pticks = 0;
@@ -376,21 +369,7 @@ trap(struct trapframe *frame)
#ifdef DEV_ISA
case T_NMI:
- /* machine/parity/power fail/"kitchen sink" faults */
- if (isa_nmi(code) == 0) {
-#ifdef KDB
- /*
- * NMI can be hooked up to a pushbutton
- * for debugging.
- */
- if (kdb_on_nmi) {
- printf ("NMI ... going to debugger\n");
- kdb_trap(type, 0, frame);
- }
-#endif /* KDB */
- goto userout;
- } else if (panic_on_nmi)
- panic("NMI indicates hardware failure");
+ nmi_handle_intr(type, frame);
break;
#endif /* DEV_ISA */
@@ -540,8 +519,7 @@ trap(struct trapframe *frame)
* Reset breakpoint bits because the
* processor doesn't
*/
- /* XXX check upper bits here */
- load_dr6(rdr6() & 0xfffffff0);
+ load_dr6(rdr6() & ~0xf);
goto out;
}
/*
@@ -553,29 +531,18 @@ trap(struct trapframe *frame)
* Otherwise, debugger traps "can't happen".
*/
#ifdef KDB
- if (kdb_trap(type, 0, frame))
+ /* XXX %dr6 is not quite reentrant. */
+ dr6 = rdr6();
+ load_dr6(dr6 & ~0x4000);
+ if (kdb_trap(type, dr6, frame))
goto out;
#endif
break;
#ifdef DEV_ISA
case T_NMI:
- /* machine/parity/power fail/"kitchen sink" faults */
- if (isa_nmi(code) == 0) {
-#ifdef KDB
- /*
- * NMI can be hooked up to a pushbutton
- * for debugging.
- */
- if (kdb_on_nmi) {
- printf ("NMI ... going to debugger\n");
- kdb_trap(type, 0, frame);
- }
-#endif /* KDB */
- goto out;
- } else if (panic_on_nmi == 0)
- goto out;
- /* FALLTHROUGH */
+ nmi_handle_intr(type, frame);
+ goto out;
#endif /* DEV_ISA */
}
@@ -773,7 +740,6 @@ trap_fatal(frame, eva)
{
int code, ss;
u_int type;
- long esp;
struct soft_segment_descriptor softseg;
char *msg;
@@ -787,7 +753,7 @@ trap_fatal(frame, eva)
else
msg = "UNKNOWN";
printf("\n\nFatal trap %d: %s while in %s mode\n", type, msg,
- ISPL(frame->tf_cs) == SEL_UPL ? "user" : "kernel");
+ TRAPF_USERMODE(frame) ? "user" : "kernel");
#ifdef SMP
/* two separate prints in case of a trap on an unmapped page */
printf("cpuid = %d; ", PCPU_GET(cpuid));
@@ -804,14 +770,8 @@ trap_fatal(frame, eva)
}
printf("instruction pointer = 0x%lx:0x%lx\n",
frame->tf_cs & 0xffff, frame->tf_rip);
- if (ISPL(frame->tf_cs) == SEL_UPL) {
- ss = frame->tf_ss & 0xffff;
- esp = frame->tf_rsp;
- } else {
- ss = GSEL(GDATA_SEL, SEL_KPL);
- esp = (long)&frame->tf_rsp;
- }
- printf("stack pointer = 0x%x:0x%lx\n", ss, esp);
+ ss = frame->tf_ss & 0xffff;
+ printf("stack pointer = 0x%x:0x%lx\n", ss, frame->tf_rsp);
printf("frame pointer = 0x%x:0x%lx\n", ss, frame->tf_rbp);
printf("code segment = base 0x%lx, limit 0x%lx, type 0x%x\n",
softseg.ssd_base, softseg.ssd_limit, softseg.ssd_type);
@@ -934,7 +894,7 @@ amd64_syscall(struct thread *td, int traced)
ksiginfo_t ksi;
#ifdef DIAGNOSTIC
- if (ISPL(td->td_frame->tf_cs) != SEL_UPL) {
+ if (!TRAPF_USERMODE(td->td_frame)) {
panic("syscall");
/* NOT REACHED */
}
diff --git a/sys/amd64/include/cputypes.h b/sys/amd64/include/cputypes.h
index 5a70462..31c8e41 100644
--- a/sys/amd64/include/cputypes.h
+++ b/sys/amd64/include/cputypes.h
@@ -1,48 +1,6 @@
/*-
- * Copyright (c) 1993 Christopher G. Demetriou
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
+ * This file is in the public domain.
*/
-
-#ifndef _MACHINE_CPUTYPES_H_
-#define _MACHINE_CPUTYPES_H_
+/* $FreeBSD$ */
#include <x86/cputypes.h>
-
-/*
- * Classes of processor.
- */
-#define CPUCLASS_X86 0 /* X86 */
-#define CPUCLASS_K8 1 /* K8 AMD64 class */
-
-/*
- * Kinds of processor.
- */
-#define CPU_X86 0 /* Intel */
-#define CPU_CLAWHAMMER 1 /* AMD Clawhammer */
-#define CPU_SLEDGEHAMMER 2 /* AMD Sledgehammer */
-
-#endif /* !_MACHINE_CPUTYPES_H_ */
diff --git a/sys/amd64/include/db_machdep.h b/sys/amd64/include/db_machdep.h
index 29e385e..722a7b3 100644
--- a/sys/amd64/include/db_machdep.h
+++ b/sys/amd64/include/db_machdep.h
@@ -56,12 +56,16 @@ do { \
#define db_clear_single_step kdb_cpu_clear_singlestep
#define db_set_single_step kdb_cpu_set_singlestep
-#define IS_BREAKPOINT_TRAP(type, code) ((type) == T_BPTFLT)
/*
- * Watchpoints are not supported. The debug exception type is in %dr6
- * and not yet in the args to this macro.
+ * The debug exception type is copied from %dr6 to 'code' and used to
+ * disambiguate single step traps. Watchpoints have no special support.
+ * Our hardware breakpoints are not well integrated with ddb and are too
+ * different from watchpoints. ddb treats them as unknown traps with
+ * unknown addresses and doesn't turn them off while it is running.
*/
-#define IS_WATCHPOINT_TRAP(type, code) 0
+#define IS_BREAKPOINT_TRAP(type, code) ((type) == T_BPTFLT)
+#define IS_SSTEP_TRAP(type, code) ((type) == T_TRCTRAP && (code) & 0x4000)
+#define IS_WATCHPOINT_TRAP(type, code) 0
#define I_CALL 0xe8
#define I_CALLI 0xff
diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c
index bd70d11..5aa17d0 100644
--- a/sys/amd64/vmm/amd/svm.c
+++ b/sys/amd64/vmm/amd/svm.c
@@ -514,10 +514,11 @@ svm_vminit(struct vm *vm, pmap_t pmap)
{
struct svm_softc *svm_sc;
struct svm_vcpu *vcpu;
- vm_paddr_t msrpm_pa, iopm_pa, pml4_pa;
+ vm_paddr_t msrpm_pa, iopm_pa, pml4_pa;
int i;
- svm_sc = malloc(sizeof (struct svm_softc), M_SVM, M_WAITOK | M_ZERO);
+ svm_sc = contigmalloc(sizeof (*svm_sc), M_SVM, M_WAITOK | M_ZERO,
+ 0, ~(vm_paddr_t)0, PAGE_SIZE, 0);
svm_sc->vm = vm;
svm_sc->nptp = (vm_offset_t)vtophys(pmap->pm_pml4);
@@ -534,7 +535,7 @@ svm_vminit(struct vm *vm, pmap_t pmap)
svm_msr_rw_ok(svm_sc->msr_bitmap, MSR_GSBASE);
svm_msr_rw_ok(svm_sc->msr_bitmap, MSR_FSBASE);
svm_msr_rw_ok(svm_sc->msr_bitmap, MSR_KGSBASE);
-
+
svm_msr_rw_ok(svm_sc->msr_bitmap, MSR_STAR);
svm_msr_rw_ok(svm_sc->msr_bitmap, MSR_LSTAR);
svm_msr_rw_ok(svm_sc->msr_bitmap, MSR_CSTAR);
@@ -2042,7 +2043,7 @@ svm_vmcleanup(void *arg)
{
struct svm_softc *sc = arg;
- free(sc, M_SVM);
+ contigfree(sc, sizeof (*sc), M_SVM);
}
static register_t *
diff --git a/sys/arm/allwinner/a10_padconf.c b/sys/arm/allwinner/a10/a10_padconf.c
index f77f5e6..f77f5e6 100644
--- a/sys/arm/allwinner/a10_padconf.c
+++ b/sys/arm/allwinner/a10/a10_padconf.c
diff --git a/sys/arm/allwinner/a10/files.a10 b/sys/arm/allwinner/a10/files.a10
new file mode 100644
index 0000000..67f5279
--- /dev/null
+++ b/sys/arm/allwinner/a10/files.a10
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+arm/allwinner/a10/a10_intc.c standard
+arm/allwinner/a10/a10_padconf.c standard
diff --git a/sys/arm/allwinner/a10_ahci.c b/sys/arm/allwinner/a10_ahci.c
index 1b87ed4..a5e6824 100644
--- a/sys/arm/allwinner/a10_ahci.c
+++ b/sys/arm/allwinner/a10_ahci.c
@@ -313,12 +313,12 @@ ahci_a10_attach(device_t dev)
return (ENXIO);
/* Enable clocks */
- error = clk_get_by_ofw_index(dev, 0, &clk_pll);
+ error = clk_get_by_ofw_index(dev, 0, 0, &clk_pll);
if (error != 0) {
device_printf(dev, "Cannot get PLL clock\n");
goto fail;
}
- error = clk_get_by_ofw_index(dev, 1, &clk_gate);
+ error = clk_get_by_ofw_index(dev, 0, 1, &clk_gate);
if (error != 0) {
device_printf(dev, "Cannot get gate clock\n");
goto fail;
diff --git a/sys/arm/allwinner/a10_codec.c b/sys/arm/allwinner/a10_codec.c
index b8c40c9..af9f41c 100644
--- a/sys/arm/allwinner/a10_codec.c
+++ b/sys/arm/allwinner/a10_codec.c
@@ -786,12 +786,12 @@ a10codec_attach(device_t dev)
}
/* Get clocks */
- error = clk_get_by_ofw_name(dev, "apb", &clk_apb);
+ error = clk_get_by_ofw_name(dev, 0, "apb", &clk_apb);
if (error != 0) {
device_printf(dev, "cannot find apb clock\n");
goto fail;
}
- error = clk_get_by_ofw_name(dev, "codec", &clk_codec);
+ error = clk_get_by_ofw_name(dev, 0, "codec", &clk_codec);
if (error != 0) {
device_printf(dev, "cannot find codec clock\n");
goto fail;
diff --git a/sys/arm/allwinner/a10_dmac.c b/sys/arm/allwinner/a10_dmac.c
index fd5aaa6..cf7d0c3 100644
--- a/sys/arm/allwinner/a10_dmac.c
+++ b/sys/arm/allwinner/a10_dmac.c
@@ -124,7 +124,7 @@ a10dmac_attach(device_t dev)
mtx_init(&sc->sc_mtx, "a10 dmac", NULL, MTX_SPIN);
/* Activate DMA controller clock */
- error = clk_get_by_ofw_index(dev, 0, &clk);
+ error = clk_get_by_ofw_index(dev, 0, 0, &clk);
if (error != 0) {
device_printf(dev, "cannot get clock\n");
return (error);
diff --git a/sys/arm/allwinner/a10_ehci.c b/sys/arm/allwinner/a10_ehci.c
index f8a3f60..f754c9a 100644
--- a/sys/arm/allwinner/a10_ehci.c
+++ b/sys/arm/allwinner/a10_ehci.c
@@ -58,7 +58,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/controller/ehci.h>
#include <dev/usb/controller/ehcireg.h>
-#include <arm/allwinner/allwinner_machdep.h>
+#include <arm/allwinner/aw_machdep.h>
#include <dev/extres/clk/clk.h>
#include <dev/extres/hwreset/hwreset.h>
#include <dev/extres/phy/phy.h>
@@ -208,7 +208,7 @@ a10_ehci_attach(device_t self)
sc->sc_flags |= EHCI_SCFLG_DONTRESET;
/* De-assert reset */
- if (hwreset_get_by_ofw_idx(self, 0, &aw_sc->rst) == 0) {
+ if (hwreset_get_by_ofw_idx(self, 0, 0, &aw_sc->rst) == 0) {
err = hwreset_deassert(aw_sc->rst);
if (err != 0) {
device_printf(self, "Could not de-assert reset\n");
@@ -217,7 +217,7 @@ a10_ehci_attach(device_t self)
}
/* Enable clock for USB */
- err = clk_get_by_ofw_index(self, 0, &aw_sc->clk);
+ err = clk_get_by_ofw_index(self, 0, 0, &aw_sc->clk);
if (err != 0) {
device_printf(self, "Could not get clock\n");
goto error;
@@ -229,7 +229,7 @@ a10_ehci_attach(device_t self)
}
/* Enable USB PHY */
- err = phy_get_by_ofw_name(self, "usb", &aw_sc->phy);
+ err = phy_get_by_ofw_name(self, 0, "usb", &aw_sc->phy);
if (err != 0) {
device_printf(self, "Could not get phy\n");
goto error;
@@ -278,17 +278,11 @@ a10_ehci_detach(device_t self)
struct aw_ehci_softc *aw_sc = device_get_softc(self);
ehci_softc_t *sc = &aw_sc->sc;
const struct aw_ehci_conf *conf;
- device_t bdev;
int err;
uint32_t reg_value = 0;
conf = USB_CONF(self);
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(self);
diff --git a/sys/arm/allwinner/a10_fb.c b/sys/arm/allwinner/a10_fb.c
index cf8f167..4beb0d2 100644
--- a/sys/arm/allwinner/a10_fb.c
+++ b/sys/arm/allwinner/a10_fb.c
@@ -209,7 +209,7 @@ a10fb_setup_debe(struct a10fb_softc *sc, const struct videomode *mode)
height = mode->vdisplay << interlace;
/* Leave reset */
- error = hwreset_get_by_ofw_name(sc->dev, "de_be", &rst);
+ error = hwreset_get_by_ofw_name(sc->dev, 0, "de_be", &rst);
if (error != 0) {
device_printf(sc->dev, "cannot find reset 'de_be'\n");
return (error);
@@ -220,7 +220,7 @@ a10fb_setup_debe(struct a10fb_softc *sc, const struct videomode *mode)
return (error);
}
/* Gating AHB clock for BE */
- error = clk_get_by_ofw_name(sc->dev, "ahb_de_be", &clk_ahb);
+ error = clk_get_by_ofw_name(sc->dev, 0, "ahb_de_be", &clk_ahb);
if (error != 0) {
device_printf(sc->dev, "cannot find clk 'ahb_de_be'\n");
return (error);
@@ -231,7 +231,7 @@ a10fb_setup_debe(struct a10fb_softc *sc, const struct videomode *mode)
return (error);
}
/* Enable DRAM clock to BE */
- error = clk_get_by_ofw_name(sc->dev, "dram_de_be", &clk_dram);
+ error = clk_get_by_ofw_name(sc->dev, 0, "dram_de_be", &clk_dram);
if (error != 0) {
device_printf(sc->dev, "cannot find clk 'dram_de_be'\n");
return (error);
@@ -242,7 +242,7 @@ a10fb_setup_debe(struct a10fb_softc *sc, const struct videomode *mode)
return (error);
}
/* Set BE clock to 300MHz and enable */
- error = clk_get_by_ofw_name(sc->dev, "de_be", &clk_debe);
+ error = clk_get_by_ofw_name(sc->dev, 0, "de_be", &clk_debe);
if (error != 0) {
device_printf(sc->dev, "cannot find clk 'de_be'\n");
return (error);
@@ -309,12 +309,12 @@ a10fb_setup_pll(struct a10fb_softc *sc, uint64_t freq)
clk_t clk_sclk1, clk_sclk2;
int error;
- error = clk_get_by_ofw_name(sc->dev, "lcd_ch1_sclk1", &clk_sclk1);
+ error = clk_get_by_ofw_name(sc->dev, 0, "lcd_ch1_sclk1", &clk_sclk1);
if (error != 0) {
device_printf(sc->dev, "cannot find clk 'lcd_ch1_sclk1'\n");
return (error);
}
- error = clk_get_by_ofw_name(sc->dev, "lcd_ch1_sclk2", &clk_sclk2);
+ error = clk_get_by_ofw_name(sc->dev, 0, "lcd_ch1_sclk2", &clk_sclk2);
if (error != 0) {
device_printf(sc->dev, "cannot find clk 'lcd_ch1_sclk2'\n");
return (error);
@@ -360,7 +360,7 @@ a10fb_setup_tcon(struct a10fb_softc *sc, const struct videomode *mode)
start_delay = START_DELAY(vbl);
/* Leave reset */
- error = hwreset_get_by_ofw_name(sc->dev, "lcd", &rst);
+ error = hwreset_get_by_ofw_name(sc->dev, 0, "lcd", &rst);
if (error != 0) {
device_printf(sc->dev, "cannot find reset 'lcd'\n");
return (error);
@@ -371,7 +371,7 @@ a10fb_setup_tcon(struct a10fb_softc *sc, const struct videomode *mode)
return (error);
}
/* Gating AHB clock for LCD */
- error = clk_get_by_ofw_name(sc->dev, "ahb_lcd", &clk_ahb);
+ error = clk_get_by_ofw_name(sc->dev, 0, "ahb_lcd", &clk_ahb);
if (error != 0) {
device_printf(sc->dev, "cannot find clk 'ahb_lcd'\n");
return (error);
diff --git a/sys/arm/allwinner/a10_gpio.c b/sys/arm/allwinner/a10_gpio.c
index 42015b0..637b575 100644
--- a/sys/arm/allwinner/a10_gpio.c
+++ b/sys/arm/allwinner/a10_gpio.c
@@ -41,8 +41,6 @@ __FBSDID("$FreeBSD$");
#include <sys/gpio.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
@@ -52,7 +50,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
-#include <arm/allwinner/allwinner_machdep.h>
+#include <arm/allwinner/aw_machdep.h>
#include <arm/allwinner/allwinner_pinctrl.h>
#include <dev/extres/clk/clk.h>
#include <dev/extres/hwreset/hwreset.h>
@@ -655,7 +653,7 @@ a10_gpio_attach(device_t dev)
sc->padconf = (struct allwinner_padconf *)ofw_bus_search_compatible(dev,
compat_data)->ocd_data;
- if (hwreset_get_by_ofw_idx(dev, 0, &rst) == 0) {
+ if (hwreset_get_by_ofw_idx(dev, 0, 0, &rst) == 0) {
error = hwreset_deassert(rst);
if (error != 0) {
device_printf(dev, "cannot de-assert reset\n");
@@ -663,7 +661,7 @@ a10_gpio_attach(device_t dev)
}
}
- if (clk_get_by_ofw_index(dev, 0, &clk) == 0) {
+ if (clk_get_by_ofw_index(dev, 0, 0, &clk) == 0) {
error = clk_enable(clk);
if (error != 0) {
device_printf(dev, "could not enable clock\n");
diff --git a/sys/arm/allwinner/a10_hdmi.c b/sys/arm/allwinner/a10_hdmi.c
index 99cbc2f..1b7cbd2 100644
--- a/sys/arm/allwinner/a10_hdmi.c
+++ b/sys/arm/allwinner/a10_hdmi.c
@@ -293,17 +293,17 @@ a10hdmi_attach(device_t dev)
}
/* Setup clocks */
- error = clk_get_by_ofw_name(dev, "ahb", &sc->clk_ahb);
+ error = clk_get_by_ofw_name(dev, 0, "ahb", &sc->clk_ahb);
if (error != 0) {
device_printf(dev, "cannot find ahb clock\n");
return (error);
}
- error = clk_get_by_ofw_name(dev, "hdmi", &sc->clk_hdmi);
+ error = clk_get_by_ofw_name(dev, 0, "hdmi", &sc->clk_hdmi);
if (error != 0) {
device_printf(dev, "cannot find hdmi clock\n");
return (error);
}
- error = clk_get_by_ofw_name(dev, "lcd", &sc->clk_lcd);
+ error = clk_get_by_ofw_name(dev, 0, "lcd", &sc->clk_lcd);
if (error != 0) {
device_printf(dev, "cannot find lcd clock\n");
}
diff --git a/sys/arm/allwinner/a10_mmc.c b/sys/arm/allwinner/a10_mmc.c
index 15ba5e2..a5eecb8 100644
--- a/sys/arm/allwinner/a10_mmc.c
+++ b/sys/arm/allwinner/a10_mmc.c
@@ -48,7 +48,6 @@ __FBSDID("$FreeBSD$");
#include <dev/mmc/mmcreg.h>
#include <dev/mmc/mmcbrvar.h>
-#include <arm/allwinner/allwinner_machdep.h>
#include <arm/allwinner/a10_mmc.h>
#include <dev/extres/clk/clk.h>
#include <dev/extres/hwreset/hwreset.h>
@@ -56,16 +55,12 @@ __FBSDID("$FreeBSD$");
#define A10_MMC_MEMRES 0
#define A10_MMC_IRQRES 1
#define A10_MMC_RESSZ 2
-#define A10_MMC_DMA_SEGS 16
+#define A10_MMC_DMA_SEGS ((MAXPHYS / PAGE_SIZE) + 1)
#define A10_MMC_DMA_MAX_SIZE 0x2000
#define A10_MMC_DMA_FTRGLEVEL 0x20070008
#define CARD_ID_FREQUENCY 400000
-static int a10_mmc_pio_mode = 0;
-
-TUNABLE_INT("hw.a10.mmc.pio_mode", &a10_mmc_pio_mode);
-
static struct ofw_compat_data compat_data[] = {
{"allwinner,sun4i-a10-mmc", 1},
{"allwinner,sun5i-a13-mmc", 1},
@@ -73,14 +68,11 @@ static struct ofw_compat_data compat_data[] = {
};
struct a10_mmc_softc {
- bus_space_handle_t a10_bsh;
- bus_space_tag_t a10_bst;
device_t a10_dev;
clk_t a10_clk_ahb;
clk_t a10_clk_mmc;
hwreset_t a10_rst_ahb;
int a10_bus_busy;
- int a10_id;
int a10_resid;
int a10_timeout;
struct callout a10_timeoutc;
@@ -91,7 +83,6 @@ struct a10_mmc_softc {
uint32_t a10_intr;
uint32_t a10_intr_wait;
void * a10_intrhand;
- bus_size_t a10_fifo_reg;
/* Fields required for DMA access. */
bus_addr_t a10_dma_desc_phys;
@@ -100,7 +91,6 @@ struct a10_mmc_softc {
void * a10_dma_desc;
bus_dmamap_t a10_dma_buf_map;
bus_dma_tag_t a10_dma_buf_tag;
- int a10_dma_inuse;
int a10_dma_map_err;
};
@@ -116,7 +106,7 @@ static int a10_mmc_detach(device_t);
static int a10_mmc_setup_dma(struct a10_mmc_softc *);
static int a10_mmc_reset(struct a10_mmc_softc *);
static void a10_mmc_intr(void *);
-static int a10_mmc_update_clock(struct a10_mmc_softc *);
+static int a10_mmc_update_clock(struct a10_mmc_softc *, uint32_t);
static int a10_mmc_update_ios(device_t, device_t);
static int a10_mmc_request(device_t, device_t, struct mmc_request *);
@@ -127,9 +117,9 @@ static int a10_mmc_release_host(device_t, device_t);
#define A10_MMC_LOCK(_sc) mtx_lock(&(_sc)->a10_mtx)
#define A10_MMC_UNLOCK(_sc) mtx_unlock(&(_sc)->a10_mtx)
#define A10_MMC_READ_4(_sc, _reg) \
- bus_space_read_4((_sc)->a10_bst, (_sc)->a10_bsh, _reg)
+ bus_read_4((_sc)->a10_res[A10_MMC_MEMRES], _reg)
#define A10_MMC_WRITE_4(_sc, _reg, _value) \
- bus_space_write_4((_sc)->a10_bst, (_sc)->a10_bsh, _reg, _value)
+ bus_write_4((_sc)->a10_res[A10_MMC_MEMRES], _reg, _value)
static int
a10_mmc_probe(device_t dev)
@@ -160,17 +150,10 @@ a10_mmc_attach(device_t dev)
sc = device_get_softc(dev);
sc->a10_dev = dev;
sc->a10_req = NULL;
- sc->a10_id = device_get_unit(dev);
- if (sc->a10_id > 3) {
- device_printf(dev, "only 4 hosts are supported (0-3)\n");
- return (ENXIO);
- }
if (bus_alloc_resources(dev, a10_mmc_res_spec, sc->a10_res) != 0) {
device_printf(dev, "cannot allocate device resources\n");
return (ENXIO);
}
- sc->a10_bst = rman_get_bustag(sc->a10_res[A10_MMC_MEMRES]);
- sc->a10_bsh = rman_get_bushandle(sc->a10_res[A10_MMC_MEMRES]);
if (bus_setup_intr(dev, sc->a10_res[A10_MMC_IRQRES],
INTR_TYPE_MISC | INTR_MPSAFE, NULL, a10_mmc_intr, sc,
&sc->a10_intrhand)) {
@@ -182,32 +165,17 @@ a10_mmc_attach(device_t dev)
MTX_DEF);
callout_init_mtx(&sc->a10_timeoutc, &sc->a10_mtx, 0);
- /*
- * Later chips use a different FIFO offset. Unfortunately the FDT
- * uses the same compatible string for old and new implementations.
- */
- switch (allwinner_soc_family()) {
- case ALLWINNERSOC_SUN4I:
- case ALLWINNERSOC_SUN5I:
- case ALLWINNERSOC_SUN7I:
- sc->a10_fifo_reg = A10_MMC_FIFO;
- break;
- default:
- sc->a10_fifo_reg = A31_MMC_FIFO;
- break;
- }
-
/* De-assert reset */
- if (hwreset_get_by_ofw_name(dev, "ahb", &sc->a10_rst_ahb) == 0) {
+ if (hwreset_get_by_ofw_name(dev, 0, "ahb", &sc->a10_rst_ahb) == 0) {
error = hwreset_deassert(sc->a10_rst_ahb);
if (error != 0) {
device_printf(dev, "cannot de-assert reset\n");
- return (error);
+ goto fail;
}
}
/* Activate the module clock. */
- error = clk_get_by_ofw_name(dev, "ahb", &sc->a10_clk_ahb);
+ error = clk_get_by_ofw_name(dev, 0, "ahb", &sc->a10_clk_ahb);
if (error != 0) {
device_printf(dev, "cannot get ahb clock\n");
goto fail;
@@ -217,7 +185,7 @@ a10_mmc_attach(device_t dev)
device_printf(dev, "cannot enable ahb clock\n");
goto fail;
}
- error = clk_get_by_ofw_name(dev, "mmc", &sc->a10_clk_mmc);
+ error = clk_get_by_ofw_name(dev, 0, "mmc", &sc->a10_clk_mmc);
if (error != 0) {
device_printf(dev, "cannot get mmc clock\n");
goto fail;
@@ -240,22 +208,25 @@ a10_mmc_attach(device_t dev)
SYSCTL_ADD_INT(ctx, tree, OID_AUTO, "req_timeout", CTLFLAG_RW,
&sc->a10_timeout, 0, "Request timeout in seconds");
- /* Reset controller. */
+ /* Hardware reset */
+ A10_MMC_WRITE_4(sc, A10_MMC_HWRST, 1);
+ DELAY(100);
+ A10_MMC_WRITE_4(sc, A10_MMC_HWRST, 0);
+ DELAY(500);
+
+ /* Soft Reset controller. */
if (a10_mmc_reset(sc) != 0) {
device_printf(dev, "cannot reset the controller\n");
goto fail;
}
- if (a10_mmc_pio_mode == 0 && a10_mmc_setup_dma(sc) != 0) {
+ if (a10_mmc_setup_dma(sc) != 0) {
device_printf(sc->a10_dev, "Couldn't setup DMA!\n");
- a10_mmc_pio_mode = 1;
+ goto fail;
}
- if (bootverbose)
- device_printf(sc->a10_dev, "DMA status: %s\n",
- a10_mmc_pio_mode ? "disabled" : "enabled");
if (OF_getencprop(node, "bus-width", &bus_width, sizeof(uint32_t)) <= 0)
- bus_width = 1;
+ bus_width = 4;
sc->a10_host.f_min = 400000;
sc->a10_host.f_max = 50000000;
@@ -316,7 +287,8 @@ a10_mmc_setup_dma(struct a10_mmc_softc *sc)
/* Allocate the DMA descriptor memory. */
dma_desc_size = sizeof(struct a10_mmc_dma_desc) * A10_MMC_DMA_SEGS;
- error = bus_dma_tag_create(bus_get_dma_tag(sc->a10_dev), 1, 0,
+ error = bus_dma_tag_create(bus_get_dma_tag(sc->a10_dev),
+ A10_MMC_DMA_ALIGN, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
dma_desc_size, 1, dma_desc_size, 0, NULL, NULL, &sc->a10_dma_tag);
if (error)
@@ -334,7 +306,8 @@ a10_mmc_setup_dma(struct a10_mmc_softc *sc)
return (sc->a10_dma_map_err);
/* Create the DMA map for data transfers. */
- error = bus_dma_tag_create(bus_get_dma_tag(sc->a10_dev), 1, 0,
+ error = bus_dma_tag_create(bus_get_dma_tag(sc->a10_dev),
+ A10_MMC_DMA_ALIGN, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
A10_MMC_DMA_MAX_SIZE * A10_MMC_DMA_SEGS, A10_MMC_DMA_SEGS,
A10_MMC_DMA_MAX_SIZE, BUS_DMA_ALLOCNOW, NULL, NULL,
@@ -358,8 +331,11 @@ a10_dma_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
sc = (struct a10_mmc_softc *)arg;
sc->a10_dma_map_err = err;
+
+ if (err)
+ return;
+
dma_desc = sc->a10_dma_desc;
- /* Note nsegs is guaranteed to be zero if err is non-zero. */
for (i = 0; i < nsegs; i++) {
dma_desc[i].buf_size = segs[i].ds_len;
dma_desc[i].buf_addr = segs[i].ds_addr;
@@ -376,7 +352,7 @@ a10_dma_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
A10_MMC_DMA_CONFIG_ER;
dma_desc[i].next = 0;
}
- }
+ }
}
static int
@@ -391,13 +367,12 @@ a10_mmc_prepare_dma(struct a10_mmc_softc *sc)
if (cmd->data->len > A10_MMC_DMA_MAX_SIZE * A10_MMC_DMA_SEGS)
return (EFBIG);
error = bus_dmamap_load(sc->a10_dma_buf_tag, sc->a10_dma_buf_map,
- cmd->data->data, cmd->data->len, a10_dma_cb, sc, BUS_DMA_NOWAIT);
+ cmd->data->data, cmd->data->len, a10_dma_cb, sc, 0);
if (error)
return (error);
if (sc->a10_dma_map_err)
return (sc->a10_dma_map_err);
- sc->a10_dma_inuse = 1;
if (cmd->data->flags & MMC_DATA_WRITE)
sync_op = BUS_DMASYNC_PREWRITE;
else
@@ -405,27 +380,32 @@ a10_mmc_prepare_dma(struct a10_mmc_softc *sc)
bus_dmamap_sync(sc->a10_dma_buf_tag, sc->a10_dma_buf_map, sync_op);
bus_dmamap_sync(sc->a10_dma_tag, sc->a10_dma_map, BUS_DMASYNC_PREWRITE);
- val = A10_MMC_READ_4(sc, A10_MMC_IMASK);
- val &= ~(A10_MMC_RX_DATA_REQ | A10_MMC_TX_DATA_REQ);
- A10_MMC_WRITE_4(sc, A10_MMC_IMASK, val);
- val = A10_MMC_READ_4(sc, A10_MMC_GCTRL);
- val &= ~A10_MMC_ACCESS_BY_AHB;
- val |= A10_MMC_DMA_ENABLE;
- A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, val);
- val |= A10_MMC_DMA_RESET;
- A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, val);
- A10_MMC_WRITE_4(sc, A10_MMC_DMAC, A10_MMC_IDMAC_SOFT_RST);
+ /* Enable DMA */
+ val = A10_MMC_READ_4(sc, A10_MMC_GCTL);
+ val &= ~A10_MMC_CTRL_FIFO_AC_MOD;
+ val |= A10_MMC_CTRL_DMA_ENB;
+ A10_MMC_WRITE_4(sc, A10_MMC_GCTL, val);
+
+ /* Reset DMA */
+ val |= A10_MMC_CTRL_DMA_RST;
+ A10_MMC_WRITE_4(sc, A10_MMC_GCTL, val);
+
+ A10_MMC_WRITE_4(sc, A10_MMC_DMAC, A10_MMC_DMAC_IDMAC_SOFT_RST);
A10_MMC_WRITE_4(sc, A10_MMC_DMAC,
- A10_MMC_IDMAC_IDMA_ON | A10_MMC_IDMAC_FIX_BURST);
- val = A10_MMC_READ_4(sc, A10_MMC_IDIE);
- val &= ~(A10_MMC_IDMAC_RECEIVE_INT | A10_MMC_IDMAC_TRANSMIT_INT);
+ A10_MMC_DMAC_IDMAC_IDMA_ON | A10_MMC_DMAC_IDMAC_FIX_BURST);
+
+ /* Enable RX or TX DMA interrupt */
if (cmd->data->flags & MMC_DATA_WRITE)
- val |= A10_MMC_IDMAC_TRANSMIT_INT;
+ val |= A10_MMC_IDST_TX_INT;
else
- val |= A10_MMC_IDMAC_RECEIVE_INT;
+ val |= A10_MMC_IDST_RX_INT;
A10_MMC_WRITE_4(sc, A10_MMC_IDIE, val);
+
+ /* Set DMA descritptor list address */
A10_MMC_WRITE_4(sc, A10_MMC_DLBA, sc->a10_dma_desc_phys);
- A10_MMC_WRITE_4(sc, A10_MMC_FTRGL, A10_MMC_DMA_FTRGLEVEL);
+
+ /* FIFO trigger level */
+ A10_MMC_WRITE_4(sc, A10_MMC_FWLR, A10_MMC_DMA_FTRGLEVEL);
return (0);
}
@@ -435,11 +415,10 @@ a10_mmc_reset(struct a10_mmc_softc *sc)
{
int timeout;
- A10_MMC_WRITE_4(sc, A10_MMC_GCTRL,
- A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_RESET);
+ A10_MMC_WRITE_4(sc, A10_MMC_GCTL, A10_MMC_RESET);
timeout = 1000;
while (--timeout > 0) {
- if ((A10_MMC_READ_4(sc, A10_MMC_GCTRL) & A10_MMC_RESET) == 0)
+ if ((A10_MMC_READ_4(sc, A10_MMC_GCTL) & A10_MMC_RESET) == 0)
break;
DELAY(100);
}
@@ -447,18 +426,20 @@ a10_mmc_reset(struct a10_mmc_softc *sc)
return (ETIMEDOUT);
/* Set the timeout. */
- A10_MMC_WRITE_4(sc, A10_MMC_TIMEOUT, 0xffffffff);
+ A10_MMC_WRITE_4(sc, A10_MMC_TMOR,
+ A10_MMC_TMOR_DTO_LMT_SHIFT(A10_MMC_TMOR_DTO_LMT_MASK) |
+ A10_MMC_TMOR_RTO_LMT_SHIFT(A10_MMC_TMOR_RTO_LMT_MASK));
/* Clear pending interrupts. */
- A10_MMC_WRITE_4(sc, A10_MMC_RINTR, 0xffffffff);
+ A10_MMC_WRITE_4(sc, A10_MMC_RISR, 0xffffffff);
A10_MMC_WRITE_4(sc, A10_MMC_IDST, 0xffffffff);
/* Unmask interrupts. */
- A10_MMC_WRITE_4(sc, A10_MMC_IMASK,
- A10_MMC_CMD_DONE | A10_MMC_INT_ERR_BIT |
- A10_MMC_DATA_OVER | A10_MMC_AUTOCMD_DONE);
+ A10_MMC_WRITE_4(sc, A10_MMC_IMKR,
+ A10_MMC_INT_CMD_DONE | A10_MMC_INT_ERR_BIT |
+ A10_MMC_INT_DATA_OVER | A10_MMC_INT_AUTO_STOP_DONE);
/* Enable interrupts and AHB access. */
- A10_MMC_WRITE_4(sc, A10_MMC_GCTRL,
- A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_INT_ENABLE);
+ A10_MMC_WRITE_4(sc, A10_MMC_GCTL,
+ A10_MMC_READ_4(sc, A10_MMC_GCTL) | A10_MMC_CTRL_INT_ENB);
return (0);
}
@@ -473,12 +454,6 @@ a10_mmc_req_done(struct a10_mmc_softc *sc)
if (cmd->error != MMC_ERR_NONE) {
/* Reset the controller. */
a10_mmc_reset(sc);
- a10_mmc_update_clock(sc);
- }
- if (sc->a10_dma_inuse == 0) {
- /* Reset the FIFO. */
- A10_MMC_WRITE_4(sc, A10_MMC_GCTRL,
- A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_FIFO_RESET);
}
req = sc->a10_req;
@@ -486,7 +461,6 @@ a10_mmc_req_done(struct a10_mmc_softc *sc)
sc->a10_req = NULL;
sc->a10_intr = 0;
sc->a10_resid = 0;
- sc->a10_dma_inuse = 0;
sc->a10_dma_map_err = 0;
sc->a10_intr_wait = 0;
req->done(req);
@@ -501,8 +475,8 @@ a10_mmc_req_ok(struct a10_mmc_softc *sc)
timeout = 1000;
while (--timeout > 0) {
- status = A10_MMC_READ_4(sc, A10_MMC_STAS);
- if ((status & A10_MMC_CARD_DATA_BUSY) == 0)
+ status = A10_MMC_READ_4(sc, A10_MMC_STAR);
+ if ((status & A10_MMC_STAR_CARD_BUSY) == 0)
break;
DELAY(1000);
}
@@ -542,28 +516,6 @@ a10_mmc_timeout(void *arg)
"Spurious timeout - no active request\n");
}
-static int
-a10_mmc_pio_transfer(struct a10_mmc_softc *sc, struct mmc_data *data)
-{
- int i, write;
- uint32_t bit, *buf;
-
- buf = (uint32_t *)data->data;
- write = (data->flags & MMC_DATA_WRITE) ? 1 : 0;
- bit = write ? A10_MMC_FIFO_FULL : A10_MMC_FIFO_EMPTY;
- for (i = sc->a10_resid; i < (data->len >> 2); i++) {
- if ((A10_MMC_READ_4(sc, A10_MMC_STAS) & bit))
- return (1);
- if (write)
- A10_MMC_WRITE_4(sc, sc->a10_fifo_reg, buf[i]);
- else
- buf[i] = A10_MMC_READ_4(sc, sc->a10_fifo_reg);
- sc->a10_resid = i + 1;
- }
-
- return (0);
-}
-
static void
a10_mmc_intr(void *arg)
{
@@ -574,9 +526,9 @@ a10_mmc_intr(void *arg)
sc = (struct a10_mmc_softc *)arg;
A10_MMC_LOCK(sc);
- rint = A10_MMC_READ_4(sc, A10_MMC_RINTR);
+ rint = A10_MMC_READ_4(sc, A10_MMC_RISR);
idst = A10_MMC_READ_4(sc, A10_MMC_IDST);
- imask = A10_MMC_READ_4(sc, A10_MMC_IMASK);
+ imask = A10_MMC_READ_4(sc, A10_MMC_IMKR);
if (idst == 0 && imask == 0 && rint == 0) {
A10_MMC_UNLOCK(sc);
return;
@@ -593,14 +545,14 @@ a10_mmc_intr(void *arg)
}
if (rint & A10_MMC_INT_ERR_BIT) {
device_printf(sc->a10_dev, "error rint: 0x%08X\n", rint);
- if (rint & A10_MMC_RESP_TIMEOUT)
+ if (rint & A10_MMC_INT_RESP_TIMEOUT)
sc->a10_req->cmd->error = MMC_ERR_TIMEOUT;
else
sc->a10_req->cmd->error = MMC_ERR_FAILED;
a10_mmc_req_done(sc);
goto end;
}
- if (idst & A10_MMC_IDMAC_ERROR) {
+ if (idst & A10_MMC_IDST_ERROR) {
device_printf(sc->a10_dev, "error idst: 0x%08x\n", idst);
sc->a10_req->cmd->error = MMC_ERR_FAILED;
a10_mmc_req_done(sc);
@@ -609,8 +561,7 @@ a10_mmc_intr(void *arg)
sc->a10_intr |= rint;
data = sc->a10_req->cmd->data;
- if (data != NULL && sc->a10_dma_inuse == 1 &&
- (idst & A10_MMC_IDMAC_COMPLETE)) {
+ if (data != NULL && (idst & A10_MMC_IDST_COMPLETE) != 0) {
if (data->flags & MMC_DATA_WRITE)
sync_op = BUS_DMASYNC_POSTWRITE;
else
@@ -621,16 +572,13 @@ a10_mmc_intr(void *arg)
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->a10_dma_buf_tag, sc->a10_dma_buf_map);
sc->a10_resid = data->len >> 2;
- } else if (data != NULL && sc->a10_dma_inuse == 0 &&
- (rint & (A10_MMC_DATA_OVER | A10_MMC_RX_DATA_REQ |
- A10_MMC_TX_DATA_REQ)) != 0)
- a10_mmc_pio_transfer(sc, data);
+ }
if ((sc->a10_intr & sc->a10_intr_wait) == sc->a10_intr_wait)
a10_mmc_req_ok(sc);
end:
A10_MMC_WRITE_4(sc, A10_MMC_IDST, idst);
- A10_MMC_WRITE_4(sc, A10_MMC_RINTR, rint);
+ A10_MMC_WRITE_4(sc, A10_MMC_RISR, rint);
A10_MMC_UNLOCK(sc);
}
@@ -640,7 +588,8 @@ a10_mmc_request(device_t bus, device_t child, struct mmc_request *req)
int blksz;
struct a10_mmc_softc *sc;
struct mmc_command *cmd;
- uint32_t cmdreg, val;
+ uint32_t cmdreg;
+ int err;
sc = device_get_softc(bus);
A10_MMC_LOCK(sc);
@@ -650,48 +599,39 @@ a10_mmc_request(device_t bus, device_t child, struct mmc_request *req)
}
sc->a10_req = req;
cmd = req->cmd;
- cmdreg = A10_MMC_START;
+ cmdreg = A10_MMC_CMDR_LOAD;
if (cmd->opcode == MMC_GO_IDLE_STATE)
- cmdreg |= A10_MMC_SEND_INIT_SEQ;
+ cmdreg |= A10_MMC_CMDR_SEND_INIT_SEQ;
if (cmd->flags & MMC_RSP_PRESENT)
- cmdreg |= A10_MMC_RESP_EXP;
+ cmdreg |= A10_MMC_CMDR_RESP_RCV;
if (cmd->flags & MMC_RSP_136)
- cmdreg |= A10_MMC_LONG_RESP;
+ cmdreg |= A10_MMC_CMDR_LONG_RESP;
if (cmd->flags & MMC_RSP_CRC)
- cmdreg |= A10_MMC_CHECK_RESP_CRC;
+ cmdreg |= A10_MMC_CMDR_CHK_RESP_CRC;
sc->a10_intr = 0;
sc->a10_resid = 0;
- sc->a10_intr_wait = A10_MMC_CMD_DONE;
+ sc->a10_intr_wait = A10_MMC_INT_CMD_DONE;
cmd->error = MMC_ERR_NONE;
if (cmd->data != NULL) {
- sc->a10_intr_wait |= A10_MMC_DATA_OVER;
- cmdreg |= A10_MMC_DATA_EXP | A10_MMC_WAIT_PREOVER;
+ sc->a10_intr_wait |= A10_MMC_INT_DATA_OVER;
+ cmdreg |= A10_MMC_CMDR_DATA_TRANS | A10_MMC_CMDR_WAIT_PRE_OVER;
if (cmd->data->flags & MMC_DATA_MULTI) {
- cmdreg |= A10_MMC_SEND_AUTOSTOP;
- sc->a10_intr_wait |= A10_MMC_AUTOCMD_DONE;
+ cmdreg |= A10_MMC_CMDR_STOP_CMD_FLAG;
+ sc->a10_intr_wait |= A10_MMC_INT_AUTO_STOP_DONE;
}
if (cmd->data->flags & MMC_DATA_WRITE)
- cmdreg |= A10_MMC_WRITE;
+ cmdreg |= A10_MMC_CMDR_DIR_WRITE;
blksz = min(cmd->data->len, MMC_SECTOR_SIZE);
- A10_MMC_WRITE_4(sc, A10_MMC_BLKSZ, blksz);
- A10_MMC_WRITE_4(sc, A10_MMC_BCNTR, cmd->data->len);
-
- if (a10_mmc_pio_mode == 0)
- a10_mmc_prepare_dma(sc);
- /* Enable PIO access if sc->a10_dma_inuse is not set. */
- if (sc->a10_dma_inuse == 0) {
- val = A10_MMC_READ_4(sc, A10_MMC_GCTRL);
- val &= ~A10_MMC_DMA_ENABLE;
- val |= A10_MMC_ACCESS_BY_AHB;
- A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, val);
- val = A10_MMC_READ_4(sc, A10_MMC_IMASK);
- val |= A10_MMC_RX_DATA_REQ | A10_MMC_TX_DATA_REQ;
- A10_MMC_WRITE_4(sc, A10_MMC_IMASK, val);
- }
+ A10_MMC_WRITE_4(sc, A10_MMC_BKSR, blksz);
+ A10_MMC_WRITE_4(sc, A10_MMC_BYCR, cmd->data->len);
+
+ err = a10_mmc_prepare_dma(sc);
+ if (err != 0)
+ device_printf(sc->a10_dev, "prepare_dma failed: %d\n", err);
}
- A10_MMC_WRITE_4(sc, A10_MMC_CARG, cmd->arg);
+ A10_MMC_WRITE_4(sc, A10_MMC_CAGR, cmd->arg);
A10_MMC_WRITE_4(sc, A10_MMC_CMDR, cmdreg | cmd->opcode);
callout_reset(&sc->a10_timeoutc, sc->a10_timeout * hz,
a10_mmc_timeout, sc);
@@ -801,23 +741,32 @@ a10_mmc_write_ivar(device_t bus, device_t child, int which,
}
static int
-a10_mmc_update_clock(struct a10_mmc_softc *sc)
+a10_mmc_update_clock(struct a10_mmc_softc *sc, uint32_t clkon)
{
uint32_t cmdreg;
int retry;
+ uint32_t ckcr;
+
+ ckcr = A10_MMC_READ_4(sc, A10_MMC_CKCR);
+ ckcr &= ~(A10_MMC_CKCR_CCLK_ENB | A10_MMC_CKCR_CCLK_CTRL);
+
+ if (clkon)
+ ckcr |= A10_MMC_CKCR_CCLK_ENB;
- cmdreg = A10_MMC_START | A10_MMC_UPCLK_ONLY |
- A10_MMC_WAIT_PREOVER;
+ A10_MMC_WRITE_4(sc, A10_MMC_CKCR, ckcr);
+
+ cmdreg = A10_MMC_CMDR_LOAD | A10_MMC_CMDR_PRG_CLK |
+ A10_MMC_CMDR_WAIT_PRE_OVER;
A10_MMC_WRITE_4(sc, A10_MMC_CMDR, cmdreg);
retry = 0xfffff;
while (--retry > 0) {
- if ((A10_MMC_READ_4(sc, A10_MMC_CMDR) & A10_MMC_START) == 0) {
- A10_MMC_WRITE_4(sc, A10_MMC_RINTR, 0xffffffff);
+ if ((A10_MMC_READ_4(sc, A10_MMC_CMDR) & A10_MMC_CMDR_LOAD) == 0) {
+ A10_MMC_WRITE_4(sc, A10_MMC_RISR, 0xffffffff);
return (0);
}
DELAY(10);
}
- A10_MMC_WRITE_4(sc, A10_MMC_RINTR, 0xffffffff);
+ A10_MMC_WRITE_4(sc, A10_MMC_RISR, 0xffffffff);
device_printf(sc->a10_dev, "timeout updating clock\n");
return (ETIMEDOUT);
@@ -829,28 +778,37 @@ a10_mmc_update_ios(device_t bus, device_t child)
int error;
struct a10_mmc_softc *sc;
struct mmc_ios *ios;
- uint32_t clkcr;
+ uint32_t ckcr;
sc = device_get_softc(bus);
- clkcr = A10_MMC_READ_4(sc, A10_MMC_CLKCR);
- if (clkcr & A10_MMC_CARD_CLK_ON) {
- /* Disable clock. */
- clkcr &= ~A10_MMC_CARD_CLK_ON;
- A10_MMC_WRITE_4(sc, A10_MMC_CLKCR, clkcr);
- error = a10_mmc_update_clock(sc);
- if (error != 0)
- return (error);
- }
ios = &sc->a10_host.ios;
+
+ /* Set the bus width. */
+ switch (ios->bus_width) {
+ case bus_width_1:
+ A10_MMC_WRITE_4(sc, A10_MMC_BWDR, A10_MMC_BWDR1);
+ break;
+ case bus_width_4:
+ A10_MMC_WRITE_4(sc, A10_MMC_BWDR, A10_MMC_BWDR4);
+ break;
+ case bus_width_8:
+ A10_MMC_WRITE_4(sc, A10_MMC_BWDR, A10_MMC_BWDR8);
+ break;
+ }
+
if (ios->clock) {
- /* Reset the divider. */
- clkcr &= ~A10_MMC_CLKCR_DIV;
- A10_MMC_WRITE_4(sc, A10_MMC_CLKCR, clkcr);
- error = a10_mmc_update_clock(sc);
+
+ /* Disable clock */
+ error = a10_mmc_update_clock(sc, 0);
if (error != 0)
return (error);
+ /* Reset the divider. */
+ ckcr = A10_MMC_READ_4(sc, A10_MMC_CKCR);
+ ckcr &= ~A10_MMC_CKCR_CCLK_DIV;
+ A10_MMC_WRITE_4(sc, A10_MMC_CKCR, ckcr);
+
/* Set the MMC clock. */
error = clk_set_freq(sc->a10_clk_mmc, ios->clock,
CLK_SET_ROUND_DOWN);
@@ -862,25 +820,11 @@ a10_mmc_update_ios(device_t bus, device_t child)
}
/* Enable clock. */
- clkcr |= A10_MMC_CARD_CLK_ON;
- A10_MMC_WRITE_4(sc, A10_MMC_CLKCR, clkcr);
- error = a10_mmc_update_clock(sc);
+ error = a10_mmc_update_clock(sc, 1);
if (error != 0)
return (error);
}
- /* Set the bus width. */
- switch (ios->bus_width) {
- case bus_width_1:
- A10_MMC_WRITE_4(sc, A10_MMC_WIDTH, A10_MMC_WIDTH1);
- break;
- case bus_width_4:
- A10_MMC_WRITE_4(sc, A10_MMC_WIDTH, A10_MMC_WIDTH4);
- break;
- case bus_width_8:
- A10_MMC_WRITE_4(sc, A10_MMC_WIDTH, A10_MMC_WIDTH8);
- break;
- }
return (0);
}
diff --git a/sys/arm/allwinner/a10_mmc.h b/sys/arm/allwinner/a10_mmc.h
index 02e200c..85f0374 100644
--- a/sys/arm/allwinner/a10_mmc.h
+++ b/sys/arm/allwinner/a10_mmc.h
@@ -29,117 +29,120 @@
#ifndef _A10_MMC_H_
#define _A10_MMC_H_
-#define A10_MMC_GCTRL 0x00 /* Global Control Register */
-#define A10_MMC_CLKCR 0x04 /* Clock Control Register */
-#define A10_MMC_TIMEOUT 0x08 /* Timeout Register */
-#define A10_MMC_WIDTH 0x0C /* Bus Width Register */
-#define A10_MMC_BLKSZ 0x10 /* Block Size Register */
-#define A10_MMC_BCNTR 0x14 /* Byte Count Register */
+#define A10_MMC_GCTL 0x00 /* Control Register */
+#define A10_MMC_CKCR 0x04 /* Clock Control Register */
+#define A10_MMC_TMOR 0x08 /* Timeout Register */
+#define A10_MMC_BWDR 0x0C /* Bus Width Register */
+#define A10_MMC_BKSR 0x10 /* Block Size Register */
+#define A10_MMC_BYCR 0x14 /* Byte Count Register */
#define A10_MMC_CMDR 0x18 /* Command Register */
-#define A10_MMC_CARG 0x1C /* Argument Register */
+#define A10_MMC_CAGR 0x1C /* Argument Register */
#define A10_MMC_RESP0 0x20 /* Response Register 0 */
#define A10_MMC_RESP1 0x24 /* Response Register 1 */
#define A10_MMC_RESP2 0x28 /* Response Register 2 */
#define A10_MMC_RESP3 0x2C /* Response Register 3 */
-#define A10_MMC_IMASK 0x30 /* Interrupt Mask Register */
-#define A10_MMC_MISTA 0x34 /* Masked Interrupt Status Register */
-#define A10_MMC_RINTR 0x38 /* Raw Interrupt Status Register */
-#define A10_MMC_STAS 0x3C /* Status Register */
-#define A10_MMC_FTRGL 0x40 /* FIFO Threshold Watermark Register */
+#define A10_MMC_IMKR 0x30 /* Interrupt Mask Register */
+#define A10_MMC_MISR 0x34 /* Masked Interrupt Status Register */
+#define A10_MMC_RISR 0x38 /* Raw Interrupt Status Register */
+#define A10_MMC_STAR 0x3C /* Status Register */
+#define A10_MMC_FWLR 0x40 /* FIFO Threshold Watermark Register */
#define A10_MMC_FUNS 0x44 /* Function Select Register */
-#define A10_MMC_CBCR 0x48 /* CIU Byte Count Register */
-#define A10_MMC_BBCR 0x4C /* BIU Byte Count Register */
-#define A10_MMC_DBGC 0x50 /* Debug Enable Register */
+#define A10_MMC_HWRST 0x78 /* Hardware reset (not documented) */
#define A10_MMC_DMAC 0x80 /* IDMAC Control Register */
#define A10_MMC_DLBA 0x84 /* IDMAC Desc List Base Address Reg */
#define A10_MMC_IDST 0x88 /* IDMAC Status Register */
#define A10_MMC_IDIE 0x8C /* IDMAC Interrupt Enable Register */
-#define A10_MMC_CHDA 0x90
-#define A10_MMC_CBDA 0x94
-#define A10_MMC_FIFO 0x100 /* FIFO Access Address (A10/A20) */
-#define A31_MMC_FIFO 0x200 /* FIFO Access Address (A31) */
+#define A10_MMC_FIFO 0x100 /* FIFO Access Address (A10/A20) */
+#define A31_MMC_FIFO 0x200 /* FIFO Access Address (A31) */
-/* A10_MMC_GCTRL */
-#define A10_MMC_SOFT_RESET (1U << 0)
-#define A10_MMC_FIFO_RESET (1U << 1)
-#define A10_MMC_DMA_RESET (1U << 2)
-#define A10_MMC_INT_ENABLE (1U << 4)
-#define A10_MMC_DMA_ENABLE (1U << 5)
-#define A10_MMC_DEBOUNCE_ENABLE (1U << 8)
-#define A10_MMC_DDR_MODE (1U << 10)
-#define A10_MMC_ACCESS_BY_AHB (1U << 31)
+/* A10_MMC_GCTL */
+#define A10_MMC_CTRL_SOFT_RST (1U << 0)
+#define A10_MMC_CTRL_FIFO_RST (1U << 1)
+#define A10_MMC_CTRL_DMA_RST (1U << 2)
+#define A10_MMC_CTRL_INT_ENB (1U << 4)
+#define A10_MMC_CTRL_DMA_ENB (1U << 5)
+#define A10_MMC_CTRL_CD_DBC_ENB (1U << 8)
+#define A10_MMC_CTRL_DDR_MOD_SEL (1U << 10)
+#define A10_MMC_CTRL_FIFO_AC_MOD (1U << 31)
#define A10_MMC_RESET \
- (A10_MMC_SOFT_RESET | A10_MMC_FIFO_RESET | A10_MMC_DMA_RESET)
+ (A10_MMC_CTRL_SOFT_RST | A10_MMC_CTRL_FIFO_RST | A10_MMC_CTRL_DMA_RST)
-/* A10_MMC_CLKCR */
-#define A10_MMC_CARD_CLK_ON (1U << 16)
-#define A10_MMC_LOW_POWER_ON (1U << 17)
-#define A10_MMC_CLKCR_DIV 0xff
+/* A10_MMC_CKCR */
+#define A10_MMC_CKCR_CCLK_ENB (1U << 16)
+#define A10_MMC_CKCR_CCLK_CTRL (1U << 17)
+#define A10_MMC_CKCR_CCLK_DIV 0xff
-/* A10_MMC_WIDTH */
-#define A10_MMC_WIDTH1 0
-#define A10_MMC_WIDTH4 1
-#define A10_MMC_WIDTH8 2
+/* A10_MMC_TMOR */
+#define A10_MMC_TMOR_RTO_LMT_SHIFT(x) x /* Response timeout limit */
+#define A10_MMC_TMOR_RTO_LMT_MASK 0xff
+#define A10_MMC_TMOR_DTO_LMT_SHIFT(x) (x << 8) /* Data timeout limit */
+#define A10_MMC_TMOR_DTO_LMT_MASK 0xffffff
+
+/* A10_MMC_BWDR */
+#define A10_MMC_BWDR1 0
+#define A10_MMC_BWDR4 1
+#define A10_MMC_BWDR8 2
/* A10_MMC_CMDR */
-#define A10_MMC_RESP_EXP (1U << 6)
-#define A10_MMC_LONG_RESP (1U << 7)
-#define A10_MMC_CHECK_RESP_CRC (1U << 8)
-#define A10_MMC_DATA_EXP (1U << 9)
-#define A10_MMC_WRITE (1U << 10)
-#define A10_MMC_SEQ_MODE (1U << 11)
-#define A10_MMC_SEND_AUTOSTOP (1U << 12)
-#define A10_MMC_WAIT_PREOVER (1U << 13)
-#define A10_MMC_STOP_ABORT_CMD (1U << 14)
-#define A10_MMC_SEND_INIT_SEQ (1U << 15)
-#define A10_MMC_UPCLK_ONLY (1U << 21)
-#define A10_MMC_RDCEATADEV (1U << 22)
-#define A10_MMC_CCS_EXP (1U << 23)
-#define A10_MMC_ENB_BOOT (1U << 24)
-#define A10_MMC_ALT_BOOT_OPT (1U << 25)
-#define A10_MMC_BOOT_ACK_EXP (1U << 26)
-#define A10_MMC_DISABLE_BOOT (1U << 27)
-#define A10_MMC_VOL_SWITCH (1U << 28)
-#define A10_MMC_START (1U << 31)
+#define A10_MMC_CMDR_RESP_RCV (1U << 6)
+#define A10_MMC_CMDR_LONG_RESP (1U << 7)
+#define A10_MMC_CMDR_CHK_RESP_CRC (1U << 8)
+#define A10_MMC_CMDR_DATA_TRANS (1U << 9)
+#define A10_MMC_CMDR_DIR_WRITE (1U << 10)
+#define A10_MMC_CMDR_TRANS_MODE_STREAM (1U << 11)
+#define A10_MMC_CMDR_STOP_CMD_FLAG (1U << 12)
+#define A10_MMC_CMDR_WAIT_PRE_OVER (1U << 13)
+#define A10_MMC_CMDR_STOP_ABT_CMD (1U << 14)
+#define A10_MMC_CMDR_SEND_INIT_SEQ (1U << 15)
+#define A10_MMC_CMDR_PRG_CLK (1U << 21)
+#define A10_MMC_CMDR_RD_CEDATA_DEV (1U << 22)
+#define A10_MMC_CMDR_CCS_EXP (1U << 23)
+#define A10_MMC_CMDR_BOOT_MOD_SHIFT 24
+#define A10_MMC_CMDR_BOOT_MOD_NORMAL 0
+#define A10_MMC_CMDR_BOOT_MOD_MANDATORY 1
+#define A10_MMC_CMDR_BOOT_MOD_ALT 2
+#define A10_MMC_CMDR_EXP_BOOT_ACK (1U << 26)
+#define A10_MMC_CMDR_BOOT_ABT (1U << 27)
+#define A10_MMC_CMDR_VOL_SW (1U << 28)
+#define A10_MMC_CMDR_LOAD (1U << 31)
-/* A10_MMC_IMASK and A10_MMC_RINTR */
-#define A10_MMC_RESP_ERR (1U << 1)
-#define A10_MMC_CMD_DONE (1U << 2)
-#define A10_MMC_DATA_OVER (1U << 3)
-#define A10_MMC_TX_DATA_REQ (1U << 4)
-#define A10_MMC_RX_DATA_REQ (1U << 5)
-#define A10_MMC_RESP_CRC_ERR (1U << 6)
-#define A10_MMC_DATA_CRC_ERR (1U << 7)
-#define A10_MMC_RESP_TIMEOUT (1U << 8)
-#define A10_MMC_ACK_RECV (1U << 8)
-#define A10_MMC_DATA_TIMEOUT (1U << 9)
-#define A10_MMC_BOOT_START (1U << 9)
-#define A10_MMC_DATA_STARVE (1U << 10)
-#define A10_MMC_VOL_CHG_DONE (1U << 10)
-#define A10_MMC_FIFO_RUN_ERR (1U << 11)
-#define A10_MMC_HARDW_LOCKED (1U << 12)
-#define A10_MMC_START_BIT_ERR (1U << 13)
-#define A10_MMC_AUTOCMD_DONE (1U << 14)
-#define A10_MMC_END_BIT_ERR (1U << 15)
-#define A10_MMC_SDIO_INT (1U << 16)
-#define A10_MMC_CARD_INSERT (1U << 30)
-#define A10_MMC_CARD_REMOVE (1U << 31)
+/* A10_MMC_IMKR and A10_MMC_RISR */
+#define A10_MMC_INT_RESP_ERR (1U << 1)
+#define A10_MMC_INT_CMD_DONE (1U << 2)
+#define A10_MMC_INT_DATA_OVER (1U << 3)
+#define A10_MMC_INT_TX_DATA_REQ (1U << 4)
+#define A10_MMC_INT_RX_DATA_REQ (1U << 5)
+#define A10_MMC_INT_RESP_CRC_ERR (1U << 6)
+#define A10_MMC_INT_DATA_CRC_ERR (1U << 7)
+#define A10_MMC_INT_RESP_TIMEOUT (1U << 8)
+#define A10_MMC_INT_BOOT_ACK_RECV (1U << 8)
+#define A10_MMC_INT_DATA_TIMEOUT (1U << 9)
+#define A10_MMC_INT_BOOT_START (1U << 9)
+#define A10_MMC_INT_DATA_STARVE (1U << 10)
+#define A10_MMC_INT_VOL_CHG_DONE (1U << 10)
+#define A10_MMC_INT_FIFO_RUN_ERR (1U << 11)
+#define A10_MMC_INT_CMD_BUSY (1U << 12)
+#define A10_MMC_INT_DATA_START_ERR (1U << 13)
+#define A10_MMC_INT_AUTO_STOP_DONE (1U << 14)
+#define A10_MMC_INT_DATA_END_BIT_ERR (1U << 15)
+#define A10_MMC_INT_SDIO (1U << 16)
+#define A10_MMC_INT_CARD_INSERT (1U << 30)
+#define A10_MMC_INT_CARD_REMOVE (1U << 31)
#define A10_MMC_INT_ERR_BIT \
- (A10_MMC_RESP_ERR | A10_MMC_RESP_CRC_ERR | \
- A10_MMC_DATA_CRC_ERR | A10_MMC_RESP_TIMEOUT | \
- A10_MMC_FIFO_RUN_ERR | A10_MMC_HARDW_LOCKED | \
- A10_MMC_START_BIT_ERR | A10_MMC_END_BIT_ERR)
+ (A10_MMC_INT_RESP_ERR | A10_MMC_INT_RESP_CRC_ERR | \
+ A10_MMC_INT_DATA_CRC_ERR | A10_MMC_INT_RESP_TIMEOUT | \
+ A10_MMC_INT_FIFO_RUN_ERR | A10_MMC_INT_CMD_BUSY | \
+ A10_MMC_INT_DATA_START_ERR | A10_MMC_INT_DATA_END_BIT_ERR)
-/* A10_MMC_STAS */
-#define A10_MMC_RX_WLFLAG (1U << 0)
-#define A10_MMC_TX_WLFLAG (1U << 1)
-#define A10_MMC_FIFO_EMPTY (1U << 2)
-#define A10_MMC_FIFO_FULL (1U << 3)
-#define A10_MMC_CARD_PRESENT (1U << 8)
-#define A10_MMC_CARD_DATA_BUSY (1U << 9)
-#define A10_MMC_DATA_FSM_BUSY (1U << 10)
-#define A10_MMC_DMA_REQ (1U << 31)
-#define A10_MMC_FIFO_SIZE 16
+/* A10_MMC_STAR */
+#define A10_MMC_STAR_FIFO_RX_LEVEL (1U << 0)
+#define A10_MMC_STAR_FIFO_TX_LEVEL (1U << 1)
+#define A10_MMC_STAR_FIFO_EMPTY (1U << 2)
+#define A10_MMC_STAR_FIFO_FULL (1U << 3)
+#define A10_MMC_STAR_CARD_PRESENT (1U << 8)
+#define A10_MMC_STAR_CARD_BUSY (1U << 9)
+#define A10_MMC_STAR_FSM_BUSY (1U << 10)
+#define A10_MMC_STAR_DMA_REQ (1U << 31)
/* A10_MMC_FUNS */
#define A10_MMC_CE_ATA_ON (0xceaaU << 16)
@@ -151,49 +154,51 @@
#define A10_MMC_CE_ATA_DEV_INT_ENB (1U << 10)
/* IDMA CONTROLLER BUS MOD BIT FIELD */
-#define A10_MMC_IDMAC_SOFT_RST (1U << 0)
-#define A10_MMC_IDMAC_FIX_BURST (1U << 1)
-#define A10_MMC_IDMAC_IDMA_ON (1U << 7)
-#define A10_MMC_IDMAC_REFETCH_DES (1U << 31)
+#define A10_MMC_DMAC_IDMAC_SOFT_RST (1U << 0)
+#define A10_MMC_DMAC_IDMAC_FIX_BURST (1U << 1)
+#define A10_MMC_DMAC_IDMAC_IDMA_ON (1U << 7)
+#define A10_MMC_DMAC_IDMAC_REFETCH_DES (1U << 31)
/* A10_MMC_IDST */
-#define A10_MMC_IDMAC_TRANSMIT_INT (1U << 0)
-#define A10_MMC_IDMAC_RECEIVE_INT (1U << 1)
-#define A10_MMC_IDMAC_FATAL_BUS_ERR (1U << 2)
-#define A10_MMC_IDMAC_DES_INVALID (1U << 4)
-#define A10_MMC_IDMAC_CARD_ERR_SUM (1U << 5)
-#define A10_MMC_IDMAC_NORMAL_INT_SUM (1U << 8)
-#define A10_MMC_IDMAC_ABNORMAL_INT_SUM (1U << 9)
-#define A10_MMC_IDMAC_HOST_ABT_INTX (1U << 10)
-#define A10_MMC_IDMAC_HOST_ABT_INRX (1U << 10)
-#define A10_MMC_IDMAC_IDLE (0U << 13)
-#define A10_MMC_IDMAC_SUSPEND (1U << 13)
-#define A10_MMC_IDMAC_DESC_RD (2U << 13)
-#define A10_MMC_IDMAC_DESC_CHECK (3U << 13)
-#define A10_MMC_IDMAC_RD_REQ_WAIT (4U << 13)
-#define A10_MMC_IDMAC_WR_REQ_WAIT (5U << 13)
-#define A10_MMC_IDMAC_RD (6U << 13)
-#define A10_MMC_IDMAC_WR (7U << 13)
-#define A10_MMC_IDMAC_DESC_CLOSE (8U << 13)
-#define A10_MMC_IDMAC_ERROR \
- (A10_MMC_IDMAC_FATAL_BUS_ERR | A10_MMC_IDMAC_CARD_ERR_SUM | \
- A10_MMC_IDMAC_DES_INVALID | A10_MMC_IDMAC_ABNORMAL_INT_SUM)
-#define A10_MMC_IDMAC_COMPLETE \
- (A10_MMC_IDMAC_TRANSMIT_INT | A10_MMC_IDMAC_RECEIVE_INT)
+#define A10_MMC_IDST_TX_INT (1U << 0)
+#define A10_MMC_IDST_RX_INT (1U << 1)
+#define A10_MMC_IDST_FATAL_BERR_INT (1U << 2)
+#define A10_MMC_IDST_DES_UNAVL_INT (1U << 4)
+#define A10_MMC_IDST_ERR_FLAG_SUM (1U << 5)
+#define A10_MMC_IDST_NOR_INT_SUM (1U << 8)
+#define A10_MMC_IDST_ABN_INT_SUM (1U << 9)
+#define A10_MMC_IDST_HOST_ABT_INTX (1U << 10)
+#define A10_MMC_IDST_HOST_ABT_INRX (1U << 10)
+#define A10_MMC_IDST_IDLE (0U << 13)
+#define A10_MMC_IDST_SUSPEND (1U << 13)
+#define A10_MMC_IDST_DESC_RD (2U << 13)
+#define A10_MMC_IDST_DESC_CHECK (3U << 13)
+#define A10_MMC_IDST_RD_REQ_WAIT (4U << 13)
+#define A10_MMC_IDST_WR_REQ_WAIT (5U << 13)
+#define A10_MMC_IDST_RD (6U << 13)
+#define A10_MMC_IDST_WR (7U << 13)
+#define A10_MMC_IDST_DESC_CLOSE (8U << 13)
+#define A10_MMC_IDST_ERROR \
+ (A10_MMC_IDST_FATAL_BERR_INT | A10_MMC_IDST_ERR_FLAG_SUM | \
+ A10_MMC_IDST_DES_UNAVL_INT | A10_MMC_IDST_ABN_INT_SUM)
+#define A10_MMC_IDST_COMPLETE \
+ (A10_MMC_IDST_TX_INT | A10_MMC_IDST_RX_INT)
/* The DMA descriptor table. */
struct a10_mmc_dma_desc {
uint32_t config;
-#define A10_MMC_DMA_CONFIG_DIC (1U << 1)
-#define A10_MMC_DMA_CONFIG_LD (1U << 2)
-#define A10_MMC_DMA_CONFIG_FD (1U << 3)
-#define A10_MMC_DMA_CONFIG_CH (1U << 4)
-#define A10_MMC_DMA_CONFIG_ER (1U << 5)
-#define A10_MMC_DMA_CONFIG_CES (1U << 30)
-#define A10_MMC_DMA_CONFIG_OWN (1U << 31)
+#define A10_MMC_DMA_CONFIG_DIC (1U << 1) /* Disable Interrupt Completion */
+#define A10_MMC_DMA_CONFIG_LD (1U << 2) /* Last DES */
+#define A10_MMC_DMA_CONFIG_FD (1U << 3) /* First DES */
+#define A10_MMC_DMA_CONFIG_CH (1U << 4) /* CHAIN MOD */
+#define A10_MMC_DMA_CONFIG_ER (1U << 5) /* End of Ring (undocumented register) */
+#define A10_MMC_DMA_CONFIG_CES (1U << 30) /* Card Error Summary */
+#define A10_MMC_DMA_CONFIG_OWN (1U << 31) /* DES Own Flag */
uint32_t buf_size;
uint32_t buf_addr;
uint32_t next;
};
+#define A10_MMC_DMA_ALIGN 4
+
#endif /* _A10_MMC_H_ */
diff --git a/sys/arm/allwinner/aw_if_dwc.c b/sys/arm/allwinner/aw_if_dwc.c
index 2f88d9d..aaf05df 100644
--- a/sys/arm/allwinner/aw_if_dwc.c
+++ b/sys/arm/allwinner/aw_if_dwc.c
@@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
-#include <arm/allwinner/allwinner_machdep.h>
+#include <arm/allwinner/aw_machdep.h>
#include <dev/extres/clk/clk.h>
#include <dev/extres/regulator/regulator.h>
@@ -73,7 +73,7 @@ a20_if_dwc_init(device_t dev)
/* Configure PHY for MII or RGMII mode */
if (OF_getprop_alloc(node, "phy-mode", 1, (void **)&phy_type)) {
- error = clk_get_by_ofw_name(dev, "allwinner_gmac_tx", &clk_tx);
+ error = clk_get_by_ofw_name(dev, 0, "allwinner_gmac_tx", &clk_tx);
if (error != 0) {
device_printf(dev, "could not get tx clk\n");
return (error);
@@ -99,7 +99,7 @@ a20_if_dwc_init(device_t dev)
}
/* Enable PHY regulator if applicable */
- if (regulator_get_by_ofw_property(dev, "phy-supply", &reg) == 0) {
+ if (regulator_get_by_ofw_property(dev, 0, "phy-supply", &reg) == 0) {
error = regulator_enable(reg);
if (error != 0) {
device_printf(dev, "could not enable PHY regulator\n");
diff --git a/sys/arm/allwinner/allwinner_machdep.c b/sys/arm/allwinner/aw_machdep.c
index 621b875..3fab0a1 100644
--- a/sys/arm/allwinner/allwinner_machdep.c
+++ b/sys/arm/allwinner/aw_machdep.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2012 Ganbold Tsagaankhuu <ganbold@freebsd.org>
- * Copyright (c) 2015-2016 Emmanuel Vadot <manu@bidouilliste.com>
+ * Copyright (c) 2015-2016 Emmanuel Vadot <manu@freebsd.org>
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
@@ -26,6 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+
* from: FreeBSD: //depot/projects/arm/src/sys/arm/ti/ti_machdep.c
*/
@@ -52,7 +53,7 @@ __FBSDID("$FreeBSD$");
#include <arm/allwinner/aw_mp.h>
#include <arm/allwinner/aw_wdog.h>
-#include <arm/allwinner/allwinner_machdep.h>
+#include <arm/allwinner/aw_machdep.h>
#include "platform_if.h"
diff --git a/sys/arm/allwinner/allwinner_machdep.h b/sys/arm/allwinner/aw_machdep.h
index de1d3f4..0e29840 100644
--- a/sys/arm/allwinner/allwinner_machdep.h
+++ b/sys/arm/allwinner/aw_machdep.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015 Emmanuel Vadot <manu@bidouilliste.com>
+ * Copyright (c) 2015 Emmanuel Vadot <manu@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/sys/arm/allwinner/aw_mp.c b/sys/arm/allwinner/aw_mp.c
index bf6f619..9d44c3e 100644
--- a/sys/arm/allwinner/aw_mp.c
+++ b/sys/arm/allwinner/aw_mp.c
@@ -46,7 +46,7 @@ __FBSDID("$FreeBSD$");
#include <machine/platformvar.h>
#include <arm/allwinner/aw_mp.h>
-#include <arm/allwinner/allwinner_machdep.h>
+#include <arm/allwinner/aw_machdep.h>
/* Register for all dual-core SoC */
#define A20_CPUCFG_BASE 0x01c25c00
diff --git a/sys/arm/allwinner/aw_rsb.c b/sys/arm/allwinner/aw_rsb.c
index 0011b43..2cdee9e 100644
--- a/sys/arm/allwinner/aw_rsb.c
+++ b/sys/arm/allwinner/aw_rsb.c
@@ -395,14 +395,14 @@ rsb_attach(device_t dev)
sc = device_get_softc(dev);
mtx_init(&sc->mtx, device_get_nameunit(dev), "rsb", MTX_DEF);
- if (clk_get_by_ofw_index(dev, 0, &sc->clk) == 0) {
+ if (clk_get_by_ofw_index(dev, 0, 0, &sc->clk) == 0) {
error = clk_enable(sc->clk);
if (error != 0) {
device_printf(dev, "cannot enable clock\n");
goto fail;
}
}
- if (hwreset_get_by_ofw_idx(dev, 0, &sc->rst) == 0) {
+ if (hwreset_get_by_ofw_idx(dev, 0, 0, &sc->rst) == 0) {
error = hwreset_deassert(sc->rst);
if (error != 0) {
device_printf(dev, "cannot de-assert reset\n");
diff --git a/sys/arm/allwinner/aw_rtc.c b/sys/arm/allwinner/aw_rtc.c
index 28b7ecd..0b60ddc 100644
--- a/sys/arm/allwinner/aw_rtc.c
+++ b/sys/arm/allwinner/aw_rtc.c
@@ -43,7 +43,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
-#include <arm/allwinner/allwinner_machdep.h>
+#include <arm/allwinner/aw_machdep.h>
#include "clock_if.h"
diff --git a/sys/arm/allwinner/aw_ts.c b/sys/arm/allwinner/aw_ts.c
new file mode 100644
index 0000000..e010ac4
--- /dev/null
+++ b/sys/arm/allwinner/aw_ts.c
@@ -0,0 +1,230 @@
+/*-
+ * Copyright (c) 2016 Emmanuel Vadot <manu@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.
+ */
+
+/*
+ * Allwinner Touch Sreen driver
+ * Touch screen part is not done, only the thermal sensor part is.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/sysctl.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>
+
+#define READ(_sc, _r) bus_read_4((_sc)->res[0], (_r))
+#define WRITE(_sc, _r, _v) bus_write_4((_sc)->res[0], (_r), (_v))
+
+/* Control register 0 */
+#define TP_CTRL0 0x00
+#define TP_CTRL0_TACQ(x) ((x & 0xFF) << 0)
+#define TP_CTRL0_FS_DIV(x) ((x & 0xF) << 16)
+#define TP_CTRL0_CLK_DIV(x) ((x & 0x3) << 20)
+#define TP_CTRL0_CLK_SELECT(x) ((x & 0x1) << 22)
+
+/* Control register 1 */
+#define TP_CTRL1 0x04
+#define TP_CTRL1_MODE_EN (1 << 4)
+
+/* Control register 2 */
+#define TP_CTRL2 0x08
+
+/* Control register 3 */
+#define TP_CTRL3 0x0C
+
+/* Int/FIFO control register */
+#define TP_FIFOC 0x10
+#define TP_FIFOC_TEMP_IRQ_ENABLE (1 << 18)
+
+/* Int/FIFO status register */
+#define TP_FIFOS 0x14
+#define TP_FIFOS_TEMP_IRQ_PENDING (1 << 18)
+
+/* Temperature Period Register */
+#define TP_TPR 0x18
+#define TP_TPR_TEMP_EN (1 << 16)
+#define TP_TPR_TEMP_PERIOD(x) (x << 0)
+
+/* Common data register */
+#define TP_CDAT 0x1C
+
+/* Temperature data register */
+#define TEMP_DATA 0x20
+
+/* TP Data register*/
+#define TP_DATA 0x24
+
+/* TP IO config register */
+#define TP_IO_CONFIG 0x28
+
+/* TP IO port data register */
+#define TP_IO_DATA 0x2C
+
+struct aw_ts_softc {
+ device_t dev;
+ struct resource * res[2];
+ void * intrhand;
+ int temp_data;
+ int temp_offset;
+ int temp_step;
+};
+
+static struct resource_spec aw_ts_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE },
+ { -1, 0 }
+};
+
+#define A10_TS 1
+#define A13_TS 2
+
+#define AW_TS_TEMP_SYSCTL 1
+
+static struct ofw_compat_data compat_data[] = {
+ {"allwinner,sun4i-a10-ts", A10_TS},
+ {"allwinner,sun5i-a13-ts", A13_TS},
+ {NULL, 0}
+};
+
+static void
+aw_ts_intr(void *arg)
+{
+ struct aw_ts_softc *sc;
+ int val;
+
+ sc= (struct aw_ts_softc *)arg;
+
+ val = READ(sc, TP_FIFOS);
+ if (val & TP_FIFOS_TEMP_IRQ_PENDING) {
+ /* Convert the value to millicelsius then millikelvin */
+ sc->temp_data = (READ(sc, TEMP_DATA) * sc->temp_step - sc->temp_offset)
+ + 273150;
+ }
+
+ WRITE(sc, TP_FIFOS, val);
+}
+
+static int
+aw_ts_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "Allwinner Touch Screen controller");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+aw_ts_attach(device_t dev)
+{
+ struct aw_ts_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ if (bus_alloc_resources(dev, aw_ts_spec, sc->res) != 0) {
+ device_printf(dev, "could not allocate memory resource\n");
+ return (ENXIO);
+ }
+
+ if (bus_setup_intr(dev, sc->res[1],
+ INTR_TYPE_MISC | INTR_MPSAFE, NULL, aw_ts_intr, sc,
+ &sc->intrhand)) {
+ bus_release_resources(dev, aw_ts_spec, sc->res);
+ device_printf(dev, "cannot setup interrupt handler\n");
+ return (ENXIO);
+ }
+
+ /*
+ * Thoses magic values were taken from linux which take them from
+ * the allwinner SDK or found them by deduction
+ */
+ switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) {
+ case A10_TS:
+ sc->temp_offset = 257000;
+ sc->temp_step = 133;
+ break;
+ case A13_TS:
+ sc->temp_offset = 144700;
+ sc->temp_step = 100;
+ break;
+ }
+
+ /* Enable clock and set divisers */
+ WRITE(sc, TP_CTRL0, TP_CTRL0_CLK_SELECT(0) |
+ TP_CTRL0_CLK_DIV(2) |
+ TP_CTRL0_FS_DIV(7) |
+ TP_CTRL0_TACQ(63));
+
+ /* Enable TS module */
+ WRITE(sc, TP_CTRL1, TP_CTRL1_MODE_EN);
+
+ /* Enable Temperature, period is ~2s */
+ WRITE(sc, TP_TPR, TP_TPR_TEMP_EN | TP_TPR_TEMP_PERIOD(1953));
+
+ /* Enable temp irq */
+ WRITE(sc, TP_FIFOC, TP_FIFOC_TEMP_IRQ_ENABLE);
+
+ /* Add sysctl */
+ SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD,
+ &sc->temp_data, 0, sysctl_handle_int,
+ "IK3", "CPU Temperature");
+
+ return (0);
+}
+
+static device_method_t aw_ts_methods[] = {
+ DEVMETHOD(device_probe, aw_ts_probe),
+ DEVMETHOD(device_attach, aw_ts_attach),
+
+ DEVMETHOD_END
+};
+
+static driver_t aw_ts_driver = {
+ "aw_ts",
+ aw_ts_methods,
+ sizeof(struct aw_ts_softc),
+};
+static devclass_t aw_ts_devclass;
+
+DRIVER_MODULE(aw_ts, simplebus, aw_ts_driver, aw_ts_devclass, 0, 0);
diff --git a/sys/arm/allwinner/aw_usbphy.c b/sys/arm/allwinner/aw_usbphy.c
index 3eb3c65..62b17ca 100644
--- a/sys/arm/allwinner/aw_usbphy.c
+++ b/sys/arm/allwinner/aw_usbphy.c
@@ -87,7 +87,7 @@ awusbphy_init(device_t dev)
node = ofw_bus_get_node(dev);
/* Enable clocks */
- for (off = 0; clk_get_by_ofw_index(dev, off, &clk) == 0; off++) {
+ for (off = 0; clk_get_by_ofw_index(dev, 0, off, &clk) == 0; off++) {
error = clk_enable(clk);
if (error != 0) {
device_printf(dev, "couldn't enable clock %s\n",
@@ -97,7 +97,7 @@ awusbphy_init(device_t dev)
}
/* De-assert resets */
- for (off = 0; hwreset_get_by_ofw_idx(dev, off, &rst) == 0; off++) {
+ for (off = 0; hwreset_get_by_ofw_idx(dev, 0, off, &rst) == 0; off++) {
error = hwreset_deassert(rst);
if (error != 0) {
device_printf(dev, "couldn't de-assert reset %d\n",
@@ -109,7 +109,7 @@ awusbphy_init(device_t dev)
/* Get regulators */
for (off = 0; off < USBPHY_NPHYS; off++) {
snprintf(pname, sizeof(pname), "usb%d_vbus-supply", off);
- if (regulator_get_by_ofw_property(dev, pname, &reg) == 0)
+ if (regulator_get_by_ofw_property(dev, 0, pname, &reg) == 0)
sc->reg[off] = reg;
}
diff --git a/sys/arm/allwinner/aw_wdog.c b/sys/arm/allwinner/aw_wdog.c
index 2630623..95dd20e 100644
--- a/sys/arm/allwinner/aw_wdog.c
+++ b/sys/arm/allwinner/aw_wdog.c
@@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus_subr.h>
#include <machine/bus.h>
-#include <machine/cpufunc.h>
#include <machine/machdep.h>
#include <arm/allwinner/aw_wdog.h>
diff --git a/sys/arm/allwinner/clk/aw_ahbclk.c b/sys/arm/allwinner/clk/aw_ahbclk.c
index 00a0afe..f2c7005 100644
--- a/sys/arm/allwinner/clk/aw_ahbclk.c
+++ b/sys/arm/allwinner/clk/aw_ahbclk.c
@@ -315,7 +315,7 @@ aw_ahbclk_attach(device_t dev)
def.parent_names = malloc(sizeof(char *) * ncells, M_OFWPROP,
M_WAITOK);
for (i = 0; i < ncells; i++) {
- error = clk_get_by_ofw_index(dev, i, &clk_parent);
+ error = clk_get_by_ofw_index(dev, 0, i, &clk_parent);
if (error != 0) {
device_printf(dev, "cannot get clock %d\n", i);
goto fail;
diff --git a/sys/arm/allwinner/clk/aw_apbclk.c b/sys/arm/allwinner/clk/aw_apbclk.c
index 7620c45..2c24f3d 100644
--- a/sys/arm/allwinner/clk/aw_apbclk.c
+++ b/sys/arm/allwinner/clk/aw_apbclk.c
@@ -248,7 +248,7 @@ aw_apbclk_attach(device_t dev)
def.id = 1;
def.parent_names = malloc(sizeof(char *) * ncells, M_OFWPROP, M_WAITOK);
for (i = 0; i < ncells; i++) {
- error = clk_get_by_ofw_index(dev, i, &clk_parent);
+ error = clk_get_by_ofw_index(dev, 0, i, &clk_parent);
if (error != 0) {
device_printf(dev, "cannot get clock %d\n", i);
goto fail;
diff --git a/sys/arm/allwinner/clk/aw_axiclk.c b/sys/arm/allwinner/clk/aw_axiclk.c
index 8f4a6d6..ad236d2 100644
--- a/sys/arm/allwinner/clk/aw_axiclk.c
+++ b/sys/arm/allwinner/clk/aw_axiclk.c
@@ -135,7 +135,7 @@ aw_axiclk_attach(device_t dev)
clkdom = clkdom_create(dev);
- error = clk_get_by_ofw_index(dev, 0, &clk_parent);
+ error = clk_get_by_ofw_index(dev, 0, 0, &clk_parent);
if (error != 0) {
device_printf(dev, "cannot parse clock parent\n");
return (ENXIO);
diff --git a/sys/arm/allwinner/clk/aw_codecclk.c b/sys/arm/allwinner/clk/aw_codecclk.c
index 5c50f49..8da00ad 100644
--- a/sys/arm/allwinner/clk/aw_codecclk.c
+++ b/sys/arm/allwinner/clk/aw_codecclk.c
@@ -120,7 +120,7 @@ aw_codecclk_attach(device_t dev)
goto fail;
}
- error = clk_get_by_ofw_index(dev, 0, &clk_parent);
+ error = clk_get_by_ofw_index(dev, 0, 0, &clk_parent);
if (error != 0) {
device_printf(dev, "cannot parse clock parent\n");
return (ENXIO);
diff --git a/sys/arm/allwinner/clk/aw_cpuclk.c b/sys/arm/allwinner/clk/aw_cpuclk.c
index 7beffcd..d6ae458 100644
--- a/sys/arm/allwinner/clk/aw_cpuclk.c
+++ b/sys/arm/allwinner/clk/aw_cpuclk.c
@@ -95,7 +95,7 @@ aw_cpuclk_attach(device_t dev)
def.clkdef.parent_names = malloc(sizeof(char *) * ncells, M_OFWPROP,
M_WAITOK);
for (i = 0; i < ncells; i++) {
- error = clk_get_by_ofw_index(dev, i, &clk);
+ error = clk_get_by_ofw_index(dev, 0, i, &clk);
if (error != 0) {
device_printf(dev, "cannot get clock %d\n", i);
goto fail;
diff --git a/sys/arm/allwinner/clk/aw_cpusclk.c b/sys/arm/allwinner/clk/aw_cpusclk.c
index 6d18284..781c83a 100644
--- a/sys/arm/allwinner/clk/aw_cpusclk.c
+++ b/sys/arm/allwinner/clk/aw_cpusclk.c
@@ -255,7 +255,7 @@ aw_cpusclk_attach(device_t dev)
def.parent_names = malloc(sizeof(char *) * ncells, M_OFWPROP,
M_WAITOK);
for (i = 0; i < ncells; i++) {
- error = clk_get_by_ofw_index(dev, i, &clk_parent);
+ error = clk_get_by_ofw_index(dev, 0, i, &clk_parent);
if (error != 0) {
device_printf(dev, "cannot get clock %d\n", i);
goto fail;
diff --git a/sys/arm/allwinner/clk/aw_debeclk.c b/sys/arm/allwinner/clk/aw_debeclk.c
index 885fad8..97f9d28 100644
--- a/sys/arm/allwinner/clk/aw_debeclk.c
+++ b/sys/arm/allwinner/clk/aw_debeclk.c
@@ -287,7 +287,7 @@ aw_debeclk_attach(device_t dev)
def.id = 1;
def.parent_names = malloc(sizeof(char *) * ncells, M_OFWPROP, M_WAITOK);
for (i = 0; i < ncells; i++) {
- error = clk_get_by_ofw_index(dev, i, &clk_parent);
+ error = clk_get_by_ofw_index(dev, 0, i, &clk_parent);
if (error != 0) {
device_printf(dev, "cannot get clock %d\n", i);
goto fail;
diff --git a/sys/arm/allwinner/clk/aw_gate.c b/sys/arm/allwinner/clk/aw_gate.c
index 27c0d78..e26ff89 100644
--- a/sys/arm/allwinner/clk/aw_gate.c
+++ b/sys/arm/allwinner/clk/aw_gate.c
@@ -168,7 +168,7 @@ aw_gate_attach(device_t dev)
goto fail;
}
- error = clk_get_by_ofw_index(dev, 0, &clk_parent);
+ error = clk_get_by_ofw_index(dev, 0, 0, &clk_parent);
if (error != 0) {
device_printf(dev, "cannot parse clock parent\n");
return (ENXIO);
diff --git a/sys/arm/allwinner/clk/aw_gmacclk.c b/sys/arm/allwinner/clk/aw_gmacclk.c
index 72495fd..8cc4ff2 100644
--- a/sys/arm/allwinner/clk/aw_gmacclk.c
+++ b/sys/arm/allwinner/clk/aw_gmacclk.c
@@ -240,7 +240,7 @@ aw_gmacclk_attach(device_t dev)
def.id = 1;
def.parent_names = malloc(sizeof(char *) * ncells, M_OFWPROP, M_WAITOK);
for (i = 0; i < ncells; i++) {
- error = clk_get_by_ofw_index(dev, i, &clk_parent);
+ error = clk_get_by_ofw_index(dev, 0, i, &clk_parent);
if (error != 0) {
device_printf(dev, "cannot get clock %d\n", error);
goto fail;
diff --git a/sys/arm/allwinner/clk/aw_hdmiclk.c b/sys/arm/allwinner/clk/aw_hdmiclk.c
index 635418c..9602dc6 100644
--- a/sys/arm/allwinner/clk/aw_hdmiclk.c
+++ b/sys/arm/allwinner/clk/aw_hdmiclk.c
@@ -249,7 +249,7 @@ aw_hdmiclk_attach(device_t dev)
clkdom = clkdom_create(dev);
- error = clk_get_by_ofw_index(dev, 0, &clk_parent);
+ error = clk_get_by_ofw_index(dev, 0, 0, &clk_parent);
if (error != 0) {
device_printf(dev, "cannot parse clock parent\n");
return (ENXIO);
diff --git a/sys/arm/allwinner/clk/aw_lcdclk.c b/sys/arm/allwinner/clk/aw_lcdclk.c
index 0cadabf..62213b8 100644
--- a/sys/arm/allwinner/clk/aw_lcdclk.c
+++ b/sys/arm/allwinner/clk/aw_lcdclk.c
@@ -493,7 +493,7 @@ aw_lcdclk_attach(device_t dev)
parent_names = malloc(sizeof(char *) * ncells, M_OFWPROP, M_WAITOK);
for (i = 0; i < ncells; i++) {
- error = clk_get_by_ofw_index(dev, i, &clk_parent);
+ error = clk_get_by_ofw_index(dev, 0, i, &clk_parent);
if (error != 0) {
device_printf(dev, "cannot get clock %d\n", i);
goto fail;
diff --git a/sys/arm/allwinner/clk/aw_mmcclk.c b/sys/arm/allwinner/clk/aw_mmcclk.c
index 653afd9..52ed231 100644
--- a/sys/arm/allwinner/clk/aw_mmcclk.c
+++ b/sys/arm/allwinner/clk/aw_mmcclk.c
@@ -292,7 +292,7 @@ aw_mmcclk_attach(device_t dev)
def.id = 0;
def.parent_names = malloc(sizeof(char *) * ncells, M_OFWPROP, M_WAITOK);
for (i = 0; i < ncells; i++) {
- error = clk_get_by_ofw_index(dev, i, &clk_parent);
+ error = clk_get_by_ofw_index(dev, 0, i, &clk_parent);
if (error != 0) {
device_printf(dev, "cannot get clock %d\n", i);
goto fail;
diff --git a/sys/arm/allwinner/clk/aw_modclk.c b/sys/arm/allwinner/clk/aw_modclk.c
index f4755ea..4b9087a 100644
--- a/sys/arm/allwinner/clk/aw_modclk.c
+++ b/sys/arm/allwinner/clk/aw_modclk.c
@@ -260,7 +260,7 @@ aw_modclk_attach(device_t dev)
def.id = 1;
def.parent_names = malloc(sizeof(char *) * ncells, M_OFWPROP, M_WAITOK);
for (i = 0; i < ncells; i++) {
- error = clk_get_by_ofw_index(dev, i, &clk_parent);
+ error = clk_get_by_ofw_index(dev, 0, i, &clk_parent);
if (error != 0) {
device_printf(dev, "cannot get clock %d\n", i);
goto fail;
diff --git a/sys/arm/allwinner/clk/aw_pll.c b/sys/arm/allwinner/clk/aw_pll.c
index 58d0833..f60af54 100644
--- a/sys/arm/allwinner/clk/aw_pll.c
+++ b/sys/arm/allwinner/clk/aw_pll.c
@@ -49,7 +49,7 @@ __FBSDID("$FreeBSD$");
#include <dt-bindings/clock/sun4i-a10-pll2.h>
-#include <arm/allwinner/allwinner_machdep.h>
+#include <arm/allwinner/aw_machdep.h>
#include "clkdev_if.h"
@@ -856,7 +856,7 @@ aw_pll_attach(device_t dev)
goto fail;
}
- if (clk_get_by_ofw_index(dev, 0, &clk_parent) != 0)
+ if (clk_get_by_ofw_index(dev, 0, 0, &clk_parent) != 0)
clk_parent = NULL;
for (index = 0; index < nout; index++) {
diff --git a/sys/arm/allwinner/clk/aw_usbclk.c b/sys/arm/allwinner/clk/aw_usbclk.c
index 444e295..e623e3b 100644
--- a/sys/arm/allwinner/clk/aw_usbclk.c
+++ b/sys/arm/allwinner/clk/aw_usbclk.c
@@ -202,13 +202,13 @@ aw_usbclk_attach(device_t dev)
else if (indices == NULL && type == AW_H3_USBCLK)
indices = aw_usbclk_indices_h3;
- error = clk_get_by_ofw_index(dev, 0, &clk_parent);
+ error = clk_get_by_ofw_index(dev, 0, 0, &clk_parent);
if (error != 0) {
device_printf(dev, "cannot parse clock parent\n");
return (ENXIO);
}
if (type == AW_A83T_USBCLK) {
- error = clk_get_by_ofw_index(dev, 1, &clk_parent_pll);
+ error = clk_get_by_ofw_index(dev, 0, 1, &clk_parent_pll);
if (error != 0) {
device_printf(dev, "cannot parse pll clock parent\n");
return (ENXIO);
diff --git a/sys/arm/allwinner/files.a10 b/sys/arm/allwinner/files.a10
deleted file mode 100644
index e7fd8d7..0000000
--- a/sys/arm/allwinner/files.a10
+++ /dev/null
@@ -1,5 +0,0 @@
-# $FreeBSD$
-
-arm/allwinner/a10/a10_intc.c standard
-arm/allwinner/a10_padconf.c standard
-arm/allwinner/timer.c standard
diff --git a/sys/arm/allwinner/files.allwinner b/sys/arm/allwinner/files.allwinner
index 4d8e071..6d716e5 100644
--- a/sys/arm/allwinner/files.allwinner
+++ b/sys/arm/allwinner/files.allwinner
@@ -14,9 +14,9 @@ arm/allwinner/aw_nmi.c optional intrng
arm/allwinner/aw_if_dwc.c optional dwc
arm/allwinner/aw_rsb.c optional rsb
arm/allwinner/aw_rtc.c standard
+arm/allwinner/aw_ts.c standard
arm/allwinner/aw_wdog.c standard
-arm/allwinner/a20/a20_cpu_cfg.c standard
-arm/allwinner/allwinner_machdep.c standard
+arm/allwinner/aw_machdep.c standard
arm/allwinner/aw_mp.c optional smp
arm/allwinner/axp209.c optional axp209
arm/allwinner/axp81x.c optional axp81x
diff --git a/sys/arm/allwinner/files.allwinner_up b/sys/arm/allwinner/files.allwinner_up
new file mode 100644
index 0000000..d90f99d
--- /dev/null
+++ b/sys/arm/allwinner/files.allwinner_up
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+arm/allwinner/timer.c standard
diff --git a/sys/arm/allwinner/if_awg.c b/sys/arm/allwinner/if_awg.c
index 6428fbd..cded892 100644
--- a/sys/arm/allwinner/if_awg.c
+++ b/sys/arm/allwinner/if_awg.c
@@ -931,12 +931,12 @@ awg_setup_extres(device_t dev)
phy_type = NULL;
/* Get AHB clock and reset resources */
- error = hwreset_get_by_ofw_name(dev, "ahb", &rst_ahb);
+ error = hwreset_get_by_ofw_name(dev, 0, "ahb", &rst_ahb);
if (error != 0) {
device_printf(dev, "cannot get ahb reset\n");
goto fail;
}
- error = clk_get_by_ofw_name(dev, "ahb", &clk_ahb);
+ error = clk_get_by_ofw_name(dev, 0, "ahb", &clk_ahb);
if (error != 0) {
device_printf(dev, "cannot get ahb clock\n");
goto fail;
@@ -954,7 +954,7 @@ awg_setup_extres(device_t dev)
OF_prop_free(phy_type);
/* Get the TX clock */
- error = clk_get_by_ofw_name(dev, "tx", &clk_tx);
+ error = clk_get_by_ofw_name(dev, 0, "tx", &clk_tx);
if (error != 0) {
device_printf(dev, "cannot get tx clock\n");
goto fail;
@@ -998,7 +998,7 @@ awg_setup_extres(device_t dev)
}
/* Enable PHY regulator if applicable */
- if (regulator_get_by_ofw_property(dev, "phy-supply", &reg) == 0) {
+ if (regulator_get_by_ofw_property(dev, 0, "phy-supply", &reg) == 0) {
error = regulator_enable(reg);
if (error != 0) {
device_printf(dev, "cannot enable PHY regulator\n");
diff --git a/sys/arm/allwinner/if_emac.c b/sys/arm/allwinner/if_emac.c
index 99cb9ab..097e4911 100644
--- a/sys/arm/allwinner/if_emac.c
+++ b/sys/arm/allwinner/if_emac.c
@@ -147,7 +147,7 @@ emac_sys_setup(struct emac_softc *sc)
int error;
/* Activate EMAC clock. */
- error = clk_get_by_ofw_index(sc->emac_dev, 0, &sc->emac_clk);
+ error = clk_get_by_ofw_index(sc->emac_dev, 0, 0, &sc->emac_clk);
if (error != 0) {
device_printf(sc->emac_dev, "cannot get clock\n");
return (error);
diff --git a/sys/arm/allwinner/std.a10 b/sys/arm/allwinner/std.allwinner_up
index b3770f8..6294cd0 100644
--- a/sys/arm/allwinner/std.a10
+++ b/sys/arm/allwinner/std.allwinner_up
@@ -1,4 +1,4 @@
-# Allwinner A10 common options
+# Allwinner Uniprocessor common options
#$FreeBSD$
cpu CPU_CORTEXA
@@ -8,6 +8,7 @@ makeoptions CONF_CFLAGS="-march=armv7a"
makeoptions KERNVIRTADDR=0xc0200000
options KERNVIRTADDR=0xc0200000
+files "../allwinner/files.allwinner_up"
files "../allwinner/files.allwinner"
-files "../allwinner/files.a10"
+files "../allwinner/a10/files.a10"
files "../allwinner/a13/files.a13"
diff --git a/sys/arm/allwinner/timer.c b/sys/arm/allwinner/timer.c
index 790b8e4..2b4ec84 100644
--- a/sys/arm/allwinner/timer.c
+++ b/sys/arm/allwinner/timer.c
@@ -51,7 +51,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kdb.h>
-#include <arm/allwinner/allwinner_machdep.h>
+#include <arm/allwinner/aw_machdep.h>
/**
* Timer registers addr
diff --git a/sys/arm/amlogic/aml8726/aml8726_machdep.c b/sys/arm/amlogic/aml8726/aml8726_machdep.c
index 58cf9b2..ee2ffd7 100644
--- a/sys/arm/amlogic/aml8726/aml8726_machdep.c
+++ b/sys/arm/amlogic/aml8726/aml8726_machdep.c
@@ -41,7 +41,6 @@ __FBSDID("$FreeBSD$");
#include <vm/pmap.h>
#include <machine/bus.h>
-#include <machine/cpufunc.h>
#include <machine/intr.h>
#include <machine/machdep.h>
#include <machine/platform.h>
diff --git a/sys/arm/amlogic/aml8726/aml8726_wdt.c b/sys/arm/amlogic/aml8726/aml8726_wdt.c
index 1e89f81..cd78c93 100644
--- a/sys/arm/amlogic/aml8726/aml8726_wdt.c
+++ b/sys/arm/amlogic/aml8726/aml8726_wdt.c
@@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$");
#include <sys/watchdog.h>
#include <machine/bus.h>
-#include <machine/cpufunc.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus.h>
diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c
index 133cc7f..ce8c28e 100644
--- a/sys/arm/arm/gic.c
+++ b/sys/arm/arm/gic.c
@@ -1700,15 +1700,15 @@ arm_gicv2m_release_msi(device_t dev, device_t child, int count,
mtx_lock(&sc->sc_mutex);
for (i = 0; i < count; i++) {
- gi = (struct gic_irqsrc *)isrc;
+ gi = (struct gic_irqsrc *)isrc[i];
KASSERT((gi->gi_flags & GI_FLAG_MSI_USED) == GI_FLAG_MSI_USED,
("%s: Trying to release an unused MSI-X interrupt",
__func__));
gi->gi_flags &= ~GI_FLAG_MSI_USED;
- mtx_unlock(&sc->sc_mutex);
}
+ mtx_unlock(&sc->sc_mutex);
return (0);
}
diff --git a/sys/arm/arm/nexus.c b/sys/arm/arm/nexus.c
index 0c5d1cf..879bc30 100644
--- a/sys/arm/arm/nexus.c
+++ b/sys/arm/arm/nexus.c
@@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
#ifdef FDT
#include <machine/fdt.h>
+#include <dev/ofw/ofw_bus_subr.h>
#include "ofw_bus_if.h"
#endif
@@ -379,6 +380,15 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid,
#endif
rman_set_virtual(r, (void *)vaddr);
rman_set_bushandle(r, vaddr);
+ return (0);
+ } else if (type == SYS_RES_IRQ) {
+#ifdef INTRNG
+ err = intr_activate_irq(child, r);
+ if (err != 0) {
+ rman_deactivate_resource(r);
+ return (err);
+ }
+#endif
}
return (0);
}
@@ -390,17 +400,23 @@ nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
bus_size_t psize;
bus_space_handle_t vaddr;
- psize = (bus_size_t)rman_get_size(r);
- vaddr = rman_get_bushandle(r);
+ if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+ psize = (bus_size_t)rman_get_size(r);
+ vaddr = rman_get_bushandle(r);
- if (vaddr != 0) {
+ if (vaddr != 0) {
#ifdef FDT
- bus_space_unmap(fdtbus_bs_tag, vaddr, psize);
+ bus_space_unmap(fdtbus_bs_tag, vaddr, psize);
#else
- pmap_unmapdev((vm_offset_t)vaddr, (vm_size_t)psize);
+ pmap_unmapdev((vm_offset_t)vaddr, (vm_size_t)psize);
+#endif
+ rman_set_virtual(r, NULL);
+ rman_set_bushandle(r, 0);
+ }
+ } else if (type == SYS_RES_IRQ) {
+#ifdef INTRNG
+ intr_deactivate_irq(child, r);
#endif
- rman_set_virtual(r, NULL);
- rman_set_bushandle(r, 0);
}
return (rman_deactivate_resource(r));
@@ -411,11 +427,22 @@ static int
nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells,
pcell_t *intr)
{
-
-#ifdef INTRNG
- return (INTR_IRQ_INVALID);
-#else
+#ifndef INTRNG
return (intr_fdt_map_irq(iparent, intr, icells));
-#endif
+#else
+ u_int irq;
+ struct intr_map_data_fdt *fdt_data;
+ size_t len;
+
+ len = sizeof(*fdt_data) + icells * sizeof(pcell_t);
+ fdt_data = (struct intr_map_data_fdt *)intr_alloc_map_data(
+ INTR_MAP_DATA_FDT, len, M_WAITOK | M_ZERO);
+ fdt_data->iparent = iparent;
+ fdt_data->ncells = icells;
+ memcpy(fdt_data->cells, intr, icells * sizeof(pcell_t));
+ irq = intr_map_irq(NULL, iparent, (struct intr_map_data *)fdt_data);
+ return (irq);
+#endif /* INTRNG */
}
-#endif
+#endif /* FDT */
+
diff --git a/sys/arm/at91/at91_aic.c b/sys/arm/at91/at91_aic.c
index 300c99a..92d6ead 100644
--- a/sys/arm/at91/at91_aic.c
+++ b/sys/arm/at91/at91_aic.c
@@ -38,8 +38,6 @@ __FBSDID("$FreeBSD$");
#include <machine/armreg.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/frame.h>
#include <machine/intr.h>
#include <machine/resource.h>
diff --git a/sys/arm/at91/at91_cfata.c b/sys/arm/at91/at91_cfata.c
index d4848ff..890029c 100644
--- a/sys/arm/at91/at91_cfata.c
+++ b/sys/arm/at91/at91_cfata.c
@@ -47,8 +47,6 @@ __FBSDID("$FreeBSD$");
#include <vm/uma.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
diff --git a/sys/arm/at91/at91_mci.c b/sys/arm/at91/at91_mci.c
index bb5b7d5..2049fc7 100644
--- a/sys/arm/at91/at91_mci.c
+++ b/sys/arm/at91/at91_mci.c
@@ -51,8 +51,6 @@ __FBSDID("$FreeBSD$");
#include <sys/watchdog.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
diff --git a/sys/arm/at91/at91_ohci.c b/sys/arm/at91/at91_ohci.c
index 3e39f51..4d8e301 100644
--- a/sys/arm/at91/at91_ohci.c
+++ b/sys/arm/at91/at91_ohci.c
@@ -165,14 +165,8 @@ static int
ohci_atmelarm_detach(device_t dev)
{
struct at91_ohci_softc *sc = device_get_softc(dev);
- device_t bdev;
int err;
- if (sc->sc_ohci.sc_bus.bdev) {
- bdev = sc->sc_ohci.sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/arm/at91/at91_ohci_fdt.c b/sys/arm/at91/at91_ohci_fdt.c
index de3d357..51d9509 100644
--- a/sys/arm/at91/at91_ohci_fdt.c
+++ b/sys/arm/at91/at91_ohci_fdt.c
@@ -171,14 +171,8 @@ static int
ohci_at91_fdt_detach(device_t dev)
{
struct at91_ohci_softc *sc = device_get_softc(dev);
- device_t bdev;
int err;
- if (sc->sc_ohci.sc_bus.bdev) {
- bdev = sc->sc_ohci.sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/arm/at91/at91_pit.c b/sys/arm/at91/at91_pit.c
index d58129f..7f7890b 100644
--- a/sys/arm/at91/at91_pit.c
+++ b/sys/arm/at91/at91_pit.c
@@ -42,7 +42,6 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/frame.h>
#include <machine/intr.h>
#include <machine/resource.h>
diff --git a/sys/arm/at91/at91_pmc.c b/sys/arm/at91/at91_pmc.c
index 88810a6..3784bad 100644
--- a/sys/arm/at91/at91_pmc.c
+++ b/sys/arm/at91/at91_pmc.c
@@ -41,8 +41,6 @@ __FBSDID("$FreeBSD$");
#include <sys/timetc.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <arm/at91/at91reg.h>
diff --git a/sys/arm/at91/at91_st.c b/sys/arm/at91/at91_st.c
index a18be2e..07ee24d 100644
--- a/sys/arm/at91/at91_st.c
+++ b/sys/arm/at91/at91_st.c
@@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/frame.h>
#include <machine/intr.h>
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_dma.c b/sys/arm/broadcom/bcm2835/bcm2835_dma.c
index 1a756c8..3b6c032 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_dma.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_dma.c
@@ -48,8 +48,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include "bcm2835_dma.h"
#include "bcm2835_vcbus.h"
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_spi.c b/sys/arm/broadcom/bcm2835/bcm2835_spi.c
index 9078efd..b30fac7 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_spi.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_spi.c
@@ -40,8 +40,6 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_wdog.c b/sys/arm/broadcom/bcm2835/bcm2835_wdog.c
index 21a376a..39b16e3 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_wdog.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_wdog.c
@@ -40,7 +40,6 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus_subr.h>
#include <machine/bus.h>
-#include <machine/cpufunc.h>
#include <machine/machdep.h>
#include <arm/broadcom/bcm2835/bcm2835_wdog.h>
diff --git a/sys/arm/cavium/cns11xx/ehci_ebus.c b/sys/arm/cavium/cns11xx/ehci_ebus.c
index 18f6a14..51c4f2c 100644
--- a/sys/arm/cavium/cns11xx/ehci_ebus.c
+++ b/sys/arm/cavium/cns11xx/ehci_ebus.c
@@ -184,14 +184,8 @@ static int
ehci_ebus_detach(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
- device_t bdev;
int err;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(self);
diff --git a/sys/arm/cavium/cns11xx/ohci_ec.c b/sys/arm/cavium/cns11xx/ohci_ec.c
index 9c49b1e..78183ea 100644
--- a/sys/arm/cavium/cns11xx/ohci_ec.c
+++ b/sys/arm/cavium/cns11xx/ohci_ec.c
@@ -177,14 +177,8 @@ static int
ohci_ec_detach(device_t dev)
{
struct ec_ohci_softc *sc = device_get_softc(dev);
- device_t bdev;
int err;
- if (sc->sc_ohci.sc_bus.bdev) {
- bdev = sc->sc_ohci.sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/arm/conf/A10 b/sys/arm/conf/ALLWINNER_UP
index 1f8b470..68c20a6 100644
--- a/sys/arm/conf/A10
+++ b/sys/arm/conf/ALLWINNER_UP
@@ -1,5 +1,5 @@
#
-# A10 -- Custom configuration for the AllWinner A10 SoC
+# ALLWINNER_UP -- Custom configuration for the AllWinner Uniprocessor SoC
#
# For more information on this file, please read the config(5) manual page,
# and/or the handbook section on Kernel Configuration Files:
@@ -18,17 +18,16 @@
#
# $FreeBSD$
-ident A10
+ident ALLWINNER_UP
include "std.armv6"
-include "../allwinner/std.a10"
+include "../allwinner/std.allwinner_up"
options INTRNG
options SOC_ALLWINNER_A10
options SOC_ALLWINNER_A13
-options HZ=100
options SCHED_4BSD # 4BSD scheduler
options PLATFORM
options MULTIDELAY
diff --git a/sys/arm/conf/CUBIEBOARD b/sys/arm/conf/CUBIEBOARD
deleted file mode 100644
index 5ee432e..0000000
--- a/sys/arm/conf/CUBIEBOARD
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# CUBIEBOARD -- Custom configuration for the CUBIEBOARD ARM development
-# platform, check out http://www.cubieboard.org
-#
-# For more information on this file, please read the config(5) manual page,
-# and/or the handbook section on Kernel Configuration Files:
-#
-# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
-#
-# The handbook is also available locally in /usr/share/doc/handbook
-# if you've installed the doc distribution, otherwise always see the
-# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
-# latest information.
-#
-# An exhaustive list of options and more detailed explanations of the
-# device lines is also present in the ../../conf/NOTES and NOTES files.
-# If you are in doubt as to the purpose or necessity of a line, check first
-# in NOTES.
-#
-# $FreeBSD$
-
-#NO_UNIVERSE
-
-include "A10"
-ident CUBIEBOARD
-
-# Boot device is 2nd slice on MMC/SD card
-options ROOTDEVNAME=\"ufs:/dev/da0s2\"
-
-# Flattened Device Tree
-options FDT
-options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=cubieboard.dts
diff --git a/sys/arm/freescale/imx/imx51_ipuv3.c b/sys/arm/freescale/imx/imx51_ipuv3.c
index 3da87a9..a96b185 100644
--- a/sys/arm/freescale/imx/imx51_ipuv3.c
+++ b/sys/arm/freescale/imx/imx51_ipuv3.c
@@ -57,8 +57,6 @@ __FBSDID("$FreeBSD$");
#include <vm/pmap.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/fdt.h>
#include <machine/resource.h>
#include <machine/intr.h>
diff --git a/sys/arm/freescale/imx/imx51_ipuv3_fbd.c b/sys/arm/freescale/imx/imx51_ipuv3_fbd.c
index 3852754..800244a 100644
--- a/sys/arm/freescale/imx/imx51_ipuv3_fbd.c
+++ b/sys/arm/freescale/imx/imx51_ipuv3_fbd.c
@@ -55,8 +55,6 @@ __FBSDID("$FreeBSD$");
#include <sys/kdb.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/frame.h>
#include <machine/intr.h>
diff --git a/sys/arm/include/atomic-v6.h b/sys/arm/include/atomic-v6.h
index 06cb507..507a1d081 100644
--- a/sys/arm/include/atomic-v6.h
+++ b/sys/arm/include/atomic-v6.h
@@ -652,7 +652,7 @@ atomic_swap_32(volatile uint32_t *p, uint32_t v)
" teq %[exf], #0 \n"
" it ne \n"
" bne 1b \n"
- : [ret] "=r" (ret),
+ : [ret] "=&r" (ret),
[exf] "=&r" (exflag)
: [val] "r" (v),
[ptr] "r" (p)
@@ -660,6 +660,26 @@ atomic_swap_32(volatile uint32_t *p, uint32_t v)
return (ret);
}
+static __inline uint64_t
+atomic_swap_64(volatile uint64_t *p, uint64_t v)
+{
+ uint64_t ret;
+ uint32_t exflag;
+
+ __asm __volatile(
+ "1: ldrexd %Q[ret], %R[ret], [%[ptr]] \n"
+ " strexd %[exf], %Q[val], %R[val], [%[ptr]] \n"
+ " teq %[exf], #0 \n"
+ " it ne \n"
+ " bne 1b \n"
+ : [ret] "=&r" (ret),
+ [exf] "=&r" (exflag)
+ : [val] "r" (v),
+ [ptr] "r" (p)
+ : "cc", "memory");
+ return (ret);
+}
+
#undef ATOMIC_ACQ_REL
#undef ATOMIC_ACQ_REL_LONG
diff --git a/sys/arm/lpc/lpc_fb.c b/sys/arm/lpc/lpc_fb.c
index 5385d30..b2eab8b 100644
--- a/sys/arm/lpc/lpc_fb.c
+++ b/sys/arm/lpc/lpc_fb.c
@@ -49,8 +49,6 @@ __FBSDID("$FreeBSD$");
#include <sys/kdb.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
diff --git a/sys/arm/lpc/lpc_gpio.c b/sys/arm/lpc/lpc_gpio.c
index 88f37b6..798469d 100644
--- a/sys/arm/lpc/lpc_gpio.c
+++ b/sys/arm/lpc/lpc_gpio.c
@@ -73,8 +73,6 @@ __FBSDID("$FreeBSD$");
#include <sys/gpio.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <machine/fdt.h>
diff --git a/sys/arm/lpc/lpc_mmc.c b/sys/arm/lpc/lpc_mmc.c
index 6c33215..c337d72 100644
--- a/sys/arm/lpc/lpc_mmc.c
+++ b/sys/arm/lpc/lpc_mmc.c
@@ -49,8 +49,6 @@ __FBSDID("$FreeBSD$");
#include <sys/kdb.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
diff --git a/sys/arm/lpc/lpc_spi.c b/sys/arm/lpc/lpc_spi.c
index 5bf8f7d..a3986da 100644
--- a/sys/arm/lpc/lpc_spi.c
+++ b/sys/arm/lpc/lpc_spi.c
@@ -47,8 +47,6 @@ __FBSDID("$FreeBSD$");
#include <sys/watchdog.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
diff --git a/sys/arm/mv/mpic.c b/sys/arm/mv/mpic.c
index 9a9785ce..3fc06d7 100644
--- a/sys/arm/mv/mpic.c
+++ b/sys/arm/mv/mpic.c
@@ -50,7 +50,6 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/intr.h>
-#include <machine/cpufunc.h>
#include <machine/smp.h>
#include <arm/mv/mvvar.h>
diff --git a/sys/arm/nvidia/as3722.c b/sys/arm/nvidia/as3722.c
index 3a03322..21dae2d 100644
--- a/sys/arm/nvidia/as3722.c
+++ b/sys/arm/nvidia/as3722.c
@@ -405,7 +405,7 @@ static device_method_t as3722_methods[] = {
};
static devclass_t as3722_devclass;
-DEFINE_CLASS_0(gpio, as3722_driver, as3722_methods,
+static DEFINE_CLASS_0(gpio, as3722_driver, as3722_methods,
sizeof(struct as3722_softc));
EARLY_DRIVER_MODULE(as3722, iicbus, as3722_driver, as3722_devclass,
- 0, 0, 74);
+ NULL, NULL, 74);
diff --git a/sys/arm/nvidia/as3722_regulators.c b/sys/arm/nvidia/as3722_regulators.c
index 314428f..8ea00d9 100644
--- a/sys/arm/nvidia/as3722_regulators.c
+++ b/sys/arm/nvidia/as3722_regulators.c
@@ -71,13 +71,6 @@ enum as3722_reg_id {
AS3722_REG_ID_LDO11,
};
-struct regulator_range {
- u_int min_uvolt;
- u_int step_uvolt;
- u_int min_sel;
- u_int max_sel;
-};
-
/* Regulator HW definition. */
struct reg_def {
@@ -107,40 +100,32 @@ struct as3722_reg_sc {
int enable_usec;
};
-#define RANGE_INIT(_min_sel, _max_sel, _min_uvolt, _step_uvolt) \
-{ \
- .min_sel = _min_sel, \
- .max_sel = _max_sel, \
- .min_uvolt = _min_uvolt, \
- .step_uvolt = _step_uvolt, \
-}
-
static struct regulator_range as3722_sd016_ranges[] = {
- RANGE_INIT(0x00, 0x00, 0, 0),
- RANGE_INIT(0x01, 0x5A, 610000, 10000),
+ REG_RANGE_INIT(0x00, 0x00, 0, 0),
+ REG_RANGE_INIT(0x01, 0x5A, 610000, 10000),
};
static struct regulator_range as3722_sd0_lv_ranges[] = {
- RANGE_INIT(0x00, 0x00, 0, 0),
- RANGE_INIT(0x01, 0x6E, 410000, 10000),
+ REG_RANGE_INIT(0x00, 0x00, 0, 0),
+ REG_RANGE_INIT(0x01, 0x6E, 410000, 10000),
};
static struct regulator_range as3722_sd_ranges[] = {
- RANGE_INIT(0x00, 0x00, 0, 0),
- RANGE_INIT(0x01, 0x40, 612500, 12500),
- RANGE_INIT(0x41, 0x70, 1425000, 25000),
- RANGE_INIT(0x71, 0x7F, 2650000, 50000),
+ REG_RANGE_INIT(0x00, 0x00, 0, 0),
+ REG_RANGE_INIT(0x01, 0x40, 612500, 12500),
+ REG_RANGE_INIT(0x41, 0x70, 1425000, 25000),
+ REG_RANGE_INIT(0x71, 0x7F, 2650000, 50000),
};
static struct regulator_range as3722_ldo3_ranges[] = {
- RANGE_INIT(0x00, 0x00, 0, 0),
- RANGE_INIT(0x01, 0x2D, 620000, 20000),
+ REG_RANGE_INIT(0x00, 0x00, 0, 0),
+ REG_RANGE_INIT(0x01, 0x2D, 620000, 20000),
};
static struct regulator_range as3722_ldo_ranges[] = {
- RANGE_INIT(0x00, 0x00, 0, 0),
- RANGE_INIT(0x01, 0x24, 825000, 25000),
- RANGE_INIT(0x40, 0x7F, 1725000, 25000),
+ REG_RANGE_INIT(0x00, 0x00, 0, 0),
+ REG_RANGE_INIT(0x01, 0x24, 825000, 25000),
+ REG_RANGE_INIT(0x40, 0x7F, 1725000, 25000),
};
static struct reg_def as3722s_def[] = {
@@ -402,87 +387,6 @@ DEFINE_CLASS_1(as3722_regnode, as3722_regnode_class, as3722_regnode_methods,
sizeof(struct as3722_reg_sc), regnode_class);
static int
-regulator_range_sel_to_volt(struct as3722_reg_sc *sc, uint8_t sel, int *volt)
-{
- struct regulator_range *range;
- struct reg_def *def;
- int i;
-
- def = sc->def;
- if (def->nranges == 0)
- panic("Voltage regulator have zero ranges\n");
-
- for (i = 0; i < def->nranges ; i++) {
- range = def->ranges + i;
-
- if (!(sel >= range->min_sel &&
- sel <= range->max_sel))
- continue;
-
- sel -= range->min_sel;
-
- *volt = range->min_uvolt + sel * range->step_uvolt;
- return (0);
- }
-
- return (ERANGE);
-}
-
-static int
-regulator_range_volt_to_sel(struct as3722_reg_sc *sc, int min_uvolt,
- int max_uvolt, uint8_t *out_sel)
-{
- struct regulator_range *range;
- struct reg_def *def;
- uint8_t sel;
- int uvolt;
- int rv, i;
-
- def = sc->def;
- if (def->nranges == 0)
- panic("Voltage regulator have zero ranges\n");
-
- for (i = 0; i < def->nranges; i++) {
- range = def->ranges + i;
- uvolt = range->min_uvolt +
- (range->max_sel - range->min_sel) * range->step_uvolt;
-
- if ((min_uvolt > uvolt) ||
- (max_uvolt < range->min_uvolt))
- continue;
-
- if (min_uvolt <= range->min_uvolt)
- min_uvolt = range->min_uvolt;
-
- /* If step is zero then range is fixed voltage range. */
- if (range->step_uvolt == 0)
- sel = 0;
- else
- sel = DIV_ROUND_UP(min_uvolt - range->min_uvolt,
- range->step_uvolt);
-
-
- sel += range->min_sel;
-
- break;
- }
-
- if (i >= def->nranges)
- return (ERANGE);
-
- /* Verify new settings. */
- rv = regulator_range_sel_to_volt(sc, sel, &uvolt);
- if (rv != 0)
- return (rv);
- if ((uvolt < min_uvolt) || (uvolt > max_uvolt))
- return (ERANGE);
-
- *out_sel = sel;
- return (0);
-}
-
-
-static int
as3722_read_sel(struct as3722_reg_sc *sc, uint8_t *sel)
{
int rv;
@@ -783,7 +687,8 @@ as3722_regnode_set_volt(struct regnode *regnode, int min_uvolt, int max_uvolt,
sc = regnode_get_softc(regnode);
*udelay = 0;
- rv = regulator_range_volt_to_sel(sc, min_uvolt, max_uvolt, &sel);
+ rv = regulator_range_volt_to_sel8(sc->def->ranges, sc->def->nranges,
+ min_uvolt, max_uvolt, &sel);
if (rv != 0)
return (rv);
rv = as3722_write_sel(sc, sel);
@@ -806,6 +711,7 @@ as3722_regnode_get_volt(struct regnode *regnode, int *uvolt)
/* LDO6 have bypass. */
if (sc->def->id == AS3722_REG_ID_LDO6 && sel == AS3722_LDO6_SEL_BYPASS)
return (ENOENT);
- rv = regulator_range_sel_to_volt(sc, sel, uvolt);
+ rv = regulator_range_sel8_to_volt(sc->def->ranges, sc->def->nranges,
+ sel, uvolt);
return (rv);
}
diff --git a/sys/arm/nvidia/tegra124/tegra124_car.c b/sys/arm/nvidia/tegra124/tegra124_car.c
index c0e93c7..4a9549f 100644
--- a/sys/arm/nvidia/tegra124/tegra124_car.c
+++ b/sys/arm/nvidia/tegra124/tegra124_car.c
@@ -602,12 +602,7 @@ static device_method_t tegra124_car_methods[] = {
};
static devclass_t tegra124_car_devclass;
-
-static driver_t tegra124_car_driver = {
- "tegra124_car",
- tegra124_car_methods,
- sizeof(struct tegra124_car_softc),
-};
-
+static DEFINE_CLASS_0(car, tegra124_car_driver, tegra124_car_methods,
+ sizeof(struct tegra124_car_softc));
EARLY_DRIVER_MODULE(tegra124_car, simplebus, tegra124_car_driver,
- tegra124_car_devclass, 0, 0, BUS_PASS_TIMER);
+ tegra124_car_devclass, NULL, NULL, BUS_PASS_TIMER);
diff --git a/sys/arm/nvidia/tegra124/tegra124_coretemp.c b/sys/arm/nvidia/tegra124/tegra124_coretemp.c
index 1426a4e..0becdb0 100644
--- a/sys/arm/nvidia/tegra124/tegra124_coretemp.c
+++ b/sys/arm/nvidia/tegra124/tegra124_coretemp.c
@@ -178,7 +178,11 @@ tegra124_coretemp_ofw_parse(struct tegra124_coretemp_softc *sc)
static void
tegra124_coretemp_identify(driver_t *driver, device_t parent)
{
+ phandle_t root;
+ root = OF_finddevice("/");
+ if (!ofw_bus_node_is_compatible(root, "nvidia,tegra124"))
+ return;
if (device_find_child(parent, "tegra124_coretemp", -1) != NULL)
return;
if (BUS_ADD_CHILD(parent, 0, "tegra124_coretemp", -1) == NULL)
@@ -189,7 +193,7 @@ static int
tegra124_coretemp_probe(device_t dev)
{
- device_set_desc(dev, "CPU Frequency Control");
+ device_set_desc(dev, "CPU Thermal Sensor");
return (0);
}
@@ -250,7 +254,6 @@ tegra124_coretemp_detach(device_t dev)
return (0);
}
-
static device_method_t tegra124_coretemp_methods[] = {
/* Device interface */
DEVMETHOD(device_identify, tegra124_coretemp_identify),
@@ -263,11 +266,7 @@ static device_method_t tegra124_coretemp_methods[] = {
};
static devclass_t tegra124_coretemp_devclass;
-static driver_t tegra124_coretemp_driver = {
- "tegra124_coretemp",
- tegra124_coretemp_methods,
- sizeof(struct tegra124_coretemp_softc),
-};
-
+static DEFINE_CLASS_0(tegra124_coretemp, tegra124_coretemp_driver,
+ tegra124_coretemp_methods, sizeof(struct tegra124_coretemp_softc));
DRIVER_MODULE(tegra124_coretemp, cpu, tegra124_coretemp_driver,
- tegra124_coretemp_devclass, 0, 0);
+ tegra124_coretemp_devclass, NULL, NULL);
diff --git a/sys/arm/nvidia/tegra124/tegra124_cpufreq.c b/sys/arm/nvidia/tegra124/tegra124_cpufreq.c
index 0f14b58..4de8603 100644
--- a/sys/arm/nvidia/tegra124/tegra124_cpufreq.c
+++ b/sys/arm/nvidia/tegra124/tegra124_cpufreq.c
@@ -141,7 +141,7 @@ static struct speedo_entry tegra124_speedo_pllx_tbl[] =
static struct cpu_volt_def tegra124_cpu_volt_pllx_def =
{
- .min_uvolt = 900000, /* 0.9 V */
+ .min_uvolt = 1000000, /* XXX 0.9 V doesn't work on all boards */
.max_uvolt = 1260000, /* 1.26 */
.step_uvolt = 10000, /* 10 mV */
.speedo_scale = 100,
@@ -172,7 +172,6 @@ static uint64_t cpu_freq_tbl[] = {
2116000000ULL,
2218000000ULL,
2320000000ULL,
- 2320000000ULL,
2422000000ULL,
2524000000ULL,
};
@@ -432,36 +431,36 @@ get_fdt_resources(struct tegra124_cpufreq_softc *sc, phandle_t node)
device_t parent_dev;
parent_dev = device_get_parent(sc->dev);
- rv = regulator_get_by_ofw_property(parent_dev, "vdd-cpu-supply",
+ rv = regulator_get_by_ofw_property(parent_dev, 0, "vdd-cpu-supply",
&sc->supply_vdd_cpu);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'vdd-cpu' regulator\n");
return (rv);
}
- rv = clk_get_by_ofw_name(parent_dev, "cpu_g", &sc->clk_cpu_g);
+ rv = clk_get_by_ofw_name(parent_dev, 0, "cpu_g", &sc->clk_cpu_g);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'cpu_g' clock: %d\n", rv);
return (ENXIO);
}
- rv = clk_get_by_ofw_name(parent_dev, "cpu_lp", &sc->clk_cpu_lp);
+ rv = clk_get_by_ofw_name(parent_dev, 0, "cpu_lp", &sc->clk_cpu_lp);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'cpu_lp' clock\n");
return (ENXIO);
}
- rv = clk_get_by_ofw_name(parent_dev, "pll_x", &sc->clk_pll_x);
+ rv = clk_get_by_ofw_name(parent_dev, 0, "pll_x", &sc->clk_pll_x);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'pll_x' clock\n");
return (ENXIO);
}
- rv = clk_get_by_ofw_name(parent_dev, "pll_p", &sc->clk_pll_p);
+ rv = clk_get_by_ofw_name(parent_dev, 0, "pll_p", &sc->clk_pll_p);
if (rv != 0) {
device_printf(parent_dev, "Cannot get 'pll_p' clock\n");
return (ENXIO);
}
- rv = clk_get_by_ofw_name(parent_dev, "dfll", &sc->clk_dfll);
+ rv = clk_get_by_ofw_name(parent_dev, 0, "dfll", &sc->clk_dfll);
if (rv != 0) {
/* XXX DPLL is not implemented yet */
/*
@@ -475,7 +474,14 @@ get_fdt_resources(struct tegra124_cpufreq_softc *sc, phandle_t node)
static void
tegra124_cpufreq_identify(driver_t *driver, device_t parent)
{
+ phandle_t root;
+
+ root = OF_finddevice("/");
+ if (!ofw_bus_node_is_compatible(root, "nvidia,tegra124"))
+ return;
+ if (device_get_unit(parent) != 0)
+ return;
if (device_find_child(parent, "tegra124_cpufreq", -1) != NULL)
return;
if (BUS_ADD_CHILD(parent, 0, "tegra124_cpufreq", -1) == NULL)
@@ -486,8 +492,6 @@ static int
tegra124_cpufreq_probe(device_t dev)
{
- if (device_get_unit(dev) != 0)
- return (ENXIO);
device_set_desc(dev, "CPU Frequency Control");
return (0);
@@ -588,11 +592,7 @@ static device_method_t tegra124_cpufreq_methods[] = {
};
static devclass_t tegra124_cpufreq_devclass;
-static driver_t tegra124_cpufreq_driver = {
- "tegra124_cpufreq",
- tegra124_cpufreq_methods,
- sizeof(struct tegra124_cpufreq_softc),
-};
-
+static DEFINE_CLASS_0(tegra124_cpufreq, tegra124_cpufreq_driver,
+ tegra124_cpufreq_methods, sizeof(struct tegra124_cpufreq_softc));
DRIVER_MODULE(tegra124_cpufreq, cpu, tegra124_cpufreq_driver,
- tegra124_cpufreq_devclass, 0, 0);
+ tegra124_cpufreq_devclass, NULL, NULL);
diff --git a/sys/arm/nvidia/tegra124/tegra124_machdep.c b/sys/arm/nvidia/tegra124/tegra124_machdep.c
index 70c31da..1233a42 100644
--- a/sys/arm/nvidia/tegra124/tegra124_machdep.c
+++ b/sys/arm/nvidia/tegra124/tegra124_machdep.c
@@ -139,18 +139,18 @@ cpu_reset(void)
/*
* Early putc routine for EARLY_PRINTF support. To use, add to kernel config:
- * option SOCDEV_PA=0x02000000
- * option SOCDEV_VA=0x02000000
+ * option SOCDEV_PA=0x70000000
+ * option SOCDEV_VA=0x70000000
* option EARLY_PRINTF
*/
-#if 0
+#ifdef EARLY_PRINTF
static void
tegra124_early_putc(int c)
{
- volatile uint32_t * UART_STAT_REG = (uint32_t *)0x02020098;
- volatile uint32_t * UART_TX_REG = (uint32_t *)0x02020040;
- const uint32_t UART_TXRDY = (1 << 3);
+ volatile uint32_t * UART_STAT_REG = (uint32_t *)(0x70006314);
+ volatile uint32_t * UART_TX_REG = (uint32_t *)(0x70006300);
+ const uint32_t UART_TXRDY = (1 << 6);
while ((*UART_STAT_REG & UART_TXRDY) == 0)
continue;
*UART_TX_REG = c;
diff --git a/sys/arm/nvidia/tegra124/tegra124_pmc.c b/sys/arm/nvidia/tegra124/tegra124_pmc.c
index 7ff7307..04ff73c 100644
--- a/sys/arm/nvidia/tegra124/tegra124_pmc.c
+++ b/sys/arm/nvidia/tegra124/tegra124_pmc.c
@@ -494,7 +494,7 @@ tegra124_pmc_attach(device_t dev)
return (rv);
}
- rv = clk_get_by_ofw_name(sc->dev, "pclk", &sc->clk);
+ rv = clk_get_by_ofw_name(sc->dev, 0, "pclk", &sc->clk);
if (rv != 0) {
device_printf(sc->dev, "Cannot get \"pclk\" clock\n");
return (ENXIO);
@@ -555,12 +555,8 @@ static device_method_t tegra124_pmc_methods[] = {
DEVMETHOD_END
};
-static driver_t tegra124_pmc_driver = {
- "tegra124_pmc",
- tegra124_pmc_methods,
- sizeof(struct tegra124_pmc_softc),
-};
-
static devclass_t tegra124_pmc_devclass;
+static DEFINE_CLASS_0(pmc, tegra124_pmc_driver, tegra124_pmc_methods,
+ sizeof(struct tegra124_pmc_softc));
EARLY_DRIVER_MODULE(tegra124_pmc, simplebus, tegra124_pmc_driver,
- tegra124_pmc_devclass, 0, 0, 70);
+ tegra124_pmc_devclass, NULL, NULL, 70);
diff --git a/sys/arm/nvidia/tegra124/tegra124_xusbpadctl.c b/sys/arm/nvidia/tegra124/tegra124_xusbpadctl.c
index 9d8b846..d61f3cb 100644
--- a/sys/arm/nvidia/tegra124/tegra124_xusbpadctl.c
+++ b/sys/arm/nvidia/tegra124/tegra124_xusbpadctl.c
@@ -556,7 +556,7 @@ xusbpadctl_attach(device_t dev)
}
node = ofw_bus_get_node(dev);
- rv = hwreset_get_by_ofw_name(dev, "padctl", &sc->rst);
+ rv = hwreset_get_by_ofw_name(dev, 0, "padctl", &sc->rst);
if (rv != 0) {
device_printf(dev, "Cannot get 'padctl' reset: %d\n", rv);
return (rv);
@@ -575,7 +575,6 @@ xusbpadctl_attach(device_t dev)
return (0);
}
-
static device_method_t tegra_xusbpadctl_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, xusbpadctl_probe),
@@ -591,13 +590,8 @@ static device_method_t tegra_xusbpadctl_methods[] = {
DEVMETHOD_END
};
-static driver_t tegra_xusbpadctl_driver = {
- "tegra_xusbpadctl",
- tegra_xusbpadctl_methods,
- sizeof(struct xusbpadctl_softc),
-};
-
static devclass_t tegra_xusbpadctl_devclass;
-
+static DEFINE_CLASS_0(xusbpadctl, tegra_xusbpadctl_driver,
+ tegra_xusbpadctl_methods, sizeof(struct xusbpadctl_softc));
EARLY_DRIVER_MODULE(tegra_xusbpadctl, simplebus, tegra_xusbpadctl_driver,
- tegra_xusbpadctl_devclass, 0, 0, 73);
+ tegra_xusbpadctl_devclass, NULL, NULL, 73);
diff --git a/sys/arm/nvidia/tegra_abpmisc.c b/sys/arm/nvidia/tegra_abpmisc.c
index 83ee44f..56d91b7 100644
--- a/sys/arm/nvidia/tegra_abpmisc.c
+++ b/sys/arm/nvidia/tegra_abpmisc.c
@@ -187,8 +187,8 @@ static device_method_t tegra_abpmisc_methods[] = {
DEVMETHOD_END
};
-DEFINE_CLASS_0(tegra_abpmisc, tegra_abpmisc_driver, tegra_abpmisc_methods,
- sizeof(struct tegra_abpmisc_softc));
static devclass_t tegra_abpmisc_devclass;
+static DEFINE_CLASS_0(abpmisc, tegra_abpmisc_driver, tegra_abpmisc_methods,
+ sizeof(struct tegra_abpmisc_softc));
EARLY_DRIVER_MODULE(tegra_abpmisc, simplebus, tegra_abpmisc_driver,
- tegra_abpmisc_devclass, 0, 0, BUS_PASS_TIMER);
+ tegra_abpmisc_devclass, NULL, NULL, BUS_PASS_TIMER);
diff --git a/sys/arm/nvidia/tegra_ahci.c b/sys/arm/nvidia/tegra_ahci.c
index 4afba17..b717d59 100644
--- a/sys/arm/nvidia/tegra_ahci.c
+++ b/sys/arm/nvidia/tegra_ahci.c
@@ -206,77 +206,77 @@ get_fdt_resources(struct tegra_ahci_sc *sc, phandle_t node)
int rv;
- rv = regulator_get_by_ofw_property(sc->dev, "hvdd-supply",
+ rv = regulator_get_by_ofw_property(sc->dev, 0, "hvdd-supply",
&sc->supply_hvdd );
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'hvdd' regulator\n");
return (ENXIO);
}
- rv = regulator_get_by_ofw_property(sc->dev, "vddio-supply",
+ rv = regulator_get_by_ofw_property(sc->dev, 0, "vddio-supply",
&sc->supply_vddio);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'vddio' regulator\n");
return (ENXIO);
}
- rv = regulator_get_by_ofw_property(sc->dev, "avdd-supply",
+ rv = regulator_get_by_ofw_property(sc->dev, 0, "avdd-supply",
&sc->supply_avdd);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'avdd' regulator\n");
return (ENXIO);
}
- rv = regulator_get_by_ofw_property(sc->dev, "target-5v-supply",
+ rv = regulator_get_by_ofw_property(sc->dev, 0, "target-5v-supply",
&sc->supply_target_5v);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'target-5v' regulator\n");
return (ENXIO);
}
- rv = regulator_get_by_ofw_property(sc->dev, "target-12v-supply",
+ rv = regulator_get_by_ofw_property(sc->dev, 0, "target-12v-supply",
&sc->supply_target_12v);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'target-12v' regulator\n");
return (ENXIO);
}
- rv = hwreset_get_by_ofw_name(sc->dev, "sata", &sc->hwreset_sata );
+ rv = hwreset_get_by_ofw_name(sc->dev, 0, "sata", &sc->hwreset_sata );
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'sata' reset\n");
return (ENXIO);
}
- rv = hwreset_get_by_ofw_name(sc->dev, "sata-oob",
+ rv = hwreset_get_by_ofw_name(sc->dev, 0, "sata-oob",
&sc->hwreset_sata_oob);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'sata oob' reset\n");
return (ENXIO);
}
- rv = hwreset_get_by_ofw_name(sc->dev, "sata-cold",
+ rv = hwreset_get_by_ofw_name(sc->dev, 0, "sata-cold",
&sc->hwreset_sata_cold);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'sata cold' reset\n");
return (ENXIO);
}
- rv = phy_get_by_ofw_name(sc->dev, "sata-phy", &sc->phy);
+ rv = phy_get_by_ofw_name(sc->dev, 0, "sata-phy", &sc->phy);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'sata' phy\n");
return (ENXIO);
}
- rv = clk_get_by_ofw_name(sc->dev, "sata", &sc->clk_sata);
+ rv = clk_get_by_ofw_name(sc->dev, 0, "sata", &sc->clk_sata);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'sata' clock\n");
return (ENXIO);
}
- rv = clk_get_by_ofw_name(sc->dev, "sata-oob", &sc->clk_sata_oob);
+ rv = clk_get_by_ofw_name(sc->dev, 0, "sata-oob", &sc->clk_sata_oob);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'sata oob' clock\n");
return (ENXIO);
}
- rv = clk_get_by_ofw_name(sc->dev, "cml1", &sc->clk_cml);
+ rv = clk_get_by_ofw_name(sc->dev, 0, "cml1", &sc->clk_cml);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'cml1' clock\n");
return (ENXIO);
}
- rv = clk_get_by_ofw_name(sc->dev, "pll_e", &sc->clk_pll_e);
+ rv = clk_get_by_ofw_name(sc->dev, 0, "pll_e", &sc->clk_pll_e);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'pll_e' clock\n");
return (ENXIO);
@@ -602,8 +602,7 @@ tegra_ahci_resume(device_t dev)
return (bus_generic_resume(dev));
}
-devclass_t genahci_devclass;
-static device_method_t genahci_methods[] = {
+static device_method_t tegra_ahci_methods[] = {
DEVMETHOD(device_probe, tegra_ahci_probe),
DEVMETHOD(device_attach, tegra_ahci_attach),
DEVMETHOD(device_detach, tegra_ahci_detach),
@@ -619,9 +618,9 @@ static device_method_t genahci_methods[] = {
DEVMETHOD_END
};
-static driver_t genahci_driver = {
- "ahci",
- genahci_methods,
- sizeof(struct tegra_ahci_sc)
-};
-DRIVER_MODULE(genahci, simplebus, genahci_driver, genahci_devclass, NULL, NULL);
+
+static devclass_t tegra_ahci_devclass;
+static DEFINE_CLASS_0(ahci, tegra_ahci_driver, tegra_ahci_methods,
+ sizeof(struct tegra_ahci_sc));
+DRIVER_MODULE(tegra_ahci, simplebus, tegra_ahci_driver, tegra_ahci_devclass,
+ NULL, NULL);
diff --git a/sys/arm/nvidia/tegra_efuse.c b/sys/arm/nvidia/tegra_efuse.c
index ae3f9ef..34e0da0 100644
--- a/sys/arm/nvidia/tegra_efuse.c
+++ b/sys/arm/nvidia/tegra_efuse.c
@@ -291,7 +291,7 @@ tegra_efuse_attach(device_t dev)
}
/* OFW resources. */
- rv = clk_get_by_ofw_name(dev, "fuse", &sc->clk);
+ rv = clk_get_by_ofw_name(dev, 0, "fuse", &sc->clk);
if (rv != 0) {
device_printf(dev, "Cannot get fuse clock: %d\n", rv);
goto fail;
@@ -301,7 +301,7 @@ tegra_efuse_attach(device_t dev)
device_printf(dev, "Cannot enable clock: %d\n", rv);
goto fail;
}
- rv = hwreset_get_by_ofw_name(sc->dev, "fuse", &sc->reset);
+ rv = hwreset_get_by_ofw_name(sc->dev, 0, "fuse", &sc->reset);
if (rv != 0) {
device_printf(dev, "Cannot get fuse reset\n");
goto fail;
@@ -357,12 +357,11 @@ static device_method_t tegra_efuse_methods[] = {
DEVMETHOD(device_attach, tegra_efuse_attach),
DEVMETHOD(device_detach, tegra_efuse_detach),
-
DEVMETHOD_END
};
-DEFINE_CLASS_0(tegra_efuse, tegra_efuse_driver, tegra_efuse_methods,
- sizeof(struct tegra_efuse_softc));
static devclass_t tegra_efuse_devclass;
+static DEFINE_CLASS_0(efuse, tegra_efuse_driver, tegra_efuse_methods,
+ sizeof(struct tegra_efuse_softc));
EARLY_DRIVER_MODULE(tegra_efuse, simplebus, tegra_efuse_driver,
- tegra_efuse_devclass, 0, 0, BUS_PASS_TIMER);
+ tegra_efuse_devclass, NULL, NULL, BUS_PASS_TIMER);
diff --git a/sys/arm/nvidia/tegra_ehci.c b/sys/arm/nvidia/tegra_ehci.c
index 1834b33..7a041d5 100644
--- a/sys/arm/nvidia/tegra_ehci.c
+++ b/sys/arm/nvidia/tegra_ehci.c
@@ -174,21 +174,21 @@ tegra_ehci_attach(device_t dev)
goto out;
}
- rv = hwreset_get_by_ofw_name(dev, "usb", &sc->reset);
+ rv = hwreset_get_by_ofw_name(dev, 0, "usb", &sc->reset);
if (rv != 0) {
device_printf(dev, "Cannot get reset\n");
rv = ENXIO;
goto out;
}
- rv = phy_get_by_ofw_property(sc->dev, "nvidia,phy", &sc->phy);
+ rv = phy_get_by_ofw_property(sc->dev, 0, "nvidia,phy", &sc->phy);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'nvidia,phy' phy\n");
rv = ENXIO;
goto out;
}
- rv = clk_get_by_ofw_index(sc->dev, 0, &sc->clk);
+ rv = clk_get_by_ofw_index(sc->dev, 0, 0, &sc->clk);
if (rv != 0) {
device_printf(dev, "Cannot get clock\n");
goto out;
@@ -311,12 +311,8 @@ static device_method_t ehci_methods[] = {
DEVMETHOD_END
};
-static driver_t ehci_driver = {
- "ehci",
- ehci_methods,
- sizeof(struct tegra_ehci_softc)
-};
-
static devclass_t ehci_devclass;
-DRIVER_MODULE(ehci, simplebus, ehci_driver, ehci_devclass, 0, 0);
-MODULE_DEPEND(ehci, usb, 1, 1, 1); \ No newline at end of file
+static DEFINE_CLASS_0(ehci, ehci_driver, ehci_methods,
+ sizeof(struct tegra_ehci_softc));
+DRIVER_MODULE(tegra_ehci, simplebus, ehci_driver, ehci_devclass, NULL, NULL);
+MODULE_DEPEND(tegra_ehci, usb, 1, 1, 1);
diff --git a/sys/arm/nvidia/tegra_gpio.c b/sys/arm/nvidia/tegra_gpio.c
index 0f88e64..d715a69 100644
--- a/sys/arm/nvidia/tegra_gpio.c
+++ b/sys/arm/nvidia/tegra_gpio.c
@@ -885,20 +885,8 @@ static device_method_t tegra_gpio_methods[] = {
DEVMETHOD_END
};
-static driver_t tegra_gpio_driver = {
- "tegra_gpio",
- tegra_gpio_methods,
- sizeof(struct tegra_gpio_softc),
-};
static devclass_t tegra_gpio_devclass;
-
+static DEFINE_CLASS_0(gpio, tegra_gpio_driver, tegra_gpio_methods,
+ sizeof(struct tegra_gpio_softc));
EARLY_DRIVER_MODULE(tegra_gpio, simplebus, tegra_gpio_driver,
- tegra_gpio_devclass, 0, 0, 70);
-
-extern devclass_t ofwgpiobus_devclass;
-extern driver_t ofw_gpiobus_driver;
-EARLY_DRIVER_MODULE(ofw_gpiobus, tegra_gpio, ofw_gpiobus_driver,
- ofwgpiobus_devclass, 0, 0, BUS_PASS_BUS);
-extern devclass_t gpioc_devclass;
-extern driver_t gpioc_driver;
-DRIVER_MODULE(gpioc, tegra_gpio, gpioc_driver, gpioc_devclass, 0, 0);
+ tegra_gpio_devclass, NULL, NULL, 70);
diff --git a/sys/arm/nvidia/tegra_i2c.c b/sys/arm/nvidia/tegra_i2c.c
index d50d34c..f88768e 100644
--- a/sys/arm/nvidia/tegra_i2c.c
+++ b/sys/arm/nvidia/tegra_i2c.c
@@ -666,12 +666,12 @@ tegra_i2c_attach(device_t dev)
}
/* FDT resources. */
- rv = clk_get_by_ofw_name(dev, "div-clk", &sc->clk);
+ rv = clk_get_by_ofw_name(dev, 0, "div-clk", &sc->clk);
if (rv != 0) {
device_printf(dev, "Cannot get i2c clock: %d\n", rv);
goto fail;
}
- rv = hwreset_get_by_ofw_name(sc->dev, "i2c", &sc->reset);
+ rv = hwreset_get_by_ofw_name(sc->dev, 0, "i2c", &sc->reset);
if (rv != 0) {
device_printf(sc->dev, "Cannot get i2c reset\n");
return (ENXIO);
@@ -797,12 +797,8 @@ static device_method_t tegra_i2c_methods[] = {
DEVMETHOD_END
};
-DEFINE_CLASS_0(iichb, tegra_i2c_driver, tegra_i2c_methods,
- sizeof(struct tegra_i2c_softc));
static devclass_t tegra_i2c_devclass;
+static DEFINE_CLASS_0(iichb, tegra_i2c_driver, tegra_i2c_methods,
+ sizeof(struct tegra_i2c_softc));
EARLY_DRIVER_MODULE(tegra_iic, simplebus, tegra_i2c_driver, tegra_i2c_devclass,
- 0, 0, 73);
-extern devclass_t ofwiicbus_devclass;
-extern driver_t ofw_iicbus_driver;
-EARLY_DRIVER_MODULE(ofw_iicbus, tegra_iic, ofw_iicbus_driver,
- ofwiicbus_devclass, 0, 0, BUS_PASS_BUS);
+ NULL, NULL, 73);
diff --git a/sys/arm/nvidia/tegra_lic.c b/sys/arm/nvidia/tegra_lic.c
index 5a27a65..b029913 100644
--- a/sys/arm/nvidia/tegra_lic.c
+++ b/sys/arm/nvidia/tegra_lic.c
@@ -88,12 +88,12 @@ struct tegra_lic_sc {
};
static int
-tegra_lic_alloc_intr(device_t dev, struct intr_irqsrc *isrc,
+tegra_lic_activate_intr(device_t dev, struct intr_irqsrc *isrc,
struct resource *res, struct intr_map_data *data)
{
struct tegra_lic_sc *sc = device_get_softc(dev);
- return (PIC_ALLOC_INTR(sc->parent, isrc, res, data));
+ return (PIC_ACTIVATE_INTR(sc->parent, isrc, res, data));
}
static void
@@ -122,12 +122,12 @@ tegra_lic_map_intr(device_t dev, struct intr_map_data *data,
}
static int
-tegra_lic_release_intr(device_t dev, struct intr_irqsrc *isrc,
+tegra_lic_deactivate_intr(device_t dev, struct intr_irqsrc *isrc,
struct resource *res, struct intr_map_data *data)
{
struct tegra_lic_sc *sc = device_get_softc(dev);
- return (PIC_RELEASE_INTR(sc->parent, isrc, res, data));
+ return (PIC_DEACTIVATE_INTR(sc->parent, isrc, res, data));
}
static int
@@ -266,11 +266,11 @@ static device_method_t tegra_lic_methods[] = {
DEVMETHOD(device_detach, tegra_lic_detach),
/* Interrupt controller interface */
- DEVMETHOD(pic_alloc_intr, tegra_lic_alloc_intr),
+ DEVMETHOD(pic_activate_intr, tegra_lic_activate_intr),
DEVMETHOD(pic_disable_intr, tegra_lic_disable_intr),
DEVMETHOD(pic_enable_intr, tegra_lic_enable_intr),
DEVMETHOD(pic_map_intr, tegra_lic_map_intr),
- DEVMETHOD(pic_release_intr, tegra_lic_release_intr),
+ DEVMETHOD(pic_deactivate_intr, tegra_lic_deactivate_intr),
DEVMETHOD(pic_setup_intr, tegra_lic_setup_intr),
DEVMETHOD(pic_teardown_intr, tegra_lic_teardown_intr),
DEVMETHOD(pic_pre_ithread, tegra_lic_pre_ithread),
@@ -281,8 +281,9 @@ static device_method_t tegra_lic_methods[] = {
#endif
DEVMETHOD_END
};
+
devclass_t tegra_lic_devclass;
-DEFINE_CLASS_0(tegra_lic, tegra_lic_driver, tegra_lic_methods,
+static DEFINE_CLASS_0(lic, tegra_lic_driver, tegra_lic_methods,
sizeof(struct tegra_lic_sc));
EARLY_DRIVER_MODULE(tegra_lic, simplebus, tegra_lic_driver, tegra_lic_devclass,
NULL, NULL, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE + 1);
diff --git a/sys/arm/nvidia/tegra_pcie.c b/sys/arm/nvidia/tegra_pcie.c
index ac38eb2..0efdc1a 100644
--- a/sys/arm/nvidia/tegra_pcie.c
+++ b/sys/arm/nvidia/tegra_pcie.c
@@ -33,20 +33,20 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/devmap.h>
+#include <sys/proc.h>
#include <sys/kernel.h>
-#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
-#include <sys/queue.h>
-#include <sys/bus.h>
#include <sys/rman.h>
-#include <sys/endian.h>
-#include <sys/devmap.h>
#include <machine/intr.h>
#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
#include <vm/pmap.h>
#include <dev/extres/clk/clk.h>
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/ofw/ofw_pci.h>
+#include <dev/ofw/ofwpci.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcib_private.h>
@@ -64,100 +65,14 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h>
#include <machine/bus.h>
-#include "ofw_bus_if.h"
-#include "pcib_if.h"
-
#include <arm/nvidia/tegra_pmc.h>
-/* --- Move to ofw_pci.c/.h ----------------------- */
-
-struct tegra_pci_range {
- /* parsed phys.hi */
- int nonrelocatable;
- int prefetchable;
- int aliased;
- int space_code; /* In native format (not shifted)*/
- int bus;
- int device;
- int function;
- int reg;
- pci_addr_t pci_addr; /* PCI Address */
- bus_addr_t host_addr; /* Host bus address*/
- bus_size_t size; /* Range size */
-};
-
-static int
-tegra_pci_get_ranges(phandle_t node, struct tegra_pci_range **ranges)
-{
- int host_address_cells, pci_address_cells, size_cells;
- cell_t *base_ranges;
- ssize_t nbase_ranges;
- int nranges;
- int i, j, k;
- uint32_t flags;
- uint64_t tmp;
-
- host_address_cells = 1;
- pci_address_cells = 3;
- size_cells = 2;
- OF_getencprop(OF_parent(node), "#address-cells", &host_address_cells,
- sizeof(host_address_cells));
- OF_getencprop(node, "#address-cells", &pci_address_cells,
- sizeof(pci_address_cells));
- OF_getencprop(node, "#size-cells", &size_cells, sizeof(size_cells));
-
- nbase_ranges = OF_getproplen(node, "ranges");
- if (nbase_ranges <= 0)
- return (-1);
- nranges = nbase_ranges / sizeof(cell_t) /
- (pci_address_cells + host_address_cells + size_cells);
-
- *ranges = malloc(nranges * sizeof(struct tegra_pci_range),
- M_DEVBUF, M_WAITOK);
- base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK);
- OF_getencprop(node, "ranges", base_ranges, nbase_ranges);
-
- for (i = 0, j = 0; i < nranges; i++) {
- flags = base_ranges[j++];
- (*ranges)[i].nonrelocatable =
- flags & OFW_PCI_PHYS_HI_NONRELOCATABLE ? 1 : 0;
- (*ranges)[i].prefetchable =
- flags & OFW_PCI_PHYS_HI_PREFETCHABLE ? 1 : 0;
- (*ranges)[i].aliased =
- flags & OFW_PCI_PHYS_HI_ALIASED ? 1 : 0;
- (*ranges)[i].space_code = flags & OFW_PCI_PHYS_HI_SPACEMASK;
- (*ranges)[i].bus = OFW_PCI_PHYS_HI_BUS(flags);
- (*ranges)[i].device = OFW_PCI_PHYS_HI_DEVICE(flags);
- (*ranges)[i].function = OFW_PCI_PHYS_HI_FUNCTION(flags);
- (*ranges)[i].reg = flags & OFW_PCI_PHYS_HI_REGISTERMASK;
-
- tmp = 0;
- for (k = 0; k < pci_address_cells - 1; k++) {
- tmp <<= 32;
- tmp |= base_ranges[j++];
- }
- (*ranges)[i].pci_addr = (pci_addr_t)tmp;
-
- tmp = 0;
- for (k = 0; k < host_address_cells; k++) {
- tmp <<= 32;
- tmp |= base_ranges[j++];
- }
- (*ranges)[i].host_addr = (bus_addr_t)tmp;
- tmp = 0;
+#include "ofw_bus_if.h"
+#include "msi_if.h"
+#include "pcib_if.h"
+#include "pic_if.h"
- for (k = 0; k < size_cells; k++) {
- tmp <<= 32;
- tmp |= base_ranges[j++];
- }
- (*ranges)[i].size = (bus_size_t)tmp;
- }
- free(base_ranges, M_DEVBUF);
- return (nranges);
-}
-
-/* -------------------------------------------------------------------------- */
#define AFI_AXI_BAR0_SZ 0x000
#define AFI_AXI_BAR1_SZ 0x004
#define AFI_AXI_BAR2_SZ 0x008
@@ -179,17 +94,10 @@ tegra_pci_get_ranges(phandle_t node, struct tegra_pci_range **ranges)
#define AFI_MSI_BAR_SZ 0x060
#define AFI_MSI_FPCI_BAR_ST 0x064
#define AFI_MSI_AXI_BAR_ST 0x068
-
-
-#define AFI_AXI_BAR6_SZ 0x134
-#define AFI_AXI_BAR7_SZ 0x138
-#define AFI_AXI_BAR8_SZ 0x13c
-#define AFI_AXI_BAR6_START 0x140
-#define AFI_AXI_BAR7_START 0x144
-#define AFI_AXI_BAR8_START 0x148
-#define AFI_FPCI_BAR6 0x14c
-#define AFI_FPCI_BAR7 0x150
-#define AFI_FPCI_BAR8 0x154
+#define AFI_MSI_VEC(x) (0x06c + 4 * (x))
+#define AFI_MSI_EN_VEC(x) (0x08c + 4 * (x))
+#define AFI_MSI_INTR_IN_REG 32
+#define AFI_MSI_REGS 8
#define AFI_CONFIGURATION 0x0ac
#define AFI_CONFIGURATION_EN_FPCI (1 << 0)
@@ -293,7 +201,10 @@ tegra_pci_get_ranges(phandle_t node, struct tegra_pci_range **ranges)
#define RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE 0x20000000
#define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000
-#define TEGRA_PCIE_LINKUP_TIMEOUT 200
+/* Wait 50 ms (per port) for link. */
+#define TEGRA_PCIE_LINKUP_TIMEOUT 50000
+
+#define TEGRA_PCIB_MSI_ENABLE
#define DEBUG
#ifdef DEBUG
@@ -344,6 +255,13 @@ static struct ofw_compat_data compat_data[] = {
{NULL, 0},
};
+#define TEGRA_FLAG_MSI_USED 0x0001
+struct tegra_pcib_irqsrc {
+ struct intr_irqsrc isrc;
+ u_int irq;
+ u_int flags;
+};
+
struct tegra_pcib_port {
int enabled;
int port_idx; /* chip port index */
@@ -357,13 +275,11 @@ struct tegra_pcib_port {
};
#define TEGRA_PCIB_MAX_PORTS 3
+#define TEGRA_PCIB_MAX_MSI AFI_MSI_INTR_IN_REG * AFI_MSI_REGS
struct tegra_pcib_softc {
+ struct ofw_pci_softc ofw_pci;
device_t dev;
struct mtx mtx;
- struct ofw_bus_iinfo pci_iinfo;
- struct rman pref_mem_rman;
- struct rman mem_rman;
- struct rman io_rman;
struct resource *pads_mem_res;
struct resource *afi_mem_res;
struct resource *cfg_mem_res;
@@ -372,18 +288,18 @@ struct tegra_pcib_softc {
void *intr_cookie;
void *msi_intr_cookie;
- struct tegra_pci_range mem_range;
- struct tegra_pci_range pref_mem_range;
- struct tegra_pci_range io_range;
+ struct ofw_pci_range mem_range;
+ struct ofw_pci_range pref_mem_range;
+ struct ofw_pci_range io_range;
phy_t phy;
clk_t clk_pex;
clk_t clk_afi;
clk_t clk_pll_e;
clk_t clk_cml;
- hwreset_t hwreset_pex;
- hwreset_t hwreset_afi;
- hwreset_t hwreset_pcie_x;
+ hwreset_t hwreset_pex;
+ hwreset_t hwreset_afi;
+ hwreset_t hwreset_pcie_x;
regulator_t supply_avddio_pex;
regulator_t supply_dvddio_pex;
regulator_t supply_avdd_pex_pll;
@@ -392,8 +308,7 @@ struct tegra_pcib_softc {
regulator_t supply_vddio_pex_ctl;
regulator_t supply_avdd_pll_erefe;
- int busnr; /* host bridge bus number */
- uint32_t msi_bitmap;
+ vm_offset_t msi_page; /* VA of MSI page */
bus_addr_t cfg_base_addr; /* base address of config */
bus_size_t cfg_cur_offs; /* currently mapped window */
bus_space_handle_t cfg_handle; /* handle of config window */
@@ -401,276 +316,28 @@ struct tegra_pcib_softc {
int lanes_cfg;
int num_ports;
struct tegra_pcib_port *ports[TEGRA_PCIB_MAX_PORTS];
+ struct tegra_pcib_irqsrc *isrcs;
};
-/* ------------------------------------------------------------------------- */
-/*
- * Resource manager
- */
-static int
-tegra_pcib_rman_init(struct tegra_pcib_softc *sc)
-{
- int err;
- char buf[64];
-
- /* Memory management. */
- sc->pref_mem_rman.rm_type = RMAN_ARRAY;
- snprintf(buf, sizeof(buf), "%s prefetchable memory space",
- device_get_nameunit(sc->dev));
- sc->pref_mem_rman.rm_descr = strdup(buf, M_DEVBUF);
- err = rman_init(&sc->pref_mem_rman);
- if (err)
- return (err);
-
- sc->mem_rman.rm_type = RMAN_ARRAY;
- snprintf(buf, sizeof(buf), "%s non prefetchable memory space",
- device_get_nameunit(sc->dev));
- sc->mem_rman.rm_descr = strdup(buf, M_DEVBUF);
- err = rman_init(&sc->mem_rman);
- if (err)
- return (err);
-
- sc->io_rman.rm_type = RMAN_ARRAY;
- snprintf(buf, sizeof(buf), "%s I/O space",
- device_get_nameunit(sc->dev));
- sc->io_rman.rm_descr = strdup(buf, M_DEVBUF);
- err = rman_init(&sc->io_rman);
- if (err) {
- rman_fini(&sc->mem_rman);
- return (err);
- }
-
- err = rman_manage_region(&sc->pref_mem_rman,
- sc->pref_mem_range.host_addr,
- sc->pref_mem_range.host_addr + sc->pref_mem_range.size - 1);
- if (err)
- goto error;
- err = rman_manage_region(&sc->mem_rman,
- sc->mem_range.host_addr,
- sc->mem_range.host_addr + sc->mem_range.size - 1);
- if (err)
- goto error;
- err = rman_manage_region(&sc->io_rman,
- sc->io_range.pci_addr,
- sc->io_range.pci_addr + sc->io_range.size - 1);
- if (err)
- goto error;
- return (0);
-
-error:
- rman_fini(&sc->pref_mem_rman);
- rman_fini(&sc->mem_rman);
- rman_fini(&sc->io_rman);
- return (err);
-}
-
-static struct rman *
-tegra_pcib_rman(struct tegra_pcib_softc *sc, int type, u_int flags)
-{
-
- switch (type) {
- case SYS_RES_IOPORT:
- return (&sc->io_rman);
- case SYS_RES_MEMORY:
- if (flags & RF_PREFETCHABLE)
- return (&sc->pref_mem_rman);
- else
- return (&sc->mem_rman);
- default:
- break;
- }
-
- return (NULL);
-}
-
-static struct resource *
-tegra_pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
- rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
-{
- struct tegra_pcib_softc *sc;
- struct rman *rm;
- struct resource *res;
-
- debugf("%s: enter %d start %#jx end %#jx count %#jx\n", __func__,
- type, start, end, count);
- sc = device_get_softc(dev);
-
-#if defined(NEW_PCIB) && defined(PCI_RES_BUS)
- if (type == PCI_RES_BUS) {
- return (pci_domain_alloc_bus(0, child, rid, start, end, count,
- flags));
- }
-#endif
-
- rm = tegra_pcib_rman(sc, type, flags);
-
- if (rm == NULL) {
- res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
- type, rid, start, end, count, flags);
-
- return (res);
- }
-
- if (bootverbose) {
- device_printf(dev,
- "rman_reserve_resource: start=%#jx, end=%#jx, count=%#jx\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=%016jx, end=%016jx, count=%016jx, flags=%x\n",
- __func__, type, *rid, start, end, count, flags);
- }
-
- return (NULL);
-}
-
-static int
-tegra_pcib_release_resource(device_t dev, device_t child, int type, int rid,
- struct resource *res)
-{
- struct tegra_pcib_softc *sc;
- struct rman *rm;
-
- sc = device_get_softc(dev);
- debugf("%s: %d rid %x\n", __func__, type, rid);
-
-#if defined(NEW_PCIB) && defined(PCI_RES_BUS)
- if (type == PCI_RES_BUS)
- return (pci_domain_release_bus(0, child, rid, res));
-#endif
-
- rm = tegra_pcib_rman(sc, type, rman_get_flags(res));
- 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 int
-tegra_pcib_adjust_resource(device_t dev, device_t child, int type,
- struct resource *res, rman_res_t start, rman_res_t end)
-{
- struct tegra_pcib_softc *sc;
- struct rman *rm;
-
- sc = device_get_softc(dev);
- debugf("%s: %d start %jx end %jx \n", __func__, type, start, end);
-
-#if defined(NEW_PCIB) && defined(PCI_RES_BUS)
- if (type == PCI_RES_BUS)
- return (pci_domain_adjust_bus(0, child, res, start, end));
-#endif
-
- rm = tegra_pcib_rman(sc, type, rman_get_flags(res));
- if (rm != NULL)
- return (rman_adjust_resource(res, start, end));
- return (bus_generic_adjust_resource(dev, child, type, res, start, end));
-}
-extern bus_space_tag_t fdtbus_bs_tag;
-static int
-tegra_pcib_pcie_activate_resource(device_t dev, device_t child, int type,
- int rid, struct resource *r)
-{
- struct tegra_pcib_softc *sc;
- vm_offset_t start;
- void *p;
- int rv;
-
- sc = device_get_softc(dev);
- rv = rman_activate_resource(r);
- if (rv != 0)
- return (rv);
- switch(type) {
- case SYS_RES_IOPORT:
- start = rman_get_start(r) + sc->io_range.host_addr;
- break;
- default:
- start = rman_get_start(r);
- rman_get_start(r);
- break;
- }
-
- if (bootverbose)
- printf("%s: start %zx, len %jd\n", __func__, start,
- rman_get_size(r));
-
- p = pmap_mapdev(start, (vm_size_t)rman_get_size(r));
- rman_set_virtual(r, p);
- rman_set_bustag(r, fdtbus_bs_tag);
- rman_set_bushandle(r, (u_long)p);
- return (0);
-}
-
-/* ------------------------------------------------------------------------- */
-/*
- * IVARs
- */
-static int
-tegra_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
-{
- struct tegra_pcib_softc *sc = device_get_softc(dev);
-
- switch (which) {
- case PCIB_IVAR_BUS:
- *result = sc->busnr;
- return (0);
- case PCIB_IVAR_DOMAIN:
- *result = device_get_unit(dev);
- return (0);
- }
-
- return (ENOENT);
-}
-
-static int
-tegra_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
-{
- struct tegra_pcib_softc *sc = device_get_softc(dev);
-
- switch (which) {
- case PCIB_IVAR_BUS:
- sc->busnr = value;
- return (0);
- }
-
- return (ENOENT);
-}
-
static int
tegra_pcib_maxslots(device_t dev)
{
return (16);
}
-
static int
tegra_pcib_route_interrupt(device_t bus, device_t dev, int pin)
{
struct tegra_pcib_softc *sc;
+ u_int irq;
sc = device_get_softc(bus);
- device_printf(bus, "route pin %d for device %d.%d to %ju\n",
+ irq = intr_map_clone_irq(rman_get_start(sc->irq_res));
+ device_printf(bus, "route pin %d for device %d.%d to %u\n",
pin, pci_get_slot(dev), pci_get_function(dev),
- rman_get_start(sc->irq_res));
+ irq);
- return (rman_get_start(sc->irq_res));
+ return (irq);
}
static int
@@ -811,84 +478,316 @@ static int tegra_pci_intr(void *arg)
return (FILTER_HANDLED);
}
-#if defined(TEGRA_PCI_MSI)
+/* -----------------------------------------------------------------------
+ *
+ * PCI MSI interface
+ */
+static int
+tegra_pcib_alloc_msi(device_t pci, device_t child, int count, int maxcount,
+ int *irqs)
+{
+ phandle_t msi_parent;
+
+ /* XXXX ofw_bus_msimap() don't works for Tegra DT.
+ ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), &msi_parent,
+ NULL);
+ */
+ msi_parent = OF_xref_from_node(ofw_bus_get_node(pci));
+ return (intr_alloc_msi(pci, child, msi_parent, count, maxcount,
+ irqs));
+}
+
static int
-tegra_pcib_map_msi(device_t dev, device_t child, int irq, uint64_t *addr,
+tegra_pcib_release_msi(device_t pci, device_t child, int count, int *irqs)
+{
+ phandle_t msi_parent;
+
+ /* XXXX ofw_bus_msimap() don't works for Tegra DT.
+ ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), &msi_parent,
+ NULL);
+ */
+ msi_parent = OF_xref_from_node(ofw_bus_get_node(pci));
+ return (intr_release_msi(pci, child, msi_parent, count, irqs));
+}
+
+static int
+tegra_pcib_map_msi(device_t pci, device_t child, int irq, uint64_t *addr,
uint32_t *data)
{
+ phandle_t msi_parent;
+
+ /* XXXX ofw_bus_msimap() don't works for Tegra DT.
+ ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), &msi_parent,
+ NULL);
+ */
+ msi_parent = OF_xref_from_node(ofw_bus_get_node(pci));
+ return (intr_map_msi(pci, child, msi_parent, irq, addr, data));
+}
+
+#ifdef TEGRA_PCIB_MSI_ENABLE
+
+/* --------------------------------------------------------------------------
+ *
+ * Interrupts
+ *
+ */
+
+static inline void
+tegra_pcib_isrc_mask(struct tegra_pcib_softc *sc,
+ struct tegra_pcib_irqsrc *tgi, uint32_t val)
+{
+ uint32_t reg;
+ int offs, bit;
+
+ offs = tgi->irq / AFI_MSI_INTR_IN_REG;
+ bit = 1 << (tgi->irq % AFI_MSI_INTR_IN_REG);
+
+ if (val != 0)
+ AFI_WR4(sc, AFI_MSI_VEC(offs), bit);
+ reg = AFI_RD4(sc, AFI_MSI_EN_VEC(offs));
+ if (val != 0)
+ reg |= bit;
+ else
+ reg &= ~bit;
+ AFI_WR4(sc, AFI_MSI_EN_VEC(offs), reg);
+}
+
+static int
+tegra_pcib_msi_intr(void *arg)
+{
+ u_int irq, i, bit, reg;
+ struct tegra_pcib_softc *sc;
+ struct trapframe *tf;
+ struct tegra_pcib_irqsrc *tgi;
+
+ sc = (struct tegra_pcib_softc *)arg;
+ tf = curthread->td_intr_frame;
+
+ for (i = 0; i < AFI_MSI_REGS; i++) {
+ reg = AFI_RD4(sc, AFI_MSI_VEC(i));
+ /* Handle one vector. */
+ while (reg != 0) {
+ bit = ffs(reg) - 1;
+ /* Send EOI */
+ AFI_WR4(sc, AFI_MSI_VEC(i), 1 << bit);
+ irq = i * AFI_MSI_INTR_IN_REG + bit;
+ tgi = &sc->isrcs[irq];
+ if (intr_isrc_dispatch(&tgi->isrc, tf) != 0) {
+ /* Disable stray. */
+ tegra_pcib_isrc_mask(sc, tgi, 0);
+ device_printf(sc->dev,
+ "Stray irq %u disabled\n", irq);
+ }
+ reg = AFI_RD4(sc, AFI_MSI_VEC(i));
+ }
+ }
+ return (FILTER_HANDLED);
+}
+
+static int
+tegra_pcib_msi_attach(struct tegra_pcib_softc *sc)
+{
+ int error;
+ uint32_t irq;
+ const char *name;
+
+ sc->isrcs = malloc(sizeof(*sc->isrcs) * TEGRA_PCIB_MAX_MSI, M_DEVBUF,
+ M_WAITOK | M_ZERO);
+
+ name = device_get_nameunit(sc->dev);
+ for (irq = 0; irq < TEGRA_PCIB_MAX_MSI; irq++) {
+ sc->isrcs[irq].irq = irq;
+ error = intr_isrc_register(&sc->isrcs[irq].isrc,
+ sc->dev, 0, "%s,%u", name, irq);
+ if (error != 0)
+ return (error); /* XXX deregister ISRCs */
+ }
+ if (intr_msi_register(sc->dev,
+ OF_xref_from_node(ofw_bus_get_node(sc->dev))) != 0)
+ return (ENXIO);
+
+ return (0);
+}
+
+static int
+tegra_pcib_msi_detach(struct tegra_pcib_softc *sc)
+{
+
+ /*
+ * There has not been established any procedure yet
+ * how to detach PIC from living system correctly.
+ */
+ device_printf(sc->dev, "%s: not implemented yet\n", __func__);
+ return (EBUSY);
+}
+
+
+static void
+tegra_pcib_msi_disable_intr(device_t dev, struct intr_irqsrc *isrc)
+{
struct tegra_pcib_softc *sc;
+ struct tegra_pcib_irqsrc *tgi;
sc = device_get_softc(dev);
- irq = irq - MSI_IRQ;
+ tgi = (struct tegra_pcib_irqsrc *)isrc;
+ tegra_pcib_isrc_mask(sc, tgi, 0);
+}
- /* validate parameters */
- if (isclr(&sc->msi_bitmap, irq)) {
- device_printf(dev, "invalid MSI 0x%x\n", irq);
- return (EINVAL);
- }
+static void
+tegra_pcib_msi_enable_intr(device_t dev, struct intr_irqsrc *isrc)
+{
+ struct tegra_pcib_softc *sc;
+ struct tegra_pcib_irqsrc *tgi;
- tegra_msi_data(irq, addr, data);
+ sc = device_get_softc(dev);
+ tgi = (struct tegra_pcib_irqsrc *)isrc;
+ tegra_pcib_isrc_mask(sc, tgi, 1);
+}
- debugf("%s: irq: %d addr: %jx data: %x\n",
- __func__, irq, *addr, *data);
+/* MSI interrupts are edge trigered -> do nothing */
+static void
+tegra_pcib_msi_post_filter(device_t dev, struct intr_irqsrc *isrc)
+{
+}
+
+static void
+tegra_pcib_msi_post_ithread(device_t dev, struct intr_irqsrc *isrc)
+{
+}
+
+static void
+tegra_pcib_msi_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
+{
+}
+static int
+tegra_pcib_msi_setup_intr(device_t dev, struct intr_irqsrc *isrc,
+ struct resource *res, struct intr_map_data *data)
+{
+ struct tegra_pcib_softc *sc;
+ struct tegra_pcib_irqsrc *tgi;
+
+ sc = device_get_softc(dev);
+ tgi = (struct tegra_pcib_irqsrc *)isrc;
+
+ if (data == NULL || data->type != INTR_MAP_DATA_MSI)
+ return (ENOTSUP);
+
+ if (isrc->isrc_handlers == 0)
+ tegra_pcib_msi_enable_intr(dev, isrc);
+
+ return (0);
+}
+
+static int
+tegra_pcib_msi_teardown_intr(device_t dev, struct intr_irqsrc *isrc,
+ struct resource *res, struct intr_map_data *data)
+{
+ struct tegra_pcib_softc *sc;
+ struct tegra_pcib_irqsrc *tgi;
+
+ sc = device_get_softc(dev);
+ tgi = (struct tegra_pcib_irqsrc *)isrc;
+
+ if (isrc->isrc_handlers == 0)
+ tegra_pcib_isrc_mask(sc, tgi, 0);
return (0);
}
+
static int
-tegra_pcib_alloc_msi(device_t dev, device_t child, int count,
- int maxcount __unused, int *irqs)
+tegra_pcib_msi_alloc_msi(device_t dev, device_t child, int count, int maxcount,
+ device_t *pic, struct intr_irqsrc **srcs)
{
struct tegra_pcib_softc *sc;
- u_int start = 0, i;
+ int i, irq, end_irq;
+ bool found;
- if (powerof2(count) == 0 || count > MSI_IRQ_NUM)
- return (EINVAL);
+ KASSERT(powerof2(count), ("%s: bad count", __func__));
+ KASSERT(powerof2(maxcount), ("%s: bad maxcount", __func__));
sc = device_get_softc(dev);
mtx_lock(&sc->mtx);
- for (start = 0; (start + count) < MSI_IRQ_NUM; start++) {
- for (i = start; i < start + count; i++) {
- if (isset(&sc->msi_bitmap, i))
+ found = false;
+ for (irq = 0; (irq + count - 1) < TEGRA_PCIB_MAX_MSI; irq++) {
+ /* Start on an aligned interrupt */
+ if ((irq & (maxcount - 1)) != 0)
+ continue;
+
+ /* Assume we found a valid range until shown otherwise */
+ found = true;
+
+ /* Check this range is valid */
+ for (end_irq = irq; end_irq < irq + count; end_irq++) {
+ /* This is already used */
+ if ((sc->isrcs[end_irq].flags & TEGRA_FLAG_MSI_USED) ==
+ TEGRA_FLAG_MSI_USED) {
+ found = false;
break;
+ }
}
- if (i == start + count)
+
+ if (found)
break;
}
- if ((start + count) == MSI_IRQ_NUM) {
+ /* Not enough interrupts were found */
+ if (!found || irq == (TEGRA_PCIB_MAX_MSI - 1)) {
mtx_unlock(&sc->mtx);
return (ENXIO);
}
- for (i = start; i < start + count; i++) {
- setbit(&sc->msi_bitmap, i);
- irqs[i] = MSI_IRQ + i;
- }
- debugf("%s: start: %x count: %x\n", __func__, start, count);
+ for (i = 0; i < count; i++) {
+ /* Mark the interrupt as used */
+ sc->isrcs[irq + i].flags |= TEGRA_FLAG_MSI_USED;
+ }
mtx_unlock(&sc->mtx);
+
+ for (i = 0; i < count; i++)
+ srcs[i] = (struct intr_irqsrc *)&sc->isrcs[irq + i];
+ *pic = device_get_parent(dev);
return (0);
}
static int
-tegra_pcib_release_msi(device_t dev, device_t child, int count, int *irqs)
+tegra_pcib_msi_release_msi(device_t dev, device_t child, int count,
+ struct intr_irqsrc **isrc)
{
struct tegra_pcib_softc *sc;
- u_int i;
+ struct tegra_pcib_irqsrc *ti;
+ int i;
sc = device_get_softc(dev);
mtx_lock(&sc->mtx);
+ for (i = 0; i < count; i++) {
+ ti = (struct tegra_pcib_irqsrc *)isrc[i];
- for (i = 0; i < count; i++)
- clrbit(&sc->msi_bitmap, irqs[i] - MSI_IRQ);
+ KASSERT((ti->flags & TEGRA_FLAG_MSI_USED) == TEGRA_FLAG_MSI_USED,
+ ("%s: Trying to release an unused MSI-X interrupt",
+ __func__));
+ ti->flags &= ~TEGRA_FLAG_MSI_USED;
+ }
mtx_unlock(&sc->mtx);
return (0);
}
+
+static int
+tegra_pcib_msi_map_msi(device_t dev, device_t child, struct intr_irqsrc *isrc,
+ uint64_t *addr, uint32_t *data)
+{
+ struct tegra_pcib_softc *sc = device_get_softc(dev);
+ struct tegra_pcib_irqsrc *ti = (struct tegra_pcib_irqsrc *)isrc;
+
+ *addr = vtophys(sc->msi_page);
+ *data = ti->irq;
+ return (0);
+}
#endif
+/* ------------------------------------------------------------------- */
static bus_size_t
tegra_pcib_pex_ctrl(struct tegra_pcib_softc *sc, int port)
{
@@ -947,7 +846,6 @@ tegra_pcib_enable_fdt_resources(struct tegra_pcib_softc *sc)
"Cannot enable 'avdd-pex-pll' regulator\n");
return (rv);
}
-
rv = regulator_enable(sc->supply_hvdd_pex);
if (rv != 0) {
device_printf(sc->dev,
@@ -991,13 +889,11 @@ tegra_pcib_enable_fdt_resources(struct tegra_pcib_softc *sc)
device_printf(sc->dev, "Cannot enable 'afi' clock\n");
return (rv);
}
-
rv = clk_enable(sc->clk_cml);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable 'cml' clock\n");
return (rv);
}
-
rv = clk_enable(sc->clk_pll_e);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable 'pll_e' clock\n");
@@ -1080,49 +976,49 @@ tegra_pcib_parse_fdt_resources(struct tegra_pcib_softc *sc, phandle_t node)
int rv;
/* Power supplies. */
- rv = regulator_get_by_ofw_property(sc->dev, "avddio-pex-supply",
+ rv = regulator_get_by_ofw_property(sc->dev, 0, "avddio-pex-supply",
&sc->supply_avddio_pex);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'avddio-pex' regulator\n");
return (ENXIO);
}
- rv = regulator_get_by_ofw_property(sc->dev, "dvddio-pex-supply",
+ rv = regulator_get_by_ofw_property(sc->dev, 0, "dvddio-pex-supply",
&sc->supply_dvddio_pex);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'dvddio-pex' regulator\n");
return (ENXIO);
}
- rv = regulator_get_by_ofw_property(sc->dev, "avdd-pex-pll-supply",
+ rv = regulator_get_by_ofw_property(sc->dev, 0, "avdd-pex-pll-supply",
&sc->supply_avdd_pex_pll);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'avdd-pex-pll' regulator\n");
return (ENXIO);
}
- rv = regulator_get_by_ofw_property(sc->dev, "hvdd-pex-supply",
+ rv = regulator_get_by_ofw_property(sc->dev, 0, "hvdd-pex-supply",
&sc->supply_hvdd_pex);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'hvdd-pex' regulator\n");
return (ENXIO);
}
- rv = regulator_get_by_ofw_property(sc->dev, "hvdd-pex-pll-e-supply",
+ rv = regulator_get_by_ofw_property(sc->dev, 0, "hvdd-pex-pll-e-supply",
&sc->supply_hvdd_pex_pll_e);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'hvdd-pex-pll-e' regulator\n");
return (ENXIO);
}
- rv = regulator_get_by_ofw_property(sc->dev, "vddio-pex-ctl-supply",
+ rv = regulator_get_by_ofw_property(sc->dev, 0, "vddio-pex-ctl-supply",
&sc->supply_vddio_pex_ctl);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'vddio-pex-ctl' regulator\n");
return (ENXIO);
}
- rv = regulator_get_by_ofw_property(sc->dev, "avdd-pll-erefe-supply",
+ rv = regulator_get_by_ofw_property(sc->dev, 0, "avdd-pll-erefe-supply",
&sc->supply_avdd_pll_erefe);
if (rv != 0) {
device_printf(sc->dev,
@@ -1131,46 +1027,46 @@ tegra_pcib_parse_fdt_resources(struct tegra_pcib_softc *sc, phandle_t node)
}
/* Resets. */
- rv = hwreset_get_by_ofw_name(sc->dev, "pex", &sc->hwreset_pex);
+ rv = hwreset_get_by_ofw_name(sc->dev, 0, "pex", &sc->hwreset_pex);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'pex' reset\n");
return (ENXIO);
}
- rv = hwreset_get_by_ofw_name(sc->dev, "afi", &sc->hwreset_afi);
+ rv = hwreset_get_by_ofw_name(sc->dev, 0, "afi", &sc->hwreset_afi);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'afi' reset\n");
return (ENXIO);
}
- rv = hwreset_get_by_ofw_name(sc->dev, "pcie_x", &sc->hwreset_pcie_x);
+ rv = hwreset_get_by_ofw_name(sc->dev, 0, "pcie_x", &sc->hwreset_pcie_x);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'pcie_x' reset\n");
return (ENXIO);
}
/* Clocks. */
- rv = clk_get_by_ofw_name(sc->dev, "pex", &sc->clk_pex);
+ rv = clk_get_by_ofw_name(sc->dev, 0, "pex", &sc->clk_pex);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'pex' clock\n");
return (ENXIO);
}
- rv = clk_get_by_ofw_name(sc->dev, "afi", &sc->clk_afi);
+ rv = clk_get_by_ofw_name(sc->dev, 0, "afi", &sc->clk_afi);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'afi' clock\n");
return (ENXIO);
}
- rv = clk_get_by_ofw_name(sc->dev, "pll_e", &sc->clk_pll_e);
+ rv = clk_get_by_ofw_name(sc->dev, 0, "pll_e", &sc->clk_pll_e);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'pll_e' clock\n");
return (ENXIO);
}
- rv = clk_get_by_ofw_name(sc->dev, "cml", &sc->clk_cml);
+ rv = clk_get_by_ofw_name(sc->dev, 0, "cml", &sc->clk_cml);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'cml' clock\n");
return (ENXIO);
}
/* Phy. */
- rv = phy_get_by_ofw_name(sc->dev, "pcie", &sc->phy);
+ rv = phy_get_by_ofw_name(sc->dev, 0, "pcie", &sc->phy);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'pcie' phy\n");
return (ENXIO);
@@ -1192,12 +1088,13 @@ tegra_pcib_parse_fdt_resources(struct tegra_pcib_softc *sc, phandle_t node)
static int
tegra_pcib_decode_ranges(struct tegra_pcib_softc *sc,
- struct tegra_pci_range *ranges, int nranges)
+ struct ofw_pci_range *ranges, int nranges)
{
int i;
for (i = 2; i < nranges; i++) {
- if (ranges[i].space_code == OFW_PCI_PHYS_HI_SPACE_IO) {
+ if ((ranges[i].pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) ==
+ OFW_PCI_PHYS_HI_SPACE_IO) {
if (sc->io_range.size != 0) {
device_printf(sc->dev,
"Duplicated IO range found in DT\n");
@@ -1205,23 +1102,25 @@ tegra_pcib_decode_ranges(struct tegra_pcib_softc *sc,
}
sc->io_range = ranges[i];
}
- if ((ranges[i].space_code == OFW_PCI_PHYS_HI_SPACE_MEM32) &&
- !ranges[i].prefetchable) {
- if (sc->mem_range.size != 0) {
- device_printf(sc->dev,
- "Duplicated memory range found in DT\n");
- return (ENXIO);
- }
- sc->mem_range = ranges[i];
- }
- if ((ranges[i].space_code == OFW_PCI_PHYS_HI_SPACE_MEM32) &&
- ranges[i].prefetchable) {
- if (sc->pref_mem_range.size != 0) {
- device_printf(sc->dev,
- "Duplicated memory range found in DT\n");
- return (ENXIO);
+ if (((ranges[i].pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) ==
+ OFW_PCI_PHYS_HI_SPACE_MEM32)) {
+ if (ranges[i].pci_hi & OFW_PCI_PHYS_HI_PREFETCHABLE) {
+ if (sc->pref_mem_range.size != 0) {
+ device_printf(sc->dev,
+ "Duplicated memory range found "
+ "in DT\n");
+ return (ENXIO);
+ }
+ sc->pref_mem_range = ranges[i];
+ } else {
+ if (sc->mem_range.size != 0) {
+ device_printf(sc->dev,
+ "Duplicated memory range found "
+ "in DT\n");
+ return (ENXIO);
+ }
+ sc->mem_range = ranges[i];
}
- sc->pref_mem_range = ranges[i];
}
}
if ((sc->io_range.size == 0) || (sc->mem_range.size == 0)
@@ -1257,6 +1156,7 @@ tegra_pcib_wait_for_link(struct tegra_pcib_softc *sc,
RP_VEND_XP, 4);
if (reg & RP_VEND_XP_DL_UP)
break;
+ DELAY(1);
}
if (i <= 0)
@@ -1268,6 +1168,7 @@ tegra_pcib_wait_for_link(struct tegra_pcib_softc *sc,
if (reg & RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE)
break;
+ DELAY(1);
}
if (i <= 0)
return (ETIMEDOUT);
@@ -1454,16 +1355,16 @@ tegra_pcib_enable(struct tegra_pcib_softc *sc, uint32_t port)
FPCI_MAP_EXT_TYPE1_CONFIG, rman_get_size(sc->cfg_mem_res), 0);
/* BAR 1 - downstream I/O. */
- tegra_pcib_set_bar(sc, 1, sc->io_range.host_addr, FPCI_MAP_IO,
+ tegra_pcib_set_bar(sc, 1, sc->io_range.host, FPCI_MAP_IO,
sc->io_range.size, 0);
/* BAR 2 - downstream prefetchable memory 1:1. */
- tegra_pcib_set_bar(sc, 2, sc->pref_mem_range.host_addr,
- sc->pref_mem_range.host_addr, sc->pref_mem_range.size, 1);
+ tegra_pcib_set_bar(sc, 2, sc->pref_mem_range.host,
+ sc->pref_mem_range.host, sc->pref_mem_range.size, 1);
/* BAR 3 - downstream not prefetchable memory 1:1 .*/
- tegra_pcib_set_bar(sc, 3, sc->mem_range.host_addr,
- sc->mem_range.host_addr, sc->mem_range.size, 1);
+ tegra_pcib_set_bar(sc, 3, sc->mem_range.host,
+ sc->mem_range.host, sc->mem_range.size, 1);
/* BAR 3-8 clear. */
tegra_pcib_set_bar(sc, 4, 0, 0, 0, 0);
@@ -1477,6 +1378,52 @@ tegra_pcib_enable(struct tegra_pcib_softc *sc, uint32_t port)
return(0);
}
+#ifdef TEGRA_PCIB_MSI_ENABLE
+static int
+tegra_pcib_attach_msi(device_t dev)
+{
+ struct tegra_pcib_softc *sc;
+ uint32_t reg;
+ int i, rv;
+
+ sc = device_get_softc(dev);
+
+ sc->msi_page = kmem_alloc_contig(kernel_arena, PAGE_SIZE, M_WAITOK,
+ 0, BUS_SPACE_MAXADDR, PAGE_SIZE, 0, VM_MEMATTR_DEFAULT);
+
+ /* MSI BAR */
+ tegra_pcib_set_bar(sc, 9, vtophys(sc->msi_page), vtophys(sc->msi_page),
+ PAGE_SIZE, 0);
+
+ /* Disble and clear all interrupts. */
+ for (i = 0; i < AFI_MSI_REGS; i++) {
+ AFI_WR4(sc, AFI_MSI_EN_VEC(i), 0);
+ AFI_WR4(sc, AFI_MSI_VEC(i), 0xFFFFFFFF);
+ }
+ rv = bus_setup_intr(dev, sc->msi_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
+ tegra_pcib_msi_intr, NULL, sc, &sc->msi_intr_cookie);
+ if (rv != 0) {
+ device_printf(dev, "cannot setup MSI interrupt handler\n");
+ rv = ENXIO;
+ goto out;
+ }
+
+ if (tegra_pcib_msi_attach(sc) != 0) {
+ device_printf(dev, "WARNING: unable to attach PIC\n");
+ tegra_pcib_msi_detach(sc);
+ goto out;
+ }
+
+ /* Unmask MSI interrupt. */
+ reg = AFI_RD4(sc, AFI_INTR_MASK);
+ reg |= AFI_INTR_MASK_MSI_MASK;
+ AFI_WR4(sc, AFI_INTR_MASK, reg);
+
+out:
+ return (rv);
+}
+#endif
+
static int
tegra_pcib_probe(device_t dev)
{
@@ -1498,8 +1445,6 @@ tegra_pcib_attach(device_t dev)
uint32_t unit;
int rv;
int rid;
- int nranges;
- struct tegra_pci_range *ranges;
struct tegra_pcib_port *port;
int i;
@@ -1508,7 +1453,6 @@ tegra_pcib_attach(device_t dev)
unit = fdt_get_unit(dev);
mtx_init(&sc->mtx, "msi_mtx", NULL, MTX_DEF);
-
node = ofw_bus_get_node(dev);
rv = tegra_pcib_parse_fdt_resources(sc, node);
@@ -1517,14 +1461,6 @@ tegra_pcib_attach(device_t dev)
return (rv);
}
- nranges = tegra_pci_get_ranges(node, &ranges);
- if (nranges != 5) {
- device_printf(sc->dev, "Unexpected number of ranges: %d\n",
- nranges);
- rv = ENXIO;
- goto out;
- }
-
/* Allocate bus_space resources. */
rid = 0;
sc->pads_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
@@ -1576,9 +1512,8 @@ tegra_pcib_attach(device_t dev)
}
/*
- * Get PCI interrupt info.
+ * Get PCI interrupt
*/
- ofw_bus_setup_iinfo(node, &sc->pci_iinfo, sizeof(pcell_t));
rid = 0;
sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE | RF_SHAREABLE);
@@ -1597,23 +1532,22 @@ tegra_pcib_attach(device_t dev)
goto out;
}
- if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- tegra_pci_intr, NULL, sc, &sc->intr_cookie)) {
- device_printf(dev, "cannot setup interrupt handler\n");
- rv = ENXIO;
+ sc->ofw_pci.sc_range_mask = 0x3;
+ rv = ofw_pci_init(dev);
+ if (rv != 0)
goto out;
- }
- /* Memory management. */
- rv = tegra_pcib_decode_ranges(sc, ranges, nranges);
+ rv = tegra_pcib_decode_ranges(sc, sc->ofw_pci.sc_range,
+ sc->ofw_pci.sc_nrange);
if (rv != 0)
goto out;
- rv = tegra_pcib_rman_init(sc);
- if (rv != 0)
+ if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
+ tegra_pci_intr, NULL, sc, &sc->intr_cookie)) {
+ device_printf(dev, "cannot setup interrupt handler\n");
+ rv = ENXIO;
goto out;
- free(ranges, M_DEVBUF);
- ranges = NULL;
+ }
/*
* Enable PCIE device.
@@ -1630,13 +1564,16 @@ tegra_pcib_attach(device_t dev)
tegra_pcib_port_disable(sc, i);
}
+#ifdef TEGRA_PCIB_MSI_ENABLE
+ rv = tegra_pcib_attach_msi(dev);
+ if (rv != 0)
+ goto out;
+#endif
device_add_child(dev, "pci", -1);
return (bus_generic_attach(dev));
out:
- if (ranges != NULL)
- free(ranges, M_DEVBUF);
return (rv);
}
@@ -1648,13 +1585,6 @@ static device_method_t tegra_pcib_methods[] = {
DEVMETHOD(device_attach, tegra_pcib_attach),
/* Bus interface */
- DEVMETHOD(bus_read_ivar, tegra_pcib_read_ivar),
- DEVMETHOD(bus_write_ivar, tegra_pcib_write_ivar),
- DEVMETHOD(bus_alloc_resource, tegra_pcib_alloc_resource),
- DEVMETHOD(bus_adjust_resource, tegra_pcib_adjust_resource),
- DEVMETHOD(bus_release_resource, tegra_pcib_release_resource),
- DEVMETHOD(bus_activate_resource, tegra_pcib_pcie_activate_resource),
- DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
@@ -1663,11 +1593,24 @@ static device_method_t tegra_pcib_methods[] = {
DEVMETHOD(pcib_read_config, tegra_pcib_read_config),
DEVMETHOD(pcib_write_config, tegra_pcib_write_config),
DEVMETHOD(pcib_route_interrupt, tegra_pcib_route_interrupt),
-
-#if defined(TEGRA_PCI_MSI)
DEVMETHOD(pcib_alloc_msi, tegra_pcib_alloc_msi),
DEVMETHOD(pcib_release_msi, tegra_pcib_release_msi),
DEVMETHOD(pcib_map_msi, tegra_pcib_map_msi),
+
+#ifdef TEGRA_PCIB_MSI_ENABLE
+ /* MSI/MSI-X */
+ DEVMETHOD(msi_alloc_msi, tegra_pcib_msi_alloc_msi),
+ DEVMETHOD(msi_release_msi, tegra_pcib_msi_release_msi),
+ DEVMETHOD(msi_map_msi, tegra_pcib_msi_map_msi),
+
+ /* Interrupt controller interface */
+ DEVMETHOD(pic_disable_intr, tegra_pcib_msi_disable_intr),
+ DEVMETHOD(pic_enable_intr, tegra_pcib_msi_enable_intr),
+ DEVMETHOD(pic_setup_intr, tegra_pcib_msi_setup_intr),
+ DEVMETHOD(pic_teardown_intr, tegra_pcib_msi_teardown_intr),
+ DEVMETHOD(pic_post_filter, tegra_pcib_msi_post_filter),
+ DEVMETHOD(pic_post_ithread, tegra_pcib_msi_post_ithread),
+ DEVMETHOD(pic_pre_ithread, tegra_pcib_msi_pre_ithread),
#endif
/* OFW bus interface */
@@ -1680,12 +1623,8 @@ static device_method_t tegra_pcib_methods[] = {
DEVMETHOD_END
};
-static driver_t tegra_pcib_driver = {
- "pcib",
- tegra_pcib_methods,
- sizeof(struct tegra_pcib_softc),
-};
-
-devclass_t pcib_devclass;
-
-DRIVER_MODULE(pcib, simplebus, tegra_pcib_driver, pcib_devclass, 0, 0);
+static devclass_t pcib_devclass;
+DEFINE_CLASS_1(pcib, tegra_pcib_driver, tegra_pcib_methods,
+ sizeof(struct tegra_pcib_softc), ofw_pci_driver);
+DRIVER_MODULE(pcib, simplebus, tegra_pcib_driver, pcib_devclass,
+ NULL, NULL);
diff --git a/sys/arm/nvidia/tegra_pinmux.c b/sys/arm/nvidia/tegra_pinmux.c
index 0e8102e..c930d30 100644
--- a/sys/arm/nvidia/tegra_pinmux.c
+++ b/sys/arm/nvidia/tegra_pinmux.c
@@ -792,13 +792,8 @@ static device_method_t tegra_pinmux_methods[] = {
DEVMETHOD_END
};
-static driver_t tegra_pinmux_driver = {
- "tegra_pinmux",
- tegra_pinmux_methods,
- sizeof(struct pinmux_softc),
-};
-
static devclass_t tegra_pinmux_devclass;
-
+static DEFINE_CLASS_0(pinmux, tegra_pinmux_driver, tegra_pinmux_methods,
+ sizeof(struct pinmux_softc));
EARLY_DRIVER_MODULE(tegra_pinmux, simplebus, tegra_pinmux_driver,
- tegra_pinmux_devclass, 0, 0, 71);
+ tegra_pinmux_devclass, NULL, NULL, 71);
diff --git a/sys/arm/nvidia/tegra_rtc.c b/sys/arm/nvidia/tegra_rtc.c
index c15ded3..09a7c74 100644
--- a/sys/arm/nvidia/tegra_rtc.c
+++ b/sys/arm/nvidia/tegra_rtc.c
@@ -219,7 +219,7 @@ tegra_rtc_attach(device_t dev)
}
/* OFW resources. */
- rv = clk_get_by_ofw_index(dev, 0, &sc->clk);
+ rv = clk_get_by_ofw_index(dev, 0, 0, &sc->clk);
if (rv != 0) {
device_printf(dev, "Cannot get i2c clock: %d\n", rv);
goto fail;
@@ -297,7 +297,8 @@ static device_method_t tegra_rtc_methods[] = {
DEVMETHOD_END
};
-DEFINE_CLASS_0(tegra_rtc, tegra_rtc_driver, tegra_rtc_methods,
- sizeof(struct tegra_rtc_softc));
static devclass_t tegra_rtc_devclass;
-DRIVER_MODULE(tegra_rtc, simplebus, tegra_rtc_driver, tegra_rtc_devclass, 0, 0);
+static DEFINE_CLASS_0(rtc, tegra_rtc_driver, tegra_rtc_methods,
+ sizeof(struct tegra_rtc_softc));
+DRIVER_MODULE(tegra_rtc, simplebus, tegra_rtc_driver, tegra_rtc_devclass,
+ NULL, NULL);
diff --git a/sys/arm/nvidia/tegra_sdhci.c b/sys/arm/nvidia/tegra_sdhci.c
index d01f1ad..07c0fa8 100644
--- a/sys/arm/nvidia/tegra_sdhci.c
+++ b/sys/arm/nvidia/tegra_sdhci.c
@@ -289,7 +289,7 @@ tegra_sdhci_attach(device_t dev)
goto fail;
}
- rv = hwreset_get_by_ofw_name(sc->dev, "sdhci", &sc->reset);
+ rv = hwreset_get_by_ofw_name(sc->dev, 0, "sdhci", &sc->reset);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'sdhci' reset\n");
goto fail;
@@ -304,14 +304,14 @@ tegra_sdhci_attach(device_t dev)
gpio_pin_get_by_ofw_property(sc->dev, node, "power-gpios", &sc->gpio_power);
gpio_pin_get_by_ofw_property(sc->dev, node, "wp-gpios", &sc->gpio_wp);
- rv = clk_get_by_ofw_index(dev, 0, &sc->clk);
+ rv = clk_get_by_ofw_index(dev, 0, 0, &sc->clk);
if (rv != 0) {
device_printf(dev, "Cannot get clock\n");
goto fail;
}
- rv = clk_get_by_ofw_index(dev, 0, &sc->clk);
+ rv = clk_get_by_ofw_index(dev, 0, 0, &sc->clk);
if (rv != 0) {
device_printf(dev, "Cannot get clock\n");
goto fail;
@@ -448,18 +448,14 @@ static device_method_t tegra_sdhci_methods[] = {
DEVMETHOD(sdhci_write_4, tegra_sdhci_write_4),
DEVMETHOD(sdhci_write_multi_4, tegra_sdhci_write_multi_4),
- { 0, 0 }
+ DEVMETHOD_END
};
static devclass_t tegra_sdhci_devclass;
-
-static driver_t tegra_sdhci_driver = {
- "sdhci_tegra",
- tegra_sdhci_methods,
- sizeof(struct tegra_sdhci_softc),
-};
-
+static DEFINE_CLASS_0(sdhci, tegra_sdhci_driver, tegra_sdhci_methods,
+ sizeof(struct tegra_sdhci_softc));
DRIVER_MODULE(sdhci_tegra, simplebus, tegra_sdhci_driver, tegra_sdhci_devclass,
- 0, 0);
+ NULL, NULL);
MODULE_DEPEND(sdhci_tegra, sdhci, 1, 1, 1);
-DRIVER_MODULE(mmc, sdhci_tegra, mmc_driver, mmc_devclass, NULL, NULL);
+DRIVER_MODULE(mmc, sdhci, mmc_driver, mmc_devclass, NULL, NULL);
+MODULE_DEPEND(sdhci_tegra, mmc, 1, 1, 1);
diff --git a/sys/arm/nvidia/tegra_soctherm.c b/sys/arm/nvidia/tegra_soctherm.c
index 3102173..6ab77ec 100644
--- a/sys/arm/nvidia/tegra_soctherm.c
+++ b/sys/arm/nvidia/tegra_soctherm.c
@@ -579,17 +579,17 @@ soctherm_attach(device_t dev)
*/
/* OWF resources */
- rv = hwreset_get_by_ofw_name(dev, "soctherm", &sc->reset);
+ rv = hwreset_get_by_ofw_name(dev, 0, "soctherm", &sc->reset);
if (rv != 0) {
device_printf(dev, "Cannot get fuse reset\n");
goto fail;
}
- rv = clk_get_by_ofw_name(dev, "tsensor", &sc->tsensor_clk);
+ rv = clk_get_by_ofw_name(dev, 0, "tsensor", &sc->tsensor_clk);
if (rv != 0) {
device_printf(dev, "Cannot get 'tsensor' clock: %d\n", rv);
goto fail;
}
- rv = clk_get_by_ofw_name(dev, "soctherm", &sc->soctherm_clk);
+ rv = clk_get_by_ofw_name(dev, 0, "soctherm", &sc->soctherm_clk);
if (rv != 0) {
device_printf(dev, "Cannot get 'soctherm' clock: %d\n", rv);
goto fail;
@@ -690,7 +690,7 @@ static device_method_t tegra_soctherm_methods[] = {
};
static devclass_t tegra_soctherm_devclass;
-DEFINE_CLASS_0(tegra_soctherm, tegra_soctherm_driver, tegra_soctherm_methods,
+static DEFINE_CLASS_0(soctherm, tegra_soctherm_driver, tegra_soctherm_methods,
sizeof(struct soctherm_softc));
EARLY_DRIVER_MODULE(tegra_soctherm, simplebus, tegra_soctherm_driver,
-tegra_soctherm_devclass, 0, 0, 79);
+ tegra_soctherm_devclass, NULL, NULL, 79);
diff --git a/sys/arm/nvidia/tegra_uart.c b/sys/arm/nvidia/tegra_uart.c
index 86972f0..c70303f 100644
--- a/sys/arm/nvidia/tegra_uart.c
+++ b/sys/arm/nvidia/tegra_uart.c
@@ -189,7 +189,7 @@ tegra_uart_probe(device_t dev)
return (ENXIO);
sc->ns8250_base.base.sc_class = (struct uart_class *)cd->ocd_data;
- rv = hwreset_get_by_ofw_name(dev, "serial", &sc->reset);
+ rv = hwreset_get_by_ofw_name(dev, 0, "serial", &sc->reset);
if (rv != 0) {
device_printf(dev, "Cannot get 'serial' reset\n");
return (ENXIO);
@@ -202,7 +202,7 @@ tegra_uart_probe(device_t dev)
node = ofw_bus_get_node(dev);
shift = uart_fdt_get_shift1(node);
- rv = clk_get_by_ofw_index(dev, 0, &sc->clk);
+ rv = clk_get_by_ofw_index(dev, 0, 0, &sc->clk);
if (rv != 0) {
device_printf(dev, "Cannot get UART clock: %d\n", rv);
return (ENXIO);
diff --git a/sys/arm/nvidia/tegra_usbphy.c b/sys/arm/nvidia/tegra_usbphy.c
index 5446068..d1c6eeb 100644
--- a/sys/arm/nvidia/tegra_usbphy.c
+++ b/sys/arm/nvidia/tegra_usbphy.c
@@ -726,28 +726,28 @@ usbphy_attach(device_t dev)
node = ofw_bus_get_node(dev);
- rv = hwreset_get_by_ofw_name(sc->dev, "usb", &sc->reset_usb);
+ rv = hwreset_get_by_ofw_name(sc->dev, 0, "usb", &sc->reset_usb);
if (rv != 0) {
device_printf(dev, "Cannot get 'usb' reset\n");
return (ENXIO);
}
- rv = hwreset_get_by_ofw_name(sc->dev, "utmi-pads", &sc->reset_pads);
+ rv = hwreset_get_by_ofw_name(sc->dev, 0, "utmi-pads", &sc->reset_pads);
if (rv != 0) {
device_printf(dev, "Cannot get 'utmi-pads' reset\n");
return (ENXIO);
}
- rv = clk_get_by_ofw_name(sc->dev, "reg", &sc->clk_reg);
+ rv = clk_get_by_ofw_name(sc->dev, 0, "reg", &sc->clk_reg);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'reg' clock\n");
return (ENXIO);
}
- rv = clk_get_by_ofw_name(sc->dev, "pll_u", &sc->clk_pllu);
+ rv = clk_get_by_ofw_name(sc->dev, 0, "pll_u", &sc->clk_pllu);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'pll_u' clock\n");
return (ENXIO);
}
- rv = clk_get_by_ofw_name(sc->dev, "utmi-pads", &sc->clk_pads);
+ rv = clk_get_by_ofw_name(sc->dev, 0, "utmi-pads", &sc->clk_pads);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'utmi-pads' clock\n");
return (ENXIO);
@@ -788,7 +788,7 @@ usbphy_attach(device_t dev)
return rv;
if (OF_hasprop(node, "vbus-supply")) {
- rv = regulator_get_by_ofw_property(sc->dev, "vbus-supply",
+ rv = regulator_get_by_ofw_property(sc->dev, 0, "vbus-supply",
&sc->supply_vbus);
if (rv != 0) {
device_printf(sc->dev,
@@ -827,13 +827,8 @@ static device_method_t tegra_usbphy_methods[] = {
DEVMETHOD_END
};
-static driver_t tegra_usbphy_driver = {
- "tegra_usbphy",
- tegra_usbphy_methods,
- sizeof(struct usbphy_softc),
-};
-
static devclass_t tegra_usbphy_devclass;
-
+static DEFINE_CLASS_0(usbphy, tegra_usbphy_driver, tegra_usbphy_methods,
+ sizeof(struct usbphy_softc));
EARLY_DRIVER_MODULE(tegra_usbphy, simplebus, tegra_usbphy_driver,
- tegra_usbphy_devclass, 0, 0, 79);
+ tegra_usbphy_devclass, NULL, NULL, 79);
diff --git a/sys/arm/rockchip/rk30xx_gpio.c b/sys/arm/rockchip/rk30xx_gpio.c
index 2c95fb9..609eb6a 100644
--- a/sys/arm/rockchip/rk30xx_gpio.c
+++ b/sys/arm/rockchip/rk30xx_gpio.c
@@ -41,8 +41,6 @@ __FBSDID("$FreeBSD$");
#include <sys/gpio.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
diff --git a/sys/arm/rockchip/rk30xx_wdog.c b/sys/arm/rockchip/rk30xx_wdog.c
index 5a15331..32ef5bd 100644
--- a/sys/arm/rockchip/rk30xx_wdog.c
+++ b/sys/arm/rockchip/rk30xx_wdog.c
@@ -42,7 +42,6 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus_subr.h>
#include <machine/bus.h>
-#include <machine/cpufunc.h>
#include <machine/machdep.h>
#include <machine/fdt.h>
diff --git a/sys/arm/samsung/exynos/exynos5_xhci.c b/sys/arm/samsung/exynos/exynos5_xhci.c
index 2accd4c..dbb8d3c 100644
--- a/sys/arm/samsung/exynos/exynos5_xhci.c
+++ b/sys/arm/samsung/exynos/exynos5_xhci.c
@@ -288,14 +288,8 @@ static int
exynos_xhci_detach(device_t dev)
{
struct exynos_xhci_softc *esc = device_get_softc(dev);
- device_t bdev;
int err;
- if (esc->base.sc_bus.bdev != NULL) {
- bdev = esc->base.sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
/* During module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/arm/ti/am335x/am335x_gpio.c b/sys/arm/ti/am335x/am335x_gpio.c
index 74bcf16..63fc544 100644
--- a/sys/arm/ti/am335x/am335x_gpio.c
+++ b/sys/arm/ti/am335x/am335x_gpio.c
@@ -39,8 +39,6 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <sys/gpio.h>
diff --git a/sys/arm/ti/am335x/am335x_lcd_syscons.c b/sys/arm/ti/am335x/am335x_lcd_syscons.c
index 12b6366..2cbf2fc 100644
--- a/sys/arm/ti/am335x/am335x_lcd_syscons.c
+++ b/sys/arm/ti/am335x/am335x_lcd_syscons.c
@@ -44,8 +44,6 @@ __FBSDID("$FreeBSD$");
#include <sys/kdb.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
diff --git a/sys/arm/ti/am335x/am335x_musb.c b/sys/arm/ti/am335x/am335x_musb.c
index 4dc96c3..c168493 100644
--- a/sys/arm/ti/am335x/am335x_musb.c
+++ b/sys/arm/ti/am335x/am335x_musb.c
@@ -366,14 +366,10 @@ static int
musbotg_detach(device_t dev)
{
struct musbotg_super_softc *sc = device_get_softc(dev);
- device_t bdev;
int err;
- if (sc->sc_otg.sc_bus.bdev) {
- bdev = sc->sc_otg.sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
+ /* during module unload there are lots of children leftover */
+ device_delete_children(dev);
if (sc->sc_otg.sc_irq_res && sc->sc_otg.sc_intr_hdl) {
/*
@@ -397,9 +393,6 @@ musbotg_detach(device_t dev)
bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irq_rid,
sc->sc_otg.sc_irq_res);
- /* during module unload there are lots of children leftover */
- device_delete_children(dev);
-
return (0);
}
diff --git a/sys/arm/ti/am335x/am335x_scm_padconf.c b/sys/arm/ti/am335x/am335x_scm_padconf.c
index a95c8cb..ebb65dd 100644
--- a/sys/arm/ti/am335x/am335x_scm_padconf.c
+++ b/sys/arm/ti/am335x/am335x_scm_padconf.c
@@ -38,8 +38,6 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <sys/gpio.h>
diff --git a/sys/arm/ti/omap4/omap4_prcm_clks.c b/sys/arm/ti/omap4/omap4_prcm_clks.c
index e17fe3d..3aa10f6 100644
--- a/sys/arm/ti/omap4/omap4_prcm_clks.c
+++ b/sys/arm/ti/omap4/omap4_prcm_clks.c
@@ -41,8 +41,6 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
diff --git a/sys/arm/ti/omap4/omap4_wugen.c b/sys/arm/ti/omap4/omap4_wugen.c
index 8909126..1a420f9 100644
--- a/sys/arm/ti/omap4/omap4_wugen.c
+++ b/sys/arm/ti/omap4/omap4_wugen.c
@@ -57,12 +57,12 @@ struct omap4_wugen_sc {
};
static int
-omap4_wugen_alloc_intr(device_t dev, struct intr_irqsrc *isrc,
+omap4_wugen_activate_intr(device_t dev, struct intr_irqsrc *isrc,
struct resource *res, struct intr_map_data *data)
{
struct omap4_wugen_sc *sc = device_get_softc(dev);
- return (PIC_ALLOC_INTR(sc->sc_parent, isrc, res, data));
+ return (PIC_ACTIVATE_INTR(sc->sc_parent, isrc, res, data));
}
static void
@@ -91,12 +91,12 @@ omap4_wugen_map_intr(device_t dev, struct intr_map_data *data,
}
static int
-omap4_wugen_release_intr(device_t dev, struct intr_irqsrc *isrc,
+omap4_wugen_deactivate_intr(device_t dev, struct intr_irqsrc *isrc,
struct resource *res, struct intr_map_data *data)
{
struct omap4_wugen_sc *sc = device_get_softc(dev);
- return (PIC_RELEASE_INTR(sc->sc_parent, isrc, res, data));
+ return (PIC_DEACTIVATE_INTR(sc->sc_parent, isrc, res, data));
}
static int
@@ -227,11 +227,11 @@ static device_method_t omap4_wugen_methods[] = {
DEVMETHOD(device_detach, omap4_wugen_detach),
/* Interrupt controller interface */
- DEVMETHOD(pic_alloc_intr, omap4_wugen_alloc_intr),
+ DEVMETHOD(pic_activate_intr, omap4_wugen_activate_intr),
DEVMETHOD(pic_disable_intr, omap4_wugen_disable_intr),
DEVMETHOD(pic_enable_intr, omap4_wugen_enable_intr),
DEVMETHOD(pic_map_intr, omap4_wugen_map_intr),
- DEVMETHOD(pic_release_intr, omap4_wugen_release_intr),
+ DEVMETHOD(pic_deactivate_intr, omap4_wugen_deactivate_intr),
DEVMETHOD(pic_setup_intr, omap4_wugen_setup_intr),
DEVMETHOD(pic_teardown_intr, omap4_wugen_teardown_intr),
DEVMETHOD(pic_pre_ithread, omap4_wugen_pre_ithread),
diff --git a/sys/arm/ti/ti_cpuid.c b/sys/arm/ti/ti_cpuid.c
index b2f0f65..7048efe 100644
--- a/sys/arm/ti/ti_cpuid.c
+++ b/sys/arm/ti/ti_cpuid.c
@@ -40,8 +40,6 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/fdt.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
diff --git a/sys/arm/ti/ti_pinmux.c b/sys/arm/ti/ti_pinmux.c
index 0eeedbe..d3daf76 100644
--- a/sys/arm/ti/ti_pinmux.c
+++ b/sys/arm/ti/ti_pinmux.c
@@ -47,8 +47,6 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <dev/fdt/fdt_common.h>
diff --git a/sys/arm/ti/ti_prcm.c b/sys/arm/ti/ti_prcm.c
index d742d07..e049cbb 100644
--- a/sys/arm/ti/ti_prcm.c
+++ b/sys/arm/ti/ti_prcm.c
@@ -52,8 +52,6 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
diff --git a/sys/arm/ti/ti_scm.c b/sys/arm/ti/ti_scm.c
index 5608265..0752a21 100644
--- a/sys/arm/ti/ti_scm.c
+++ b/sys/arm/ti/ti_scm.c
@@ -59,8 +59,6 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <dev/fdt/fdt_common.h>
diff --git a/sys/arm/ti/twl/twl.c b/sys/arm/ti/twl/twl.c
index 387ca1b..8cafcf4 100644
--- a/sys/arm/ti/twl/twl.c
+++ b/sys/arm/ti/twl/twl.c
@@ -57,8 +57,6 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
diff --git a/sys/arm/ti/twl/twl_clks.c b/sys/arm/ti/twl/twl_clks.c
index a042e43..33efa0a 100644
--- a/sys/arm/ti/twl/twl_clks.c
+++ b/sys/arm/ti/twl/twl_clks.c
@@ -62,8 +62,6 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
diff --git a/sys/arm/ti/twl/twl_vreg.c b/sys/arm/ti/twl/twl_vreg.c
index accbf49..6662c5d 100644
--- a/sys/arm/ti/twl/twl_vreg.c
+++ b/sys/arm/ti/twl/twl_vreg.c
@@ -63,8 +63,6 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
diff --git a/sys/arm/ti/usb/omap_ehci.c b/sys/arm/ti/usb/omap_ehci.c
index 7ce957f..f7e2057 100644
--- a/sys/arm/ti/usb/omap_ehci.c
+++ b/sys/arm/ti/usb/omap_ehci.c
@@ -392,15 +392,8 @@ omap_ehci_detach(device_t dev)
{
struct omap_ehci_softc *isc = device_get_softc(dev);
ehci_softc_t *sc = &isc->base;
- device_t bdev;
int err;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
-
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/arm/xilinx/zy7_ehci.c b/sys/arm/xilinx/zy7_ehci.c
index f03c131..6468faa 100644
--- a/sys/arm/xilinx/zy7_ehci.c
+++ b/sys/arm/xilinx/zy7_ehci.c
@@ -323,20 +323,17 @@ zy7_ehci_detach(device_t dev)
{
ehci_softc_t *sc = device_get_softc(dev);
+ /* during module unload there are lots of children leftover */
+ device_delete_children(dev);
+
sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
- if (device_is_attached(dev))
- bus_generic_detach(dev);
-
if (sc->sc_irq_res && sc->sc_intr_hdl)
/* call ehci_detach() after ehci_init() called after
* successful bus_setup_intr().
*/
ehci_detach(sc);
- if (sc->sc_bus.bdev) {
- device_detach(sc->sc_bus.bdev);
- device_delete_child(dev, sc->sc_bus.bdev);
- }
+
if (sc->sc_irq_res) {
if (sc->sc_intr_hdl != NULL)
bus_teardown_intr(dev, sc->sc_irq_res,
diff --git a/sys/arm/xscale/i8134x/i80321_timer.c b/sys/arm/xscale/i8134x/i80321_timer.c
index ea15d92..f67c3190 100644
--- a/sys/arm/xscale/i8134x/i80321_timer.c
+++ b/sys/arm/xscale/i8134x/i80321_timer.c
@@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <machine/armreg.h>
#include <machine/bus.h>
#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/frame.h>
#include <machine/resource.h>
#include <machine/intr.h>
diff --git a/sys/arm/xscale/i8134x/i80321_wdog.c b/sys/arm/xscale/i8134x/i80321_wdog.c
index c11c78a..72f0fd8 100644
--- a/sys/arm/xscale/i8134x/i80321_wdog.c
+++ b/sys/arm/xscale/i8134x/i80321_wdog.c
@@ -51,7 +51,6 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <machine/bus.h>
-#include <machine/cpufunc.h>
#include <machine/machdep.h>
#include <arm/xscale/i8134x/i80321reg.h>
diff --git a/sys/arm/xscale/ixp425/avila_ata.c b/sys/arm/xscale/ixp425/avila_ata.c
index d181286..2000a4f 100644
--- a/sys/arm/xscale/ixp425/avila_ata.c
+++ b/sys/arm/xscale/ixp425/avila_ata.c
@@ -53,8 +53,6 @@ __FBSDID("$FreeBSD$");
#include <sys/endian.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <arm/xscale/ixp425/ixp425reg.h>
diff --git a/sys/arm/xscale/ixp425/ixp425_intr.h b/sys/arm/xscale/ixp425/ixp425_intr.h
index b7724ff..6c2e650 100644
--- a/sys/arm/xscale/ixp425/ixp425_intr.h
+++ b/sys/arm/xscale/ixp425/ixp425_intr.h
@@ -46,7 +46,6 @@
#ifndef _LOCORE
#include <machine/armreg.h>
-#include <machine/cpufunc.h>
#include <arm/xscale/ixp425/ixp425reg.h>
diff --git a/sys/arm/xscale/ixp425/ixp425_npe.c b/sys/arm/xscale/ixp425/ixp425_npe.c
index 95facb4..720b0f4 100644
--- a/sys/arm/xscale/ixp425/ixp425_npe.c
+++ b/sys/arm/xscale/ixp425/ixp425_npe.c
@@ -92,8 +92,6 @@ __FBSDID("$FreeBSD$");
#include <sys/firmware.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <arm/xscale/ixp425/ixp425reg.h>
diff --git a/sys/arm/xscale/ixp425/ixp425_qmgr.c b/sys/arm/xscale/ixp425/ixp425_qmgr.c
index d6db260..16c2c25 100644
--- a/sys/arm/xscale/ixp425/ixp425_qmgr.c
+++ b/sys/arm/xscale/ixp425/ixp425_qmgr.c
@@ -84,8 +84,6 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <arm/xscale/ixp425/ixp425reg.h>
diff --git a/sys/arm/xscale/ixp425/ixp425_timer.c b/sys/arm/xscale/ixp425/ixp425_timer.c
index 6357c13..e6b6ecd 100644
--- a/sys/arm/xscale/ixp425/ixp425_timer.c
+++ b/sys/arm/xscale/ixp425/ixp425_timer.c
@@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$");
#include <machine/armreg.h>
#include <machine/bus.h>
#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/frame.h>
#include <machine/resource.h>
#include <machine/intr.h>
diff --git a/sys/arm/xscale/ixp425/ixp425_wdog.c b/sys/arm/xscale/ixp425/ixp425_wdog.c
index 3e64fb3..c3111d2 100644
--- a/sys/arm/xscale/ixp425/ixp425_wdog.c
+++ b/sys/arm/xscale/ixp425/ixp425_wdog.c
@@ -38,8 +38,6 @@ __FBSDID("$FreeBSD$");
#include <sys/watchdog.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
diff --git a/sys/arm64/arm64/nexus.c b/sys/arm64/arm64/nexus.c
index 2cd36ad..3e071cb 100644
--- a/sys/arm64/arm64/nexus.c
+++ b/sys/arm64/arm64/nexus.c
@@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
#include <machine/intr.h>
#ifdef FDT
+#include <dev/ofw/ofw_bus_subr.h>
#include <dev/ofw/openfirm.h>
#include "ofw_bus_if.h"
#endif
@@ -344,6 +345,12 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid,
rman_set_bustag(r, &memmap_bus);
rman_set_virtual(r, (void *)vaddr);
rman_set_bushandle(r, vaddr);
+ } else if (type == SYS_RES_IRQ) {
+ err = intr_activate_irq(child, r);
+ if (err != 0) {
+ rman_deactivate_resource(r);
+ return (err);
+ }
}
return (0);
}
@@ -377,13 +384,17 @@ nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
bus_size_t psize;
bus_space_handle_t vaddr;
- psize = (bus_size_t)rman_get_size(r);
- vaddr = rman_get_bushandle(r);
+ if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+ psize = (bus_size_t)rman_get_size(r);
+ vaddr = rman_get_bushandle(r);
- if (vaddr != 0) {
- bus_space_unmap(&memmap_bus, vaddr, psize);
- rman_set_virtual(r, NULL);
- rman_set_bushandle(r, 0);
+ if (vaddr != 0) {
+ bus_space_unmap(&memmap_bus, vaddr, psize);
+ rman_set_virtual(r, NULL);
+ rman_set_bushandle(r, 0);
+ }
+ } else if (type == SYS_RES_IRQ) {
+ intr_deactivate_irq(child, r);
}
return (rman_deactivate_resource(r));
@@ -430,8 +441,18 @@ static int
nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells,
pcell_t *intr)
{
-
- return (INTR_IRQ_INVALID);
+ u_int irq;
+ struct intr_map_data_fdt *fdt_data;
+ size_t len;
+
+ len = sizeof(*fdt_data) + icells * sizeof(pcell_t);
+ fdt_data = (struct intr_map_data_fdt *)intr_alloc_map_data(
+ INTR_MAP_DATA_FDT, len, M_WAITOK | M_ZERO);
+ fdt_data->iparent = iparent;
+ fdt_data->ncells = icells;
+ memcpy(fdt_data->cells, intr, icells * sizeof(pcell_t));
+ irq = intr_map_irq(NULL, iparent, (struct intr_map_data *)fdt_data);
+ return (irq);
}
#endif
diff --git a/sys/boot/fdt/dts/arm/bananapi.dts b/sys/boot/fdt/dts/arm/bananapi.dts
index f63884b..23a9ef1 100644
--- a/sys/boot/fdt/dts/arm/bananapi.dts
+++ b/sys/boot/fdt/dts/arm/bananapi.dts
@@ -41,7 +41,3 @@
};
};
};
-
-&mmc0_pins_a {
- allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
-};
diff --git a/sys/boot/kshim/bsd_kernel.c b/sys/boot/kshim/bsd_kernel.c
index 36a6d82..c94b755 100644
--- a/sys/boot/kshim/bsd_kernel.c
+++ b/sys/boot/kshim/bsd_kernel.c
@@ -817,8 +817,12 @@ device_delete_child(device_t dev, device_t child)
int error = 0;
device_t grandchild;
- /* remove children first */
+ /* detach parent before deleting children, if any */
+ error = device_detach(child);
+ if (error)
+ goto done;
+ /* remove children second */
while ((grandchild = TAILQ_FIRST(&child->dev_children))) {
error = device_delete_child(child, grandchild);
if (error) {
@@ -827,11 +831,6 @@ device_delete_child(device_t dev, device_t child)
}
}
- error = device_detach(child);
-
- if (error)
- goto done;
-
devclass_delete_device(child->dev_module, child);
if (dev != NULL) {
diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c
index 091b96f..942a6c3 100644
--- a/sys/cam/cam_periph.c
+++ b/sys/cam/cam_periph.c
@@ -975,16 +975,6 @@ cam_periph_unmapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo)
PRELE(curproc);
}
-void
-cam_periph_ccbwait(union ccb *ccb)
-{
-
- if ((ccb->ccb_h.pinfo.index != CAM_UNQUEUED_INDEX)
- || ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG))
- xpt_path_sleep(ccb->ccb_h.path, &ccb->ccb_h.cbfcnp, PRIBIO,
- "cbwait", 0);
-}
-
int
cam_periph_ioctl(struct cam_periph *periph, u_long cmd, caddr_t addr,
int (*error_routine)(union ccb *ccb,
@@ -1048,13 +1038,38 @@ cam_periph_ioctl(struct cam_periph *periph, u_long cmd, caddr_t addr,
}
static void
+cam_periph_done_panic(struct cam_periph *periph, union ccb *done_ccb)
+{
+
+ panic("%s: already done with ccb %p", __func__, done_ccb);
+}
+
+static void
cam_periph_done(struct cam_periph *periph, union ccb *done_ccb)
{
/* Caller will release the CCB */
+ xpt_path_assert(done_ccb->ccb_h.path, MA_OWNED);
+ done_ccb->ccb_h.cbfcnp = cam_periph_done_panic;
wakeup(&done_ccb->ccb_h.cbfcnp);
}
+static void
+cam_periph_ccbwait(union ccb *ccb)
+{
+
+ if ((ccb->ccb_h.func_code & XPT_FC_QUEUED) != 0) {
+ while (ccb->ccb_h.cbfcnp != cam_periph_done_panic)
+ xpt_path_sleep(ccb->ccb_h.path, &ccb->ccb_h.cbfcnp,
+ PRIBIO, "cbwait", 0);
+ }
+ KASSERT(ccb->ccb_h.pinfo.index == CAM_UNQUEUED_INDEX &&
+ (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG,
+ ("%s: proceeding with incomplete ccb: ccb=%p, func_code=%#x, "
+ "status=%#x, index=%d", __func__, ccb, ccb->ccb_h.func_code,
+ ccb->ccb_h.status, ccb->ccb_h.pinfo.index));
+}
+
int
cam_periph_runccb(union ccb *ccb,
int (*error_routine)(union ccb *ccb,
@@ -1069,6 +1084,9 @@ cam_periph_runccb(union ccb *ccb,
starttime = NULL;
xpt_path_assert(ccb->ccb_h.path, MA_OWNED);
+ KASSERT((ccb->ccb_h.flags & CAM_UNLOCKED) == 0,
+ ("%s: ccb=%p, func_code=%#x, flags=%#x", __func__, ccb,
+ ccb->ccb_h.func_code, ccb->ccb_h.flags));
/*
* If the user has supplied a stats structure, and if we understand
@@ -1088,9 +1106,10 @@ cam_periph_runccb(union ccb *ccb,
cam_periph_ccbwait(ccb);
if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
error = 0;
- else if (error_routine != NULL)
+ else if (error_routine != NULL) {
+ ccb->ccb_h.cbfcnp = cam_periph_done;
error = (*error_routine)(ccb, camflags, sense_flags);
- else
+ } else
error = 0;
} while (error == ERESTART);
diff --git a/sys/cam/cam_periph.h b/sys/cam/cam_periph.h
index e28d5b1..d5a74a5 100644
--- a/sys/cam/cam_periph.h
+++ b/sys/cam/cam_periph.h
@@ -166,7 +166,6 @@ void cam_periph_unmapmem(union ccb *ccb,
struct cam_periph_map_info *mapinfo);
union ccb *cam_periph_getccb(struct cam_periph *periph,
u_int32_t priority);
-void cam_periph_ccbwait(union ccb *ccb);
int cam_periph_runccb(union ccb *ccb,
int (*error_routine)(union ccb *ccb,
cam_flags camflags,
diff --git a/sys/cam/cam_queue.c b/sys/cam/cam_queue.c
index 3959c3d..059dd63 100644
--- a/sys/cam/cam_queue.c
+++ b/sys/cam/cam_queue.c
@@ -176,8 +176,11 @@ camq_remove(struct camq *queue, int index)
{
cam_pinfo *removed_entry;
- if (index == 0 || index > queue->entries)
- return (NULL);
+ if (index <= 0 || index > queue->entries)
+ panic("%s: Attempt to remove out-of-bounds index %d "
+ "from queue %p of size %d", __func__, index, queue,
+ queue->entries);
+
removed_entry = queue->queue_array[index];
if (queue->entries != index) {
queue->queue_array[index] = queue->queue_array[queue->entries];
diff --git a/sys/cam/cam_queue.h b/sys/cam/cam_queue.h
index 33f6b1d..b15998b 100644
--- a/sys/cam/cam_queue.h
+++ b/sys/cam/cam_queue.h
@@ -197,6 +197,11 @@ cam_ccbq_insert_ccb(struct cam_ccbq *ccbq, union ccb *new_ccb)
struct ccb_hdr *old_ccb;
struct camq *queue = &ccbq->queue;
+ KASSERT((new_ccb->ccb_h.func_code & XPT_FC_QUEUED) != 0 &&
+ (new_ccb->ccb_h.func_code & XPT_FC_USER_CCB) == 0,
+ ("%s: Cannot queue ccb %p func_code %#x", __func__, new_ccb,
+ new_ccb->ccb_h.func_code));
+
/*
* If queue is already full, try to resize.
* If resize fail, push CCB with lowest priority out to the TAILQ.
@@ -218,6 +223,7 @@ cam_ccbq_remove_ccb(struct cam_ccbq *ccbq, union ccb *ccb)
{
struct ccb_hdr *cccb, *bccb;
struct camq *queue = &ccbq->queue;
+ cam_pinfo *removed_entry __unused;
/* If the CCB is on the TAILQ, remove it from there. */
if (ccb->ccb_h.pinfo.index == CAM_EXTRAQ_INDEX) {
@@ -228,7 +234,10 @@ cam_ccbq_remove_ccb(struct cam_ccbq *ccbq, union ccb *ccb)
return;
}
- camq_remove(queue, ccb->ccb_h.pinfo.index);
+ removed_entry = camq_remove(queue, ccb->ccb_h.pinfo.index);
+ KASSERT(removed_entry == &ccb->ccb_h.pinfo,
+ ("%s: Removed wrong entry from queue (%p != %p)", __func__,
+ removed_entry, &ccb->ccb_h.pinfo));
/*
* If there are some CCBs on TAILQ, find the best one and move it
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zrlock.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zrlock.c
index 7f6beee..ec333e5 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zrlock.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zrlock.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015 by Delphix. All rights reserved.
+ * Copyright 2016 The MathWorks, Inc. All rights reserved.
*/
/*
@@ -71,37 +72,32 @@ zrl_destroy(zrlock_t *zrl)
void
zrl_add_impl(zrlock_t *zrl, const char *zc)
{
- uint32_t n = (uint32_t)zrl->zr_refcount;
-
- while (n != ZRL_LOCKED) {
- uint32_t cas = atomic_cas_32(
- (uint32_t *)&zrl->zr_refcount, n, n + 1);
- if (cas == n) {
- ASSERT3S((int32_t)n, >=, 0);
+ for (;;) {
+ uint32_t n = (uint32_t)zrl->zr_refcount;
+ while (n != ZRL_LOCKED) {
+ uint32_t cas = atomic_cas_32(
+ (uint32_t *)&zrl->zr_refcount, n, n + 1);
+ if (cas == n) {
+ ASSERT3S((int32_t)n, >=, 0);
#ifdef ZFS_DEBUG
- if (zrl->zr_owner == curthread) {
- DTRACE_PROBE2(zrlock__reentry,
- zrlock_t *, zrl, uint32_t, n);
- }
- zrl->zr_owner = curthread;
- zrl->zr_caller = zc;
+ if (zrl->zr_owner == curthread) {
+ DTRACE_PROBE2(zrlock__reentry,
+ zrlock_t *, zrl, uint32_t, n);
+ }
+ zrl->zr_owner = curthread;
+ zrl->zr_caller = zc;
#endif
- return;
+ return;
+ }
+ n = cas;
}
- n = cas;
- }
- mutex_enter(&zrl->zr_mtx);
- while (zrl->zr_refcount == ZRL_LOCKED) {
- cv_wait(&zrl->zr_cv, &zrl->zr_mtx);
+ mutex_enter(&zrl->zr_mtx);
+ while (zrl->zr_refcount == ZRL_LOCKED) {
+ cv_wait(&zrl->zr_cv, &zrl->zr_mtx);
+ }
+ mutex_exit(&zrl->zr_mtx);
}
- ASSERT3S(zrl->zr_refcount, >=, 0);
- zrl->zr_refcount++;
-#ifdef ZFS_DEBUG
- zrl->zr_owner = curthread;
- zrl->zr_caller = zc;
-#endif
- mutex_exit(&zrl->zr_mtx);
}
void
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
index d0c7a74..832847e 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
@@ -782,8 +782,10 @@ zvol_remove_zv(zvol_state_t *zv)
g_topology_lock();
zvol_geom_destroy(zv);
g_topology_unlock();
- } else if (zv->zv_volmode == ZFS_VOLMODE_DEV)
- destroy_dev(zv->zv_dev);
+ } else if (zv->zv_volmode == ZFS_VOLMODE_DEV) {
+ if (zv->zv_dev != NULL)
+ destroy_dev(zv->zv_dev);
+ }
#endif
avl_destroy(&zv->zv_znode.z_range_avl);
@@ -2973,14 +2975,14 @@ zvol_rename_minor(zvol_state_t *zv, const char *newname)
} else if (zv->zv_volmode == ZFS_VOLMODE_DEV) {
struct make_dev_args args;
- dev = zv->zv_dev;
- ASSERT(dev != NULL);
- zv->zv_dev = NULL;
- destroy_dev(dev);
- if (zv->zv_total_opens > 0) {
- zv->zv_flags &= ~ZVOL_EXCL;
- zv->zv_total_opens = 0;
- zvol_last_close(zv);
+ if ((dev = zv->zv_dev) != NULL) {
+ zv->zv_dev = NULL;
+ destroy_dev(dev);
+ if (zv->zv_total_opens > 0) {
+ zv->zv_flags &= ~ZVOL_EXCL;
+ zv->zv_total_opens = 0;
+ zvol_last_close(zv);
+ }
}
make_dev_args_init(&args);
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index a0dce47..f1bae96 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -218,7 +218,7 @@ linprocfs_docpuinfo(PFS_FILL_ARGS)
char model[128];
uint64_t freq;
size_t size;
- int class, fqmhz, fqkhz;
+ int fqmhz, fqkhz;
int i;
/*
@@ -235,33 +235,6 @@ linprocfs_docpuinfo(PFS_FILL_ARGS)
"3dnowext", "3dnow"
};
- switch (cpu_class) {
-#ifdef __i386__
- case CPUCLASS_286:
- class = 2;
- break;
- case CPUCLASS_386:
- class = 3;
- break;
- case CPUCLASS_486:
- class = 4;
- break;
- case CPUCLASS_586:
- class = 5;
- break;
- case CPUCLASS_686:
- class = 6;
- break;
- default:
- class = 0;
- break;
-#else /* __amd64__ */
- default:
- class = 15;
- break;
-#endif
- }
-
hw_model[0] = CTL_HW;
hw_model[1] = HW_MODEL;
model[0] = '\0';
@@ -286,7 +259,7 @@ linprocfs_docpuinfo(PFS_FILL_ARGS)
#ifdef __i386__
switch (cpu_vendor_id) {
case CPU_VENDOR_AMD:
- if (class < 6)
+ if (cpu_class < CPUCLASS_686)
flags[16] = "fcmov";
break;
case CPU_VENDOR_CYRIX:
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 797b82e..1f6a2c6 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -2534,7 +2534,12 @@ device ismt
device smb
+# SMBus peripheral devices
#
+# jedec_ts Temperature Sensor compliant with JEDEC Standard 21-C
+#
+device jedec_ts
+
# I2C Bus
#
# Philips i2c bus support is provided by the `iicbus' device.
diff --git a/sys/conf/files b/sys/conf/files
index 2dd6406..e1cd48c 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2017,6 +2017,7 @@ dev/ixgbe/ixgbe_dcb_82598.c optional ix inet | ixv inet \
compile-with "${NORMAL_C} -I$S/dev/ixgbe"
dev/ixgbe/ixgbe_dcb_82599.c optional ix inet | ixv inet \
compile-with "${NORMAL_C} -I$S/dev/ixgbe"
+dev/jedec_ts/jedec_ts.c optional jedec_ts smbus
dev/jme/if_jme.c optional jme pci
dev/joy/joy.c optional joy
dev/joy/joy_isa.c optional joy isa
diff --git a/sys/ddb/db_examine.c b/sys/ddb/db_examine.c
index de2bbe4..a1e5a28 100644
--- a/sys/ddb/db_examine.c
+++ b/sys/ddb/db_examine.c
@@ -241,7 +241,7 @@ db_print_loc_and_inst(db_addr_t loc)
db_printsym(loc, DB_STGY_PROC);
if (db_search_symbol(loc, DB_STGY_PROC, &off) != C_DB_SYM_NULL) {
db_printf(":\t");
- (void)db_disasm(loc, true);
+ (void)db_disasm(loc, false);
}
}
diff --git a/sys/ddb/db_expr.c b/sys/ddb/db_expr.c
index db17f36..c206a57 100644
--- a/sys/ddb/db_expr.c
+++ b/sys/ddb/db_expr.c
@@ -57,7 +57,8 @@ db_term(db_expr_t *valuep)
if (!db_value_of_name(db_tok_string, valuep) &&
!db_value_of_name_pcpu(db_tok_string, valuep) &&
!db_value_of_name_vnet(db_tok_string, valuep)) {
- db_error("Symbol not found\n");
+ db_printf("Symbol '%s' not found\n", db_tok_string);
+ db_error(NULL);
/*NOTREACHED*/
}
return (true);
@@ -89,12 +90,14 @@ db_term(db_expr_t *valuep)
}
if (t == tLPAREN) {
if (!db_expression(valuep)) {
- db_error("Syntax error\n");
+ db_printf("Expression syntax error after '%c'\n", '(');
+ db_error(NULL);
/*NOTREACHED*/
}
t = db_read_token();
if (t != tRPAREN) {
- db_error("Syntax error\n");
+ db_printf("Expression syntax error -- expected '%c'\n", ')');
+ db_error(NULL);
/*NOTREACHED*/
}
return (true);
@@ -164,7 +167,9 @@ db_mult_expr(db_expr_t *valuep)
while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH ||
t == tBIT_AND ) {
if (!db_term(&rhs)) {
- db_printf("Expression syntax error after '%c'\n", '!');
+ db_printf("Expression syntax error after '%c'\n",
+ t == tSTAR ? '*' : t == tSLASH ? '/' : t == tPCT ? '%' :
+ t == tHASH ? '#' : '&');
db_error(NULL);
/*NOTREACHED*/
}
@@ -177,7 +182,7 @@ db_mult_expr(db_expr_t *valuep)
break;
default:
if (rhs == 0) {
- db_error("Divide by 0\n");
+ db_error("Division by 0\n");
/*NOTREACHED*/
}
if (t == tSLASH)
@@ -199,7 +204,6 @@ db_add_expr(db_expr_t *valuep)
{
db_expr_t lhs, rhs;
int t;
- char c;
if (!db_mult_expr(&lhs))
return (false);
@@ -207,8 +211,8 @@ db_add_expr(db_expr_t *valuep)
t = db_read_token();
while (t == tPLUS || t == tMINUS || t == tBIT_OR) {
if (!db_mult_expr(&rhs)) {
- c = db_tok_string[0];
- db_printf("Expression syntax error after '%c'\n", c);
+ db_printf("Expression syntax error after '%c'\n",
+ t == tPLUS ? '+' : t == tMINUS ? '-' : '|');
db_error(NULL);
/*NOTREACHED*/
}
@@ -243,11 +247,14 @@ db_shift_expr(db_expr_t *valuep)
t = db_read_token();
while (t == tSHIFT_L || t == tSHIFT_R) {
if (!db_add_expr(&rhs)) {
- db_error("Syntax error\n");
+ db_printf("Expression syntax error after '%s'\n",
+ t == tSHIFT_L ? "<<" : ">>");
+ db_error(NULL);
/*NOTREACHED*/
}
if (rhs < 0) {
- db_error("Negative shift amount\n");
+ db_printf("Negative shift amount %jd\n", (intmax_t)rhs);
+ db_error(NULL);
/*NOTREACHED*/
}
if (t == tSHIFT_L)
@@ -269,7 +276,6 @@ db_logical_relation_expr(
{
db_expr_t lhs, rhs;
int t;
- char op[3];
if (!db_shift_expr(&lhs))
return (false);
@@ -277,11 +283,11 @@ db_logical_relation_expr(
t = db_read_token();
while (t == tLOG_EQ || t == tLOG_NOT_EQ || t == tGREATER ||
t == tGREATER_EQ || t == tLESS || t == tLESS_EQ) {
- op[0] = db_tok_string[0];
- op[1] = db_tok_string[1];
- op[2] = 0;
if (!db_shift_expr(&rhs)) {
- db_printf("Expression syntax error after \"%s\"\n", op);
+ db_printf("Expression syntax error after '%s'\n",
+ t == tLOG_EQ ? "==" : t == tLOG_NOT_EQ ? "!=" :
+ t == tGREATER ? ">" : t == tGREATER_EQ ? ">=" :
+ t == tLESS ? "<" : "<=");
db_error(NULL);
/*NOTREACHED*/
}
diff --git a/sys/ddb/db_main.c b/sys/ddb/db_main.c
index 3345bb6..da6a513 100644
--- a/sys/ddb/db_main.c
+++ b/sys/ddb/db_main.c
@@ -226,10 +226,7 @@ db_trap(int type, int code)
if (cnunavailable())
return (0);
- bkpt = IS_BREAKPOINT_TRAP(type, code);
- watchpt = IS_WATCHPOINT_TRAP(type, code);
-
- if (db_stop_at_pc(&bkpt)) {
+ if (db_stop_at_pc(type, code, &bkpt, &watchpt)) {
if (db_inst_count) {
db_printf("After %d instructions (%d loads, %d stores),\n",
db_inst_count, db_load_count, db_store_count);
diff --git a/sys/ddb/db_run.c b/sys/ddb/db_run.c
index 5250651..4d8d3c7 100644
--- a/sys/ddb/db_run.c
+++ b/sys/ddb/db_run.c
@@ -48,15 +48,15 @@ __FBSDID("$FreeBSD$");
#include <ddb/db_break.h>
#include <ddb/db_access.h>
-static int db_run_mode;
-#define STEP_NONE 0
#define STEP_ONCE 1
#define STEP_RETURN 2
#define STEP_CALLT 3
#define STEP_CONTINUE 4
#define STEP_INVISIBLE 5
#define STEP_COUNT 6
+static int db_run_mode = STEP_CONTINUE;
+static bool db_sstep_multiple;
static bool db_sstep_print;
static int db_loop_count;
static int db_call_depth;
@@ -90,13 +90,14 @@ db_pc_is_singlestep(db_addr_t pc)
#endif
bool
-db_stop_at_pc(bool *is_breakpoint)
+db_stop_at_pc(int type, int code, bool *is_breakpoint, bool *is_watchpoint)
{
db_addr_t pc;
db_breakpoint_t bkpt;
+ *is_breakpoint = IS_BREAKPOINT_TRAP(type, code);
+ *is_watchpoint = IS_WATCHPOINT_TRAP(type, code);
pc = PC_REGS();
-
if (db_pc_is_singlestep(pc))
*is_breakpoint = false;
@@ -125,13 +126,39 @@ db_stop_at_pc(bool *is_breakpoint)
*is_breakpoint = true;
return (true); /* stop here */
}
+ return (false); /* continue the countdown */
} else if (*is_breakpoint) {
#ifdef BKPT_SKIP
BKPT_SKIP;
#endif
}
- *is_breakpoint = false;
+ *is_breakpoint = false; /* might be a breakpoint, but not ours */
+
+ /*
+ * If not stepping, then silently ignore single-step traps
+ * (except for clearing the single-step-flag above).
+ *
+ * If stepping, then abort if the trap type is unexpected.
+ * Breakpoints owned by us are expected and were handled above.
+ * Single-steps are expected and are handled below. All others
+ * are unexpected.
+ *
+ * Only do either of these if the MD layer claims to classify
+ * single-step traps unambiguously (by defining IS_SSTEP_TRAP).
+ * Otherwise, fall through to the bad historical behaviour
+ * given by turning unexpected traps into expected traps: if not
+ * stepping, then expect only breakpoints and stop, and if
+ * stepping, then expect only single-steps and step.
+ */
+#ifdef IS_SSTEP_TRAP
+ if (db_run_mode == STEP_CONTINUE && IS_SSTEP_TRAP(type, code))
+ return (false);
+ if (db_run_mode != STEP_CONTINUE && !IS_SSTEP_TRAP(type, code)) {
+ printf("Stepping aborted\n");
+ return (true);
+ }
+#endif
if (db_run_mode == STEP_INVISIBLE) {
db_run_mode = STEP_CONTINUE;
@@ -184,7 +211,6 @@ db_stop_at_pc(bool *is_breakpoint)
return (false); /* continue */
}
}
- db_run_mode = STEP_NONE;
return (true);
}
@@ -194,6 +220,7 @@ db_restart_at_pc(bool watchpt)
db_addr_t pc = PC_REGS();
if ((db_run_mode == STEP_COUNT) ||
+ ((db_run_mode == STEP_ONCE) && db_sstep_multiple) ||
(db_run_mode == STEP_RETURN) ||
(db_run_mode == STEP_CALLT)) {
/*
@@ -321,6 +348,7 @@ db_single_step_cmd(db_expr_t addr, bool have_addr, db_expr_t count, char *modif)
db_run_mode = STEP_ONCE;
db_loop_count = count;
+ db_sstep_multiple = (count != 1);
db_sstep_print = print;
db_inst_count = 0;
db_load_count = 0;
diff --git a/sys/ddb/ddb.h b/sys/ddb/ddb.h
index a2adcdf..fcf772b 100644
--- a/sys/ddb/ddb.h
+++ b/sys/ddb/ddb.h
@@ -215,7 +215,8 @@ void db_restart_at_pc(bool watchpt);
int db_set_variable(db_expr_t value);
void db_set_watchpoints(void);
void db_skip_to_eol(void);
-bool db_stop_at_pc(bool *is_breakpoint);
+bool db_stop_at_pc(int type, int code, bool *is_breakpoint,
+ bool *is_watchpoint);
#define db_strcpy strcpy
void db_trace_self(void);
int db_trace_thread(struct thread *, int);
diff --git a/sys/dev/acpi_support/atk0110.c b/sys/dev/acpi_support/atk0110.c
index e79a0e0..c2759e6 100644
--- a/sys/dev/acpi_support/atk0110.c
+++ b/sys/dev/acpi_support/atk0110.c
@@ -28,6 +28,7 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/sysctl.h>
+#include <sys/stdint.h>
#include <contrib/dev/acpica/include/acpi.h>
#include <dev/acpica/acpivar.h>
@@ -51,18 +52,23 @@ ACPI_SERIAL_DECL(aibs, "aibs");
#define AIBS_MORE_SENSORS
#define AIBS_VERBOSE
-enum aibs_type {
- AIBS_VOLT,
- AIBS_TEMP,
- AIBS_FAN
-};
+#define AIBS_GROUP_SENSORS 0x06
+
+#define AIBS_SENS_TYPE(x) (((x) >> 16) & 0xff)
+#define AIBS_SENS_TYPE_VOLT 2
+#define AIBS_SENS_TYPE_TEMP 3
+#define AIBS_SENS_TYPE_FAN 4
+
+#define AIBS_SENS_TYPE_VOLT_NAME "volt"
+#define AIBS_SENS_TYPE_VOLT_TEMP "temp"
+#define AIBS_SENS_TYPE_VOLT_FAN "fan"
struct aibs_sensor {
ACPI_INTEGER v;
ACPI_INTEGER i;
ACPI_INTEGER l;
ACPI_INTEGER h;
- enum aibs_type t;
+ int t;
};
struct aibs_softc {
@@ -72,14 +78,23 @@ struct aibs_softc {
struct aibs_sensor *sc_asens_volt;
struct aibs_sensor *sc_asens_temp;
struct aibs_sensor *sc_asens_fan;
+ struct aibs_sensor *sc_asens_all;
+
+ struct sysctl_oid *sc_volt_sysctl;
+ struct sysctl_oid *sc_temp_sysctl;
+ struct sysctl_oid *sc_fan_sysctl;
+
+ bool sc_ggrp_method;
};
static int aibs_probe(device_t);
static int aibs_attach(device_t);
static int aibs_detach(device_t);
static int aibs_sysctl(SYSCTL_HANDLER_ARGS);
+static int aibs_sysctl_ggrp(SYSCTL_HANDLER_ARGS);
-static void aibs_attach_sif(struct aibs_softc *, enum aibs_type);
+static int aibs_attach_ggrp(struct aibs_softc *);
+static int aibs_attach_sif(struct aibs_softc *, int);
static device_method_t aibs_methods[] = {
DEVMETHOD(device_probe, aibs_probe),
@@ -109,54 +124,240 @@ aibs_probe(device_t dev)
{
if (acpi_disabled("aibs") ||
ACPI_ID_PROBE(device_get_parent(dev), dev, aibs_hids) == NULL)
- return ENXIO;
+ return (ENXIO);
device_set_desc(dev, "ASUSTeK AI Booster (ACPI ASOC ATK0110)");
- return 0;
+ return (0);
}
static int
aibs_attach(device_t dev)
{
struct aibs_softc *sc = device_get_softc(dev);
+ int err;
sc->sc_dev = dev;
sc->sc_ah = acpi_get_handle(dev);
- aibs_attach_sif(sc, AIBS_VOLT);
- aibs_attach_sif(sc, AIBS_TEMP);
- aibs_attach_sif(sc, AIBS_FAN);
+ sc->sc_ggrp_method = false;
+ err = aibs_attach_sif(sc, AIBS_SENS_TYPE_VOLT);
+ if (err == 0)
+ err = aibs_attach_sif(sc, AIBS_SENS_TYPE_TEMP);
+ if (err == 0)
+ err = aibs_attach_sif(sc, AIBS_SENS_TYPE_FAN);
+
+ if (err == 0)
+ return (0);
+
+ /* Clean up whatever was allocated earlier. */
+ if (sc->sc_volt_sysctl != NULL)
+ sysctl_remove_oid(sc->sc_volt_sysctl, true, true);
+ if (sc->sc_temp_sysctl != NULL)
+ sysctl_remove_oid(sc->sc_temp_sysctl, true, true);
+ if (sc->sc_fan_sysctl != NULL)
+ sysctl_remove_oid(sc->sc_fan_sysctl, true, true);
+ aibs_detach(dev);
+
+ sc->sc_ggrp_method = true;
+ err = aibs_attach_ggrp(sc);
+ return (err);
+}
+
+static int
+aibs_add_sensor(struct aibs_softc *sc, ACPI_OBJECT *o,
+ struct aibs_sensor* sensor, const char ** descr)
+{
+ int off;
+
+ /*
+ * Packages for the old and new methods are quite
+ * similar except that the new package has two
+ * new (unknown / unused) fields after the name field.
+ */
+ if (sc->sc_ggrp_method)
+ off = 4;
+ else
+ off = 2;
+
+ if (o->Type != ACPI_TYPE_PACKAGE) {
+ device_printf(sc->sc_dev,
+ "sensor object is not a package: %i type\n",
+ o->Type);
+ return (ENXIO);
+ }
+ if (o[0].Package.Count != (off + 3) ||
+ o->Package.Elements[0].Type != ACPI_TYPE_INTEGER ||
+ o->Package.Elements[1].Type != ACPI_TYPE_STRING ||
+ o->Package.Elements[off].Type != ACPI_TYPE_INTEGER ||
+ o->Package.Elements[off + 1].Type != ACPI_TYPE_INTEGER ||
+ o->Package.Elements[off + 2].Type != ACPI_TYPE_INTEGER) {
+ device_printf(sc->sc_dev, "unexpected package content\n");
+ return (ENXIO);
+ }
- return 0;
+ sensor->i = o->Package.Elements[0].Integer.Value;
+ *descr = o->Package.Elements[1].String.Pointer;
+ sensor->l = o->Package.Elements[off].Integer.Value;
+ sensor->h = o->Package.Elements[off + 1].Integer.Value;
+ /* For the new method the second value is a range size. */
+ if (sc->sc_ggrp_method)
+ sensor->h += sensor->l;
+ sensor->t = AIBS_SENS_TYPE(sensor->i);
+
+ switch (sensor->t) {
+ case AIBS_SENS_TYPE_VOLT:
+ case AIBS_SENS_TYPE_TEMP:
+ case AIBS_SENS_TYPE_FAN:
+ return (0);
+ default:
+ device_printf(sc->sc_dev, "unknown sensor type 0x%x",
+ sensor->t);
+ return (ENXIO);
+ }
}
static void
-aibs_attach_sif(struct aibs_softc *sc, enum aibs_type st)
+aibs_sensor_added(struct aibs_softc *sc, struct sysctl_oid *so,
+ const char *type_name, int idx, struct aibs_sensor *sensor,
+ const char *descr)
+{
+ char sysctl_name[8];
+
+ snprintf(sysctl_name, sizeof(sysctl_name), "%i", idx);
+#ifdef AIBS_VERBOSE
+ device_printf(sc->sc_dev, "%c%i: 0x%08jx %20s %5jd / %5jd\n",
+ type_name[0], idx,
+ (uintmax_t)sensor->i, descr, (intmax_t)sensor->l,
+ (intmax_t)sensor->h);
+#endif
+ SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->sc_dev),
+ SYSCTL_CHILDREN(so), idx, sysctl_name,
+ CTLTYPE_INT | CTLFLAG_RD, sc, (uintptr_t)sensor,
+ sc->sc_ggrp_method ? aibs_sysctl_ggrp : aibs_sysctl,
+ sensor->t == AIBS_SENS_TYPE_TEMP ? "IK" : "I", descr);
+}
+
+static int
+aibs_attach_ggrp(struct aibs_softc *sc)
{
ACPI_STATUS s;
+ ACPI_BUFFER buf;
+ ACPI_HANDLE h;
+ ACPI_OBJECT id;
+ ACPI_OBJECT *bp;
+ ACPI_OBJECT_LIST arg;
+ int i;
+ int t, v, f;
+ int err;
+ int *s_idx;
+ const char *name;
+ const char *descr;
+ struct aibs_sensor *sensor;
+ struct sysctl_oid **so;
+
+ /* First see if GITM is available. */
+ s = AcpiGetHandle(sc->sc_ah, "GITM", &h);
+ if (ACPI_FAILURE(s)) {
+ if (bootverbose)
+ device_printf(sc->sc_dev, "GITM not found\n");
+ return (ENXIO);
+ }
+
+ /*
+ * Now call GGRP with the appropriate argument to list sensors.
+ * The method lists different groups of entities depending on
+ * the argument.
+ */
+ id.Integer.Value = AIBS_GROUP_SENSORS;
+ id.Type = ACPI_TYPE_INTEGER;
+ arg.Count = 1;
+ arg.Pointer = &id;
+ buf.Length = ACPI_ALLOCATE_BUFFER;
+ buf.Pointer = NULL;
+ s = AcpiEvaluateObjectTyped(sc->sc_ah, "GGRP", &arg, &buf,
+ ACPI_TYPE_PACKAGE);
+ if (ACPI_FAILURE(s)) {
+ device_printf(sc->sc_dev, "GGRP not found\n");
+ return (ENXIO);
+ }
+
+ bp = buf.Pointer;
+ sc->sc_asens_all = malloc(sizeof(*sc->sc_asens_all) * bp->Package.Count,
+ M_DEVBUF, M_WAITOK | M_ZERO);
+ v = t = f = 0;
+ for (i = 0; i < bp->Package.Count; i++) {
+ sensor = &sc->sc_asens_all[i];
+ err = aibs_add_sensor(sc, &bp->Package.Elements[i], sensor,
+ &descr);
+ if (err != 0)
+ continue;
+
+ switch (sensor->t) {
+ case AIBS_SENS_TYPE_VOLT:
+ name = "volt";
+ so = &sc->sc_volt_sysctl;
+ s_idx = &v;
+ break;
+ case AIBS_SENS_TYPE_TEMP:
+ name = "temp";
+ so = &sc->sc_temp_sysctl;
+ s_idx = &t;
+ break;
+ case AIBS_SENS_TYPE_FAN:
+ name = "fan";
+ so = &sc->sc_fan_sysctl;
+ s_idx = &f;
+ break;
+ default:
+ panic("add_sensor succeeded for unknown sensor type %d",
+ sensor->t);
+ }
+
+ if (*so == NULL) {
+ /* sysctl subtree for sensors of this type */
+ *so = SYSCTL_ADD_NODE(device_get_sysctl_ctx(sc->sc_dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev)),
+ sensor->t, name, CTLFLAG_RD, NULL, NULL);
+ }
+ aibs_sensor_added(sc, *so, name, *s_idx, sensor, descr);
+ *s_idx += 1;
+ }
+
+ AcpiOsFree(buf.Pointer);
+ return (0);
+}
+
+static int
+aibs_attach_sif(struct aibs_softc *sc, int st)
+{
+ char name[] = "?SIF";
+ ACPI_STATUS s;
ACPI_BUFFER b;
ACPI_OBJECT *bp, *o;
- int i, n;
const char *node;
- char name[] = "?SIF";
struct aibs_sensor *as;
- struct sysctl_oid *so;
+ struct sysctl_oid **so;
+ int i, n;
+ int err;
switch (st) {
- case AIBS_VOLT:
+ case AIBS_SENS_TYPE_VOLT:
node = "volt";
name[0] = 'V';
+ so = &sc->sc_volt_sysctl;
break;
- case AIBS_TEMP:
+ case AIBS_SENS_TYPE_TEMP:
node = "temp";
name[0] = 'T';
+ so = &sc->sc_temp_sysctl;
break;
- case AIBS_FAN:
+ case AIBS_SENS_TYPE_FAN:
node = "fan";
name[0] = 'F';
+ so = &sc->sc_fan_sysctl;
break;
default:
- return;
+ panic("Unsupported sensor type %d", st);
}
b.Length = ACPI_ALLOCATE_BUFFER;
@@ -164,7 +365,7 @@ aibs_attach_sif(struct aibs_softc *sc, enum aibs_type st)
ACPI_TYPE_PACKAGE);
if (ACPI_FAILURE(s)) {
device_printf(sc->sc_dev, "%s not found\n", name);
- return;
+ return (ENXIO);
}
bp = b.Pointer;
@@ -172,14 +373,14 @@ aibs_attach_sif(struct aibs_softc *sc, enum aibs_type st)
if (o[0].Type != ACPI_TYPE_INTEGER) {
device_printf(sc->sc_dev, "%s[0]: invalid type\n", name);
AcpiOsFree(b.Pointer);
- return;
+ return (ENXIO);
}
n = o[0].Integer.Value;
if (bp->Package.Count - 1 < n) {
device_printf(sc->sc_dev, "%s: invalid package\n", name);
AcpiOsFree(b.Pointer);
- return;
+ return (ENXIO);
} else if (bp->Package.Count - 1 > n) {
int on = n;
@@ -193,76 +394,37 @@ aibs_attach_sif(struct aibs_softc *sc, enum aibs_type st)
device_printf(sc->sc_dev, "%s: no members in the package\n",
name);
AcpiOsFree(b.Pointer);
- return;
+ return (ENXIO);
}
- as = malloc(sizeof(*as) * n, M_DEVBUF, M_NOWAIT | M_ZERO);
- if (as == NULL) {
- device_printf(sc->sc_dev, "%s: malloc fail\n", name);
- AcpiOsFree(b.Pointer);
- return;
- }
+ as = malloc(sizeof(*as) * n, M_DEVBUF, M_WAITOK | M_ZERO);
switch (st) {
- case AIBS_VOLT:
+ case AIBS_SENS_TYPE_VOLT:
sc->sc_asens_volt = as;
break;
- case AIBS_TEMP:
+ case AIBS_SENS_TYPE_TEMP:
sc->sc_asens_temp = as;
break;
- case AIBS_FAN:
+ case AIBS_SENS_TYPE_FAN:
sc->sc_asens_fan = as;
break;
}
/* sysctl subtree for sensors of this type */
- so = SYSCTL_ADD_NODE(device_get_sysctl_ctx(sc->sc_dev),
+ *so = SYSCTL_ADD_NODE(device_get_sysctl_ctx(sc->sc_dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev)), st,
node, CTLFLAG_RD, NULL, NULL);
for (i = 0, o++; i < n; i++, o++) {
- ACPI_OBJECT *oi;
- char si[3];
- const char *desc;
-
- /* acpica5 automatically evaluates the referenced package */
- if (o[0].Type != ACPI_TYPE_PACKAGE) {
- device_printf(sc->sc_dev,
- "%s: %i: not a package: %i type\n",
- name, i, o[0].Type);
- continue;
- }
- oi = o[0].Package.Elements;
- if (o[0].Package.Count != 5 ||
- oi[0].Type != ACPI_TYPE_INTEGER ||
- oi[1].Type != ACPI_TYPE_STRING ||
- oi[2].Type != ACPI_TYPE_INTEGER ||
- oi[3].Type != ACPI_TYPE_INTEGER ||
- oi[4].Type != ACPI_TYPE_INTEGER) {
- device_printf(sc->sc_dev,
- "%s: %i: invalid package\n",
- name, i);
- continue;
- }
- as[i].i = oi[0].Integer.Value;
- desc = oi[1].String.Pointer;
- as[i].l = oi[2].Integer.Value;
- as[i].h = oi[3].Integer.Value;
- as[i].t = st;
-#ifdef AIBS_VERBOSE
- device_printf(sc->sc_dev, "%c%i: "
- "0x%08"PRIx64" %20s %5"PRIi64" / %5"PRIi64" "
- "0x%"PRIx64"\n",
- name[0], i,
- (uint64_t)as[i].i, desc, (int64_t)as[i].l,
- (int64_t)as[i].h, (uint64_t)oi[4].Integer.Value);
-#endif
- snprintf(si, sizeof(si), "%i", i);
- SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->sc_dev),
- SYSCTL_CHILDREN(so), i, si, CTLTYPE_INT | CTLFLAG_RD,
- sc, st, aibs_sysctl, st == AIBS_TEMP ? "IK" : "I", desc);
+ const char *descr;
+
+ err = aibs_add_sensor(sc, o, &as[i], &descr);
+ if (err == 0)
+ aibs_sensor_added(sc, *so, node, i, &as[i], descr);
}
AcpiOsFree(b.Pointer);
+ return (0);
}
static int
@@ -276,7 +438,9 @@ aibs_detach(device_t dev)
free(sc->sc_asens_temp, M_DEVBUF);
if (sc->sc_asens_fan != NULL)
free(sc->sc_asens_fan, M_DEVBUF);
- return 0;
+ if (sc->sc_asens_all != NULL)
+ free(sc->sc_asens_all, M_DEVBUF);
+ return (0);
}
#ifdef AIBS_VERBOSE
@@ -289,39 +453,33 @@ static int
aibs_sysctl(SYSCTL_HANDLER_ARGS)
{
struct aibs_softc *sc = arg1;
- enum aibs_type st = arg2;
+ struct aibs_sensor *sensor = (void *)arg2;
int i = oidp->oid_number;
ACPI_STATUS rs;
ACPI_OBJECT p, *bp;
ACPI_OBJECT_LIST mp;
ACPI_BUFFER b;
char *name;
- struct aibs_sensor *as;
ACPI_INTEGER v, l, h;
int so[3];
- switch (st) {
- case AIBS_VOLT:
+ switch (sensor->t) {
+ case AIBS_SENS_TYPE_VOLT:
name = "RVLT";
- as = sc->sc_asens_volt;
break;
- case AIBS_TEMP:
+ case AIBS_SENS_TYPE_TEMP:
name = "RTMP";
- as = sc->sc_asens_temp;
break;
- case AIBS_FAN:
+ case AIBS_SENS_TYPE_FAN:
name = "RFAN";
- as = sc->sc_asens_fan;
break;
default:
- return ENOENT;
+ return (ENOENT);
}
- if (as == NULL)
- return ENOENT;
- l = as[i].l;
- h = as[i].h;
+ l = sensor->l;
+ h = sensor->h;
p.Type = ACPI_TYPE_INTEGER;
- p.Integer.Value = as[i].i;
+ p.Integer.Value = sensor->i;
mp.Count = 1;
mp.Pointer = &p;
b.Length = ACPI_ALLOCATE_BUFFER;
@@ -333,26 +491,91 @@ aibs_sysctl(SYSCTL_HANDLER_ARGS)
"%s: %i: evaluation failed\n",
name, i);
ACPI_SERIAL_END(aibs);
- return EIO;
+ return (EIO);
}
bp = b.Pointer;
v = bp->Integer.Value;
AcpiOsFree(b.Pointer);
ACPI_SERIAL_END(aibs);
- switch (st) {
- case AIBS_VOLT:
+ switch (sensor->t) {
+ case AIBS_SENS_TYPE_VOLT:
+ break;
+ case AIBS_SENS_TYPE_TEMP:
+ v += 2731;
+ l += 2731;
+ h += 2731;
+ break;
+ case AIBS_SENS_TYPE_FAN:
+ break;
+ }
+ so[0] = v;
+ so[1] = l;
+ so[2] = h;
+ return (sysctl_handle_opaque(oidp, &so, sizeof(so), req));
+}
+
+static int
+aibs_sysctl_ggrp(SYSCTL_HANDLER_ARGS)
+{
+ struct aibs_softc *sc = arg1;
+ struct aibs_sensor *sensor = (void *)arg2;
+ ACPI_STATUS rs;
+ ACPI_OBJECT p, *bp;
+ ACPI_OBJECT_LIST arg;
+ ACPI_BUFFER buf;
+ ACPI_INTEGER v, l, h;
+ int so[3];
+ uint32_t *ret;
+ uint32_t cmd[3];
+
+ cmd[0] = sensor->i;
+ cmd[1] = 0;
+ cmd[2] = 0;
+ p.Type = ACPI_TYPE_BUFFER;
+ p.Buffer.Pointer = (void *)cmd;
+ p.Buffer.Length = sizeof(cmd);
+ arg.Count = 1;
+ arg.Pointer = &p;
+ buf.Pointer = NULL;
+ buf.Length = ACPI_ALLOCATE_BUFFER;
+ ACPI_SERIAL_BEGIN(aibs);
+ rs = AcpiEvaluateObjectTyped(sc->sc_ah, "GITM", &arg, &buf,
+ ACPI_TYPE_BUFFER);
+ ACPI_SERIAL_END(aibs);
+ if (ACPI_FAILURE(rs)) {
+ device_printf(sc->sc_dev, "GITM evaluation failed\n");
+ return (EIO);
+ }
+ bp = buf.Pointer;
+ if (bp->Buffer.Length < 8) {
+ device_printf(sc->sc_dev, "GITM returned short buffer\n");
+ return (EIO);
+ }
+ ret = (uint32_t *)bp->Buffer.Pointer;
+ if (ret[0] == 0) {
+ device_printf(sc->sc_dev, "GITM returned error status\n");
+ return (EINVAL);
+ }
+ v = ret[1];
+ AcpiOsFree(buf.Pointer);
+
+ l = sensor->l;
+ h = sensor->h;
+
+ switch (sensor->t) {
+ case AIBS_SENS_TYPE_VOLT:
break;
- case AIBS_TEMP:
+ case AIBS_SENS_TYPE_TEMP:
v += 2731;
l += 2731;
h += 2731;
break;
- case AIBS_FAN:
+ case AIBS_SENS_TYPE_FAN:
break;
}
so[0] = v;
so[1] = l;
so[2] = h;
- return sysctl_handle_opaque(oidp, &so, sizeof(so), req);
+ return (sysctl_handle_opaque(oidp, &so, sizeof(so), req));
}
diff --git a/sys/dev/dwc/if_dwc.c b/sys/dev/dwc/if_dwc.c
index a34879b..769fa66 100644
--- a/sys/dev/dwc/if_dwc.c
+++ b/sys/dev/dwc/if_dwc.c
@@ -1097,7 +1097,7 @@ dwc_clock_init(device_t dev)
int error;
/* Enable clock */
- if (clk_get_by_ofw_name(dev, "stmmaceth", &clk) == 0) {
+ if (clk_get_by_ofw_name(dev, 0, "stmmaceth", &clk) == 0) {
error = clk_enable(clk);
if (error != 0) {
device_printf(dev, "could not enable main clock\n");
@@ -1106,7 +1106,7 @@ dwc_clock_init(device_t dev)
}
/* De-assert reset */
- if (hwreset_get_by_ofw_name(dev, "stmmaceth", &rst) == 0) {
+ if (hwreset_get_by_ofw_name(dev, 0, "stmmaceth", &rst) == 0) {
error = hwreset_deassert(rst);
if (error != 0) {
device_printf(dev, "could not de-assert reset\n");
diff --git a/sys/dev/evdev/evdev.c b/sys/dev/evdev/evdev.c
index 63e0496..4de5dee 100644
--- a/sys/dev/evdev/evdev.c
+++ b/sys/dev/evdev/evdev.c
@@ -822,21 +822,6 @@ push:
return (ret);
}
-inline int
-evdev_sync(struct evdev_dev *evdev)
-{
-
- return (evdev_push_event(evdev, EV_SYN, SYN_REPORT, 1));
-}
-
-
-inline int
-evdev_mt_sync(struct evdev_dev *evdev)
-{
-
- return (evdev_push_event(evdev, EV_SYN, SYN_MT_REPORT, 1));
-}
-
int
evdev_register_client(struct evdev_dev *evdev, struct evdev_client *client)
{
diff --git a/sys/dev/evdev/evdev.h b/sys/dev/evdev/evdev.h
index 7287e73..34808b4 100644
--- a/sys/dev/evdev/evdev.h
+++ b/sys/dev/evdev/evdev.h
@@ -97,8 +97,6 @@ int evdev_register(struct evdev_dev *);
int evdev_register_mtx(struct evdev_dev *, struct mtx *);
int evdev_unregister(struct evdev_dev *);
int evdev_push_event(struct evdev_dev *, uint16_t, uint16_t, int32_t);
-int evdev_sync(struct evdev_dev *);
-int evdev_mt_sync(struct evdev_dev *);
void evdev_support_prop(struct evdev_dev *, uint16_t);
void evdev_support_event(struct evdev_dev *, uint16_t);
void evdev_support_key(struct evdev_dev *, uint16_t);
@@ -129,4 +127,68 @@ void evdev_push_leds(struct evdev_dev *, int);
void evdev_push_repeats(struct evdev_dev *, keyboard_t *);
evdev_event_t evdev_ev_kbd_event;
+/* Event reporting shortcuts: */
+static __inline int
+evdev_sync(struct evdev_dev *evdev)
+{
+
+ return (evdev_push_event(evdev, EV_SYN, SYN_REPORT, 1));
+}
+
+static __inline int
+evdev_mt_sync(struct evdev_dev *evdev)
+{
+
+ return (evdev_push_event(evdev, EV_SYN, SYN_MT_REPORT, 1));
+}
+
+static __inline int
+evdev_push_key(struct evdev_dev *evdev, uint16_t code, int32_t value)
+{
+
+ return (evdev_push_event(evdev, EV_KEY, code, value != 0));
+}
+
+static __inline int
+evdev_push_rel(struct evdev_dev *evdev, uint16_t code, int32_t value)
+{
+
+ return (evdev_push_event(evdev, EV_REL, code, value));
+}
+
+static __inline int
+evdev_push_abs(struct evdev_dev *evdev, uint16_t code, int32_t value)
+{
+
+ return (evdev_push_event(evdev, EV_ABS, code, value));
+}
+
+static __inline int
+evdev_push_msc(struct evdev_dev *evdev, uint16_t code, int32_t value)
+{
+
+ return (evdev_push_event(evdev, EV_MSC, code, value));
+}
+
+static __inline int
+evdev_push_led(struct evdev_dev *evdev, uint16_t code, int32_t value)
+{
+
+ return (evdev_push_event(evdev, EV_LED, code, value != 0));
+}
+
+static __inline int
+evdev_push_snd(struct evdev_dev *evdev, uint16_t code, int32_t value)
+{
+
+ return (evdev_push_event(evdev, EV_SND, code, value != 0));
+}
+
+static __inline int
+evdev_push_sw(struct evdev_dev *evdev, uint16_t code, int32_t value)
+{
+
+ return (evdev_push_event(evdev, EV_SW, code, value != 0));
+}
+
#endif /* _DEV_EVDEV_EVDEV_H */
diff --git a/sys/dev/evdev/evdev_utils.c b/sys/dev/evdev/evdev_utils.c
index 47e5e64..8606342 100644
--- a/sys/dev/evdev/evdev_utils.c
+++ b/sys/dev/evdev/evdev_utils.c
@@ -271,8 +271,8 @@ evdev_push_mouse_btn(struct evdev_dev *evdev, int buttons)
size_t i;
for (i = 0; i < nitems(evdev_mouse_button_codes); i++)
- evdev_push_event(evdev, EV_KEY, evdev_mouse_button_codes[i],
- (buttons & (1 << i)) != 0);
+ evdev_push_key(evdev, evdev_mouse_button_codes[i],
+ buttons & (1 << i));
}
void
@@ -285,8 +285,7 @@ evdev_push_leds(struct evdev_dev *evdev, int leds)
return;
for (i = 0; i < nitems(evdev_led_codes); i++)
- evdev_push_event(evdev, EV_LED, evdev_led_codes[i],
- (leds & (1 << i)) != 0);
+ evdev_push_led(evdev, evdev_led_codes[i], leds & (1 << i));
}
void
diff --git a/sys/dev/extres/clk/clk.c b/sys/dev/extres/clk/clk.c
index 5b9eeb6..bcb0a26 100644
--- a/sys/dev/extres/clk/clk.c
+++ b/sys/dev/extres/clk/clk.c
@@ -1196,23 +1196,24 @@ clk_get_by_id(device_t dev, struct clkdom *clkdom, intptr_t id, clk_t *clk)
#ifdef FDT
int
-clk_get_by_ofw_index(device_t dev, int idx, clk_t *clk)
+clk_get_by_ofw_index(device_t dev, phandle_t cnode, int idx, clk_t *clk)
{
- phandle_t cnode, parent, *cells;
+ phandle_t parent, *cells;
device_t clockdev;
int ncells, rv;
struct clkdom *clkdom;
struct clknode *clknode;
*clk = NULL;
-
- cnode = ofw_bus_get_node(dev);
+ if (cnode <= 0)
+ cnode = ofw_bus_get_node(dev);
if (cnode <= 0) {
device_printf(dev, "%s called on not ofw based device\n",
__func__);
return (ENXIO);
}
+
rv = ofw_bus_parse_xref_list_alloc(cnode, "clocks", "#clock-cells", idx,
&parent, &ncells, &cells);
if (rv != 0) {
@@ -1246,12 +1247,12 @@ done:
}
int
-clk_get_by_ofw_name(device_t dev, const char *name, clk_t *clk)
+clk_get_by_ofw_name(device_t dev, phandle_t cnode, const char *name, clk_t *clk)
{
int rv, idx;
- phandle_t cnode;
- cnode = ofw_bus_get_node(dev);
+ if (cnode <= 0)
+ cnode = ofw_bus_get_node(dev);
if (cnode <= 0) {
device_printf(dev, "%s called on not ofw based device\n",
__func__);
@@ -1260,7 +1261,7 @@ clk_get_by_ofw_name(device_t dev, const char *name, clk_t *clk)
rv = ofw_bus_find_string_index(cnode, "clock-names", name, &idx);
if (rv != 0)
return (rv);
- return (clk_get_by_ofw_index(dev, idx, clk));
+ return (clk_get_by_ofw_index(dev, cnode, idx, clk));
}
/* --------------------------------------------------------------------------
diff --git a/sys/dev/extres/clk/clk.h b/sys/dev/extres/clk/clk.h
index 510f0ce..60b8d2b 100644
--- a/sys/dev/extres/clk/clk.h
+++ b/sys/dev/extres/clk/clk.h
@@ -129,8 +129,9 @@ int clk_set_parent_by_clk(clk_t clk, clk_t parent);
const char *clk_get_name(clk_t clk);
#ifdef FDT
-int clk_get_by_ofw_index(device_t dev, int idx, clk_t *clk);
-int clk_get_by_ofw_name(device_t dev, const char *name, clk_t *clk);
+int clk_get_by_ofw_index(device_t dev, phandle_t node, int idx, clk_t *clk);
+int clk_get_by_ofw_name(device_t dev, phandle_t node, const char *name,
+ clk_t *clk);
int clk_parse_ofw_out_names(device_t dev, phandle_t node,
const char ***out_names, uint32_t **indices);
int clk_parse_ofw_clk_name(device_t dev, phandle_t node, const char **name);
diff --git a/sys/dev/extres/clk/clk_fixed.c b/sys/dev/extres/clk/clk_fixed.c
index 133a38a..fd20bb6 100644
--- a/sys/dev/extres/clk/clk_fixed.c
+++ b/sys/dev/extres/clk/clk_fixed.c
@@ -195,7 +195,7 @@ clk_fixed_init_fixed_factor(struct clk_fixed_softc *sc, phandle_t node,
if (rv <= 0)
return (ENXIO);
/* Get name of parent clock */
- rv = clk_get_by_ofw_index(sc->dev, 0, &parent);
+ rv = clk_get_by_ofw_index(sc->dev, 0, 0, &parent);
if (rv != 0)
return (ENXIO);
def->clkdef.parent_names = malloc(sizeof(char *), M_OFWPROP, M_WAITOK);
diff --git a/sys/dev/extres/hwreset/hwreset.c b/sys/dev/extres/hwreset/hwreset.c
index 8623b60..40ee915 100644
--- a/sys/dev/extres/hwreset/hwreset.c
+++ b/sys/dev/extres/hwreset/hwreset.c
@@ -109,15 +109,17 @@ hwreset_default_ofw_map(device_t provider_dev, phandle_t xref, int ncells,
}
int
-hwreset_get_by_ofw_idx(device_t consumer_dev, int idx, hwreset_t *rst)
+hwreset_get_by_ofw_idx(device_t consumer_dev, phandle_t cnode, int idx,
+ hwreset_t *rst)
{
- phandle_t cnode, xnode;
+ phandle_t xnode;
pcell_t *cells;
device_t rstdev;
int ncells, rv;
intptr_t id;
- cnode = ofw_bus_get_node(consumer_dev);
+ if (cnode <= 0)
+ cnode = ofw_bus_get_node(consumer_dev);
if (cnode <= 0) {
device_printf(consumer_dev,
"%s called on not ofw based device\n", __func__);
@@ -145,12 +147,13 @@ hwreset_get_by_ofw_idx(device_t consumer_dev, int idx, hwreset_t *rst)
}
int
-hwreset_get_by_ofw_name(device_t consumer_dev, char *name, hwreset_t *rst)
+hwreset_get_by_ofw_name(device_t consumer_dev, phandle_t cnode, char *name,
+ hwreset_t *rst)
{
int rv, idx;
- phandle_t cnode;
- cnode = ofw_bus_get_node(consumer_dev);
+ if (cnode <= 0)
+ cnode = ofw_bus_get_node(consumer_dev);
if (cnode <= 0) {
device_printf(consumer_dev,
"%s called on not ofw based device\n", __func__);
@@ -159,7 +162,7 @@ hwreset_get_by_ofw_name(device_t consumer_dev, char *name, hwreset_t *rst)
rv = ofw_bus_find_string_index(cnode, "reset-names", name, &idx);
if (rv != 0)
return (rv);
- return (hwreset_get_by_ofw_idx(consumer_dev, idx, rst));
+ return (hwreset_get_by_ofw_idx(consumer_dev, cnode, idx, rst));
}
void
diff --git a/sys/dev/extres/hwreset/hwreset.h b/sys/dev/extres/hwreset/hwreset.h
index 75e653a..6366351 100644
--- a/sys/dev/extres/hwreset/hwreset.h
+++ b/sys/dev/extres/hwreset/hwreset.h
@@ -58,8 +58,10 @@ int hwreset_deassert(hwreset_t rst);
int hwreset_is_asserted(hwreset_t rst, bool *value);
#ifdef FDT
-int hwreset_get_by_ofw_name(device_t consumer_dev, char *name, hwreset_t *rst);
-int hwreset_get_by_ofw_idx(device_t consumer_dev, int idx, hwreset_t *rst);
+int hwreset_get_by_ofw_name(device_t consumer_dev, phandle_t node, char *name,
+ hwreset_t *rst);
+int hwreset_get_by_ofw_idx(device_t consumer_dev, phandle_t node, int idx,
+ hwreset_t *rst);
#endif
diff --git a/sys/dev/extres/phy/phy.c b/sys/dev/extres/phy/phy.c
index a4dc621..dc454a2 100644
--- a/sys/dev/extres/phy/phy.c
+++ b/sys/dev/extres/phy/phy.c
@@ -124,15 +124,16 @@ int phy_default_map(device_t provider, phandle_t xref, int ncells,
}
int
-phy_get_by_ofw_idx(device_t consumer_dev, int idx, phy_t *phy)
+phy_get_by_ofw_idx(device_t consumer_dev, phandle_t cnode, int idx, phy_t *phy)
{
- phandle_t cnode, xnode;
+ phandle_t xnode;
pcell_t *cells;
device_t phydev;
int ncells, rv;
intptr_t id;
- cnode = ofw_bus_get_node(consumer_dev);
+ if (cnode <= 0)
+ cnode = ofw_bus_get_node(consumer_dev);
if (cnode <= 0) {
device_printf(consumer_dev,
"%s called on not ofw based device\n", __func__);
@@ -159,12 +160,13 @@ phy_get_by_ofw_idx(device_t consumer_dev, int idx, phy_t *phy)
}
int
-phy_get_by_ofw_name(device_t consumer_dev, char *name, phy_t *phy)
+phy_get_by_ofw_name(device_t consumer_dev, phandle_t cnode, char *name,
+ phy_t *phy)
{
int rv, idx;
- phandle_t cnode;
- cnode = ofw_bus_get_node(consumer_dev);
+ if (cnode <= 0)
+ cnode = ofw_bus_get_node(consumer_dev);
if (cnode <= 0) {
device_printf(consumer_dev,
"%s called on not ofw based device\n", __func__);
@@ -173,19 +175,20 @@ phy_get_by_ofw_name(device_t consumer_dev, char *name, phy_t *phy)
rv = ofw_bus_find_string_index(cnode, "phy-names", name, &idx);
if (rv != 0)
return (rv);
- return (phy_get_by_ofw_idx(consumer_dev, idx, phy));
+ return (phy_get_by_ofw_idx(consumer_dev, cnode, idx, phy));
}
int
-phy_get_by_ofw_property(device_t consumer_dev, char *name, phy_t *phy)
+phy_get_by_ofw_property(device_t consumer_dev, phandle_t cnode, char *name,
+ phy_t *phy)
{
- phandle_t cnode;
pcell_t *cells;
device_t phydev;
int ncells, rv;
intptr_t id;
- cnode = ofw_bus_get_node(consumer_dev);
+ if (cnode <= 0)
+ cnode = ofw_bus_get_node(consumer_dev);
if (cnode <= 0) {
device_printf(consumer_dev,
"%s called on not ofw based device\n", __func__);
diff --git a/sys/dev/extres/phy/phy.h b/sys/dev/extres/phy/phy.h
index 93b4fe4..2d0e3f8 100644
--- a/sys/dev/extres/phy/phy.h
+++ b/sys/dev/extres/phy/phy.h
@@ -50,9 +50,14 @@ void phy_unregister_provider(device_t provider);
int phy_get_by_id(device_t consumer_dev, device_t provider_dev, intptr_t id,
phy_t *phy);
void phy_release(phy_t phy);
-int phy_get_by_ofw_name(device_t consumer, char *name, phy_t *phy);
-int phy_get_by_ofw_idx(device_t consumer, int idx, phy_t *phy);
-int phy_get_by_ofw_property(device_t consumer, char *name, phy_t *phy);
+
+#ifdef FDT
+int phy_get_by_ofw_name(device_t consumer, phandle_t node, char *name,
+ phy_t *phy);
+int phy_get_by_ofw_idx(device_t consumer, phandle_t node, int idx, phy_t *phy);
+int phy_get_by_ofw_property(device_t consumer, phandle_t node, char *name,
+ phy_t *phy);
+#endif
int phy_init(device_t consumer, phy_t phy);
int phy_deinit(device_t consumer, phy_t phy);
diff --git a/sys/dev/extres/regulator/regulator.c b/sys/dev/extres/regulator/regulator.c
index 84cd8fd..10307b1 100644
--- a/sys/dev/extres/regulator/regulator.c
+++ b/sys/dev/extres/regulator/regulator.c
@@ -53,6 +53,8 @@ __FBSDID("$FreeBSD$");
MALLOC_DEFINE(M_REGULATOR, "regulator", "Regulator framework");
+#define DIV_ROUND_UP(n,d) howmany(n, d)
+
/* Forward declarations. */
struct regulator;
struct regnode;
@@ -945,16 +947,18 @@ regulator_parse_ofw_stdparam(device_t pdev, phandle_t node,
}
int
-regulator_get_by_ofw_property(device_t cdev, char *name, regulator_t *reg)
+regulator_get_by_ofw_property(device_t cdev, phandle_t cnode, char *name,
+ regulator_t *reg)
{
- phandle_t cnode, *cells;
+ phandle_t *cells;
device_t regdev;
int ncells, rv;
intptr_t id;
*reg = NULL;
- cnode = ofw_bus_get_node(cdev);
+ if (cnode <= 0)
+ cnode = ofw_bus_get_node(cdev);
if (cnode <= 0) {
device_printf(cdev, "%s called on not ofw based device\n",
__func__);
@@ -982,3 +986,87 @@ regulator_get_by_ofw_property(device_t cdev, char *name, regulator_t *reg)
return (regulator_get_by_id(cdev, regdev, id, reg));
}
#endif
+
+/* --------------------------------------------------------------------------
+ *
+ * Regulator utility functions.
+ *
+ */
+
+/* Convert raw selector value to real voltage */
+int
+regulator_range_sel8_to_volt(struct regulator_range *ranges, int nranges,
+ uint8_t sel, int *volt)
+{
+ struct regulator_range *range;
+ int i;
+
+ if (nranges == 0)
+ panic("Voltage regulator have zero ranges\n");
+
+ for (i = 0; i < nranges ; i++) {
+ range = ranges + i;
+
+ if (!(sel >= range->min_sel &&
+ sel <= range->max_sel))
+ continue;
+
+ sel -= range->min_sel;
+
+ *volt = range->min_uvolt + sel * range->step_uvolt;
+ return (0);
+ }
+
+ return (ERANGE);
+}
+
+int
+regulator_range_volt_to_sel8(struct regulator_range *ranges, int nranges,
+ int min_uvolt, int max_uvolt, uint8_t *out_sel)
+{
+ struct regulator_range *range;
+ uint8_t sel;
+ int uvolt;
+ int rv, i;
+
+ if (nranges == 0)
+ panic("Voltage regulator have zero ranges\n");
+
+ for (i = 0; i < nranges; i++) {
+ range = ranges + i;
+ uvolt = range->min_uvolt +
+ (range->max_sel - range->min_sel) * range->step_uvolt;
+
+ if ((min_uvolt > uvolt) ||
+ (max_uvolt < range->min_uvolt))
+ continue;
+
+ if (min_uvolt <= range->min_uvolt)
+ min_uvolt = range->min_uvolt;
+
+ /* if step == 0 -> fixed voltage range. */
+ if (range->step_uvolt == 0)
+ sel = 0;
+ else
+ sel = DIV_ROUND_UP(min_uvolt - range->min_uvolt,
+ range->step_uvolt);
+
+
+ sel += range->min_sel;
+
+ break;
+ }
+
+ if (i >= nranges)
+ return (ERANGE);
+
+ /* Verify new settings. */
+ rv = regulator_range_sel8_to_volt(ranges, nranges, sel, &uvolt);
+ if (rv != 0)
+ return (rv);
+ if ((uvolt < min_uvolt) || (uvolt > max_uvolt))
+ return (ERANGE);
+
+ *out_sel = sel;
+ return (0);
+}
diff --git a/sys/dev/extres/regulator/regulator.h b/sys/dev/extres/regulator/regulator.h
index 380bad6..75d673d 100644
--- a/sys/dev/extres/regulator/regulator.h
+++ b/sys/dev/extres/regulator/regulator.h
@@ -67,9 +67,22 @@ struct regnode_init_def {
#ifdef FDT
phandle_t ofw_node; /* OFW node of regulator */
#endif
+};
+struct regulator_range {
+ int min_uvolt;
+ int step_uvolt;
+ uint8_t min_sel;
+ uint8_t max_sel;
};
+#define REG_RANGE_INIT(_min_sel, _max_sel, _min_uvolt, _step_uvolt) { \
+ .min_sel = _min_sel, \
+ .max_sel = _max_sel, \
+ .min_uvolt = _min_uvolt, \
+ .step_uvolt = _step_uvolt, \
+}
+
/*
* Shorthands for constructing method tables.
*/
@@ -119,9 +132,16 @@ int regulator_get_voltage(regulator_t reg, int *uvolt);
int regulator_set_voltage(regulator_t reg, int min_uvolt, int max_uvolt);
#ifdef FDT
-int regulator_get_by_ofw_property(device_t dev, char *name, regulator_t *reg);
+int regulator_get_by_ofw_property(device_t dev, phandle_t node, char *name,
+ regulator_t *reg);
int regulator_parse_ofw_stdparam(device_t dev, phandle_t node,
struct regnode_init_def *def);
#endif
+/* Utility functions */
+int regulator_range_volt_to_sel8(struct regulator_range *ranges, int nranges,
+ int min_uvolt, int max_uvolt, uint8_t *out_sel);
+int regulator_range_sel8_to_volt(struct regulator_range *ranges, int nranges,
+ uint8_t sel, int *volt);
+
#endif /* _DEV_EXTRES_REGULATOR_H_ */
diff --git a/sys/dev/fdt/simplebus.c b/sys/dev/fdt/simplebus.c
index 4173160..8d43a70 100644
--- a/sys/dev/fdt/simplebus.c
+++ b/sys/dev/fdt/simplebus.c
@@ -251,9 +251,7 @@ simplebus_setup_dinfo(device_t dev, phandle_t node,
resource_list_init(&ndi->rl);
ofw_bus_reg_to_rl(dev, node, sc->acells, sc->scells, &ndi->rl);
-#ifndef INTRNG
ofw_bus_intr_to_rl(dev, node, &ndi->rl, NULL);
-#endif
return (ndi);
}
diff --git a/sys/dev/gpio/gpiobus.c b/sys/dev/gpio/gpiobus.c
index eac9d2b..421af9d 100644
--- a/sys/dev/gpio/gpiobus.c
+++ b/sys/dev/gpio/gpiobus.c
@@ -31,7 +31,9 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/gpio.h>
+#ifdef INTRNG
#include <sys/intr.h>
+#endif
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
@@ -79,43 +81,26 @@ static int gpiobus_pin_toggle(device_t, device_t, uint32_t);
* data will be moved into struct resource.
*/
#ifdef INTRNG
-static void
-gpio_destruct_map_data(struct intr_map_data *map_data)
-{
-
- KASSERT(map_data->type == INTR_MAP_DATA_GPIO,
- ("%s: bad map_data type %d", __func__, map_data->type));
-
- free(map_data, M_DEVBUF);
-}
struct resource *
gpio_alloc_intr_resource(device_t consumer_dev, int *rid, u_int alloc_flags,
gpio_pin_t pin, uint32_t intr_mode)
{
- int rv;
u_int irq;
struct intr_map_data_gpio *gpio_data;
struct resource *res;
- gpio_data = malloc(sizeof(*gpio_data), M_DEVBUF, M_WAITOK | M_ZERO);
- gpio_data->hdr.type = INTR_MAP_DATA_GPIO;
- gpio_data->hdr.destruct = gpio_destruct_map_data;
+ gpio_data = (struct intr_map_data_gpio *)intr_alloc_map_data(
+ INTR_MAP_DATA_GPIO, sizeof(*gpio_data), M_WAITOK | M_ZERO);
gpio_data->gpio_pin_num = pin->pin;
gpio_data->gpio_pin_flags = pin->flags;
gpio_data->gpio_intr_mode = intr_mode;
- rv = intr_map_irq(pin->dev, 0, (struct intr_map_data *)gpio_data,
- &irq);
- if (rv != 0) {
- gpio_destruct_map_data((struct intr_map_data *)gpio_data);
- return (NULL);
- }
-
+ irq = intr_map_irq(pin->dev, 0, (struct intr_map_data *)gpio_data);
res = bus_alloc_resource(consumer_dev, SYS_RES_IRQ, rid, irq, irq, 1,
alloc_flags);
if (res == NULL) {
- gpio_destruct_map_data((struct intr_map_data *)gpio_data);
+ intr_free_intr_map_data((struct intr_map_data *)gpio_data);
return (NULL);
}
rman_set_virtual(res, gpio_data);
diff --git a/sys/dev/gpio/gpiobusvar.h b/sys/dev/gpio/gpiobusvar.h
index a271905..6352b81 100644
--- a/sys/dev/gpio/gpiobusvar.h
+++ b/sys/dev/gpio/gpiobusvar.h
@@ -70,12 +70,14 @@ struct gpiobus_pin_data
char *name; /* pin name. */
};
+#ifdef INTRNG
struct intr_map_data_gpio {
struct intr_map_data hdr;
u_int gpio_pin_num;
u_int gpio_pin_flags;
u_int gpio_intr_mode;
};
+#endif
struct gpiobus_softc
{
diff --git a/sys/dev/gpio/ofw_gpiobus.c b/sys/dev/gpio/ofw_gpiobus.c
index 804b33e..96775dc 100644
--- a/sys/dev/gpio/ofw_gpiobus.c
+++ b/sys/dev/gpio/ofw_gpiobus.c
@@ -321,13 +321,11 @@ ofw_gpiobus_setup_devinfo(device_t bus, device_t child, phandle_t node)
devi->pins[i] = pins[i].pin;
}
free(pins, M_DEVBUF);
-#ifndef INTRNG
/* Parse the interrupt resources. */
if (ofw_bus_intr_to_rl(bus, node, &dinfo->opd_dinfo.rl, NULL) != 0) {
ofw_gpiobus_destroy_devinfo(bus, dinfo);
return (NULL);
}
-#endif
device_set_ivars(child, dinfo);
return (dinfo);
diff --git a/sys/dev/iicbus/ofw_iicbus.c b/sys/dev/iicbus/ofw_iicbus.c
index 2da1691..0820bbf 100644
--- a/sys/dev/iicbus/ofw_iicbus.c
+++ b/sys/dev/iicbus/ofw_iicbus.c
@@ -187,10 +187,8 @@ ofw_iicbus_attach(device_t dev)
childdev = device_add_child(dev, NULL, -1);
resource_list_init(&dinfo->opd_dinfo.rl);
-#ifndef INTRNG
ofw_bus_intr_to_rl(childdev, child,
&dinfo->opd_dinfo.rl, NULL);
-#endif
device_set_ivars(childdev, dinfo);
}
diff --git a/sys/dev/iicbus/twsi/a10_twsi.c b/sys/dev/iicbus/twsi/a10_twsi.c
index c32e6fa..b468f08 100644
--- a/sys/dev/iicbus/twsi/a10_twsi.c
+++ b/sys/dev/iicbus/twsi/a10_twsi.c
@@ -95,7 +95,7 @@ a10_twsi_attach(device_t dev)
sc = device_get_softc(dev);
/* De-assert reset */
- if (hwreset_get_by_ofw_idx(dev, 0, &rst) == 0) {
+ if (hwreset_get_by_ofw_idx(dev, 0, 0, &rst) == 0) {
error = hwreset_deassert(rst);
if (error != 0) {
device_printf(dev, "could not de-assert reset\n");
@@ -104,7 +104,7 @@ a10_twsi_attach(device_t dev)
}
/* Activate clock */
- error = clk_get_by_ofw_index(dev, 0, &clk);
+ error = clk_get_by_ofw_index(dev, 0, 0, &clk);
if (error != 0) {
device_printf(dev, "could not find clock\n");
return (error);
diff --git a/sys/dev/jedec_ts/jedec_ts.c b/sys/dev/jedec_ts/jedec_ts.c
new file mode 100644
index 0000000..b65ef78
--- /dev/null
+++ b/sys/dev/jedec_ts/jedec_ts.c
@@ -0,0 +1,179 @@
+/*-
+ * Copyright (c) 2016 Andriy Gapon <avg@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 ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+
+#include <dev/smbus/smbconf.h>
+#include <dev/smbus/smbus.h>
+
+#include "smbus_if.h"
+
+
+/*
+ * SMBus specification defines little-endian byte order,
+ * but it seems that the JEDEC devices expect it to
+ * be big-endian.
+ */
+static int
+ts_readw_be(device_t dev, uint8_t reg, uint16_t *val)
+{
+ device_t bus = device_get_parent(dev);
+ uint8_t addr = smbus_get_addr(dev);
+ int err;
+
+ err = smbus_readw(bus, addr, reg, val);
+ if (err != 0)
+ return (err);
+ *val = be16toh(*val);
+ return (0);
+}
+
+static int
+ts_temp_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ device_t dev = arg1;
+ int err;
+ int temp;
+ uint16_t val;
+
+ err = ts_readw_be(dev, 5, &val);
+ if (err != 0)
+ return (EIO);
+
+ /*
+ * Convert the reading to temperature in 0.0001 Kelvins.
+ * Three most significant bits are flags, the next
+ * most significant bit is a sign bit.
+ * Each step is 0.0625 degrees.
+ */
+ temp = val & 0xfff;
+ if ((val & 0x1000) != 0)
+ temp = -temp;
+ temp = temp * 625 + 2731500;
+ err = sysctl_handle_int(oidp, &temp, 0, req);
+ return (err);
+}
+
+static int
+ts_probe(device_t dev)
+{
+ device_set_desc(dev, "DIMM memory sensor");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+ts_attach(device_t dev)
+{
+ struct sysctl_ctx_list *ctx;
+ struct sysctl_oid_list *tree;
+ int err;
+ uint16_t vendorid;
+ uint16_t devid;
+ uint8_t addr;
+
+ addr = smbus_get_addr(dev);
+ if ((addr & 0x30) != 0x30) {
+ /* Up to 8 slave devices starting at 0x30. */
+ return (ENXIO);
+ }
+
+ err = ts_readw_be(dev, 6, &vendorid);
+ if (err != 0) {
+ device_printf(dev, "failed to read Manufacturer ID\n");
+ return (ENXIO);
+ }
+ err = ts_readw_be(dev, 6, &devid);
+ if (err != 0) {
+ device_printf(dev, "failed to read Device ID\n");
+ return (ENXIO);
+ }
+ if ((devid & 0xff00) == 0x2200) {
+ /*
+ * Defined by JEDEC Standard No. 21-C, Release 26,
+ * Page 4.1.6 – 24
+ */
+ } else if (vendorid == 0x104a) {
+ /*
+ * STMicroelectronics datasheets say that
+ * device ID and revision can vary.
+ * E.g. STT424E02, Doc ID 13448 Rev 8,
+ * section 4.6, page 26.
+ */
+ } else {
+ if (bootverbose) {
+ device_printf(dev, "Unknown Manufacturer and Device IDs"
+ ", 0x%x and 0x%x\n", vendorid, devid);
+ }
+ return (ENXIO);
+ }
+
+ ctx = device_get_sysctl_ctx(dev);
+ tree = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
+
+ SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "temp",
+ CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, dev, 0,
+ ts_temp_sysctl, "IK4", "Current temperature");
+
+ return (0);
+}
+
+static int
+ts_detach(device_t dev)
+{
+ return (0);
+}
+
+
+static device_method_t jedec_ts_methods[] = {
+ /* Methods from the device interface */
+ DEVMETHOD(device_probe, ts_probe),
+ DEVMETHOD(device_attach, ts_attach),
+ DEVMETHOD(device_detach, ts_detach),
+
+ /* Terminate method list */
+ { 0, 0 }
+};
+
+static driver_t jedec_ts_driver = {
+ "jedec_ts",
+ jedec_ts_methods,
+ 0 /* no softc */
+};
+
+static devclass_t jedec_ts_devclass;
+
+DRIVER_MODULE(jedec_ts, smbus, jedec_ts_driver, jedec_ts_devclass, 0, 0);
+MODULE_DEPEND(jedec_ts, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
+MODULE_VERSION(jedec_ts, 1);
diff --git a/sys/dev/ofw/ofw_bus_subr.c b/sys/dev/ofw/ofw_bus_subr.c
index b58d041..1c80106 100644
--- a/sys/dev/ofw/ofw_bus_subr.c
+++ b/sys/dev/ofw/ofw_bus_subr.c
@@ -45,6 +45,8 @@ __FBSDID("$FreeBSD$");
#include "ofw_bus_if.h"
+#define OFW_COMPAT_LEN 255
+
int
ofw_bus_gen_setup_devinfo(struct ofw_bus_devinfo *obd, phandle_t node)
{
@@ -178,7 +180,8 @@ ofw_bus_status_okay(device_t dev)
}
static int
-ofw_bus_node_is_compatible(const char *compat, int len, const char *onecompat)
+ofw_bus_node_is_compatible_int(const char *compat, int len,
+ const char *onecompat)
{
int onelen, l, ret;
@@ -203,6 +206,25 @@ ofw_bus_node_is_compatible(const char *compat, int len, const char *onecompat)
}
int
+ofw_bus_node_is_compatible(phandle_t node, const char *compatstr)
+{
+ char compat[OFW_COMPAT_LEN];
+ int len, rv;
+
+ if ((len = OF_getproplen(node, "compatible")) <= 0)
+ return (0);
+
+ bzero(compat, OFW_COMPAT_LEN);
+
+ if (OF_getprop(node, "compatible", compat, OFW_COMPAT_LEN) < 0)
+ return (0);
+
+ rv = ofw_bus_node_is_compatible_int(compat, len, compatstr);
+
+ return (rv);
+}
+
+int
ofw_bus_is_compatible(device_t dev, const char *onecompat)
{
phandle_t node;
@@ -219,7 +241,7 @@ ofw_bus_is_compatible(device_t dev, const char *onecompat)
if ((len = OF_getproplen(node, "compatible")) <= 0)
return (0);
- return (ofw_bus_node_is_compatible(compat, len, onecompat));
+ return (ofw_bus_node_is_compatible_int(compat, len, onecompat));
}
int
@@ -516,7 +538,6 @@ ofw_bus_find_iparent(phandle_t node)
return (iparent);
}
-#ifndef INTRNG
int
ofw_bus_intr_to_rl(device_t dev, phandle_t node,
struct resource_list *rl, int *rlen)
@@ -582,7 +603,6 @@ ofw_bus_intr_to_rl(device_t dev, phandle_t node,
free(intr, M_OFWPROP);
return (err);
}
-#endif
int
ofw_bus_intr_by_rid(device_t dev, phandle_t node, int wanted_rid,
@@ -691,7 +711,7 @@ ofw_bus_find_compatible(phandle_t node, const char *onecompat)
for (child = OF_child(node); child != 0; child = OF_peer(child)) {
len = OF_getprop_alloc(child, "compatible", 1, &compat);
if (len >= 0) {
- ret = ofw_bus_node_is_compatible(compat, len,
+ ret = ofw_bus_node_is_compatible_int(compat, len,
onecompat);
free(compat, M_OFWPROP);
if (ret != 0)
diff --git a/sys/dev/ofw/ofw_bus_subr.h b/sys/dev/ofw/ofw_bus_subr.h
index 3c2b4e1..6532a16 100644
--- a/sys/dev/ofw/ofw_bus_subr.h
+++ b/sys/dev/ofw/ofw_bus_subr.h
@@ -32,7 +32,9 @@
#define _DEV_OFW_OFW_BUS_SUBR_H_
#include <sys/bus.h>
-
+#ifdef INTRNG
+#include <sys/intr.h>
+#endif
#include <dev/ofw/openfirm.h>
#include "ofw_bus_if.h"
@@ -52,12 +54,14 @@ struct ofw_compat_data {
uintptr_t ocd_data;
};
+#ifdef INTRNG
struct intr_map_data_fdt {
struct intr_map_data hdr;
phandle_t iparent;
u_int ncells;
- pcell_t *cells;
+ pcell_t cells[];
};
+#endif
#define SIMPLEBUS_PNP_DESCR "Z:compat;P:private;"
#define SIMPLEBUS_PNP_INFO(t) \
@@ -89,9 +93,7 @@ int ofw_bus_msimap(phandle_t, uint16_t, phandle_t *, uint32_t *);
/* Routines for parsing device-tree data into resource lists. */
int ofw_bus_reg_to_rl(device_t, phandle_t, pcell_t, pcell_t,
struct resource_list *);
-#ifndef INTRNG
int ofw_bus_intr_to_rl(device_t, phandle_t, struct resource_list *, int *);
-#endif
int ofw_bus_intr_by_rid(device_t, phandle_t, int, phandle_t *, int *,
pcell_t **);
@@ -105,6 +107,7 @@ phandle_t ofw_bus_find_iparent(phandle_t);
/* Helper routine for checking compat prop */
int ofw_bus_is_compatible(device_t, const char *);
int ofw_bus_is_compatible_strict(device_t, const char *);
+int ofw_bus_node_is_compatible(phandle_t, const char *);
/*
* Helper routine to search a list of compat properties. The table is
diff --git a/sys/dev/ofw/ofwbus.c b/sys/dev/ofw/ofwbus.c
index 1e048c4..2a28a92 100644
--- a/sys/dev/ofw/ofwbus.c
+++ b/sys/dev/ofw/ofwbus.c
@@ -80,9 +80,6 @@ static device_attach_t ofwbus_attach;
static bus_alloc_resource_t ofwbus_alloc_resource;
static bus_adjust_resource_t ofwbus_adjust_resource;
static bus_release_resource_t ofwbus_release_resource;
-#ifdef INTRNG
-static bus_map_intr_t ofwbus_map_intr;
-#endif
static device_method_t ofwbus_methods[] = {
/* Device interface */
@@ -96,9 +93,6 @@ static device_method_t ofwbus_methods[] = {
DEVMETHOD(bus_alloc_resource, ofwbus_alloc_resource),
DEVMETHOD(bus_adjust_resource, ofwbus_adjust_resource),
DEVMETHOD(bus_release_resource, ofwbus_release_resource),
-#ifdef INTRNG
- DEVMETHOD(bus_map_intr, ofwbus_map_intr),
-#endif
DEVMETHOD_END
};
@@ -299,53 +293,3 @@ ofwbus_release_resource(device_t bus, device_t child, int type,
}
return (rman_release_resource(r));
}
-
-#ifdef INTRNG
-static void
-ofwbus_destruct_map_data(struct intr_map_data *map_data)
-{
- struct intr_map_data_fdt *fdt_map_data;
-
- KASSERT(map_data->type == INTR_MAP_DATA_FDT,
- ("%s: bad map_data type %d", __func__, map_data->type));
-
- fdt_map_data = (struct intr_map_data_fdt *)map_data;
- OF_prop_free(fdt_map_data->cells);
- free(fdt_map_data, M_OFWPROP);
-}
-
-static int
-ofwbus_map_intr(device_t bus, device_t child, int *rid, rman_res_t *start,
- rman_res_t *end, rman_res_t *count, struct intr_map_data **imd)
-{
- phandle_t iparent, node;
- pcell_t *cells;
- int ncells, rv;
- u_int irq;
- struct intr_map_data_fdt *fdt_data;
-
- node = ofw_bus_get_node(child);
- rv = ofw_bus_intr_by_rid(child, node, *rid, &iparent, &ncells, &cells);
- if (rv != 0)
- return (rv);
-
- fdt_data = malloc(sizeof(*fdt_data), M_OFWPROP, M_WAITOK | M_ZERO);
- fdt_data->hdr.type = INTR_MAP_DATA_FDT;
- fdt_data->hdr.destruct = ofwbus_destruct_map_data;
- fdt_data->iparent = iparent;
- fdt_data->ncells = ncells;
- fdt_data->cells = cells;
- rv = intr_map_irq(NULL, iparent, (struct intr_map_data *)fdt_data,
- &irq);
- if (rv != 0) {
- ofwbus_destruct_map_data((struct intr_map_data *)fdt_data);
- return (rv);
- }
-
- *start = irq;
- *end = irq;
- *count = 1;
- *imd = (struct intr_map_data *)fdt_data;
- return (0);
-}
-#endif
diff --git a/sys/dev/pci/pci_host_generic.c b/sys/dev/pci/pci_host_generic.c
index f894ca0..e95543d 100644
--- a/sys/dev/pci/pci_host_generic.c
+++ b/sys/dev/pci/pci_host_generic.c
@@ -939,9 +939,7 @@ generic_pcie_ofw_bus_attach(device_t dev)
resource_list_init(&di->di_rl);
ofw_bus_reg_to_rl(dev, node, addr_cells, size_cells,
&di->di_rl);
-#ifndef INTRNG
ofw_bus_intr_to_rl(dev, node, &di->di_rl, NULL);
-#endif
/* Add newbus device for this FDT node */
child = device_add_child(dev, NULL, -1);
diff --git a/sys/dev/puc/puc.c b/sys/dev/puc/puc.c
index d3b14fb..3d3c3fa 100644
--- a/sys/dev/puc/puc.c
+++ b/sys/dev/puc/puc.c
@@ -414,8 +414,7 @@ puc_bfe_detach(device_t dev)
port = &sc->sc_port[idx];
if (port->p_dev == NULL)
continue;
- if (device_detach(port->p_dev) == 0) {
- device_delete_child(dev, port->p_dev);
+ if (device_delete_child(dev, port->p_dev) == 0) {
if (port->p_rres != NULL)
rman_release_resource(port->p_rres);
if (port->p_ires != NULL)
diff --git a/sys/dev/uart/uart_cpu_powerpc.c b/sys/dev/uart/uart_cpu_powerpc.c
index 8d98405..d3155b0 100644
--- a/sys/dev/uart/uart_cpu_powerpc.c
+++ b/sys/dev/uart/uart_cpu_powerpc.c
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/ofw_machdep.h>
+#include <dev/ofw/ofw_bus_subr.h>
#include <dev/ofw/openfirm.h>
#include <dev/uart/uart.h>
#include <dev/uart/uart_cpu.h>
@@ -163,14 +164,13 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
return (ENXIO);
if (strcmp(buf, "serial") != 0)
return (ENXIO);
- if (OF_getprop(input, "compatible", buf, sizeof(buf)) == -1)
- return (ENXIO);
- if (strncmp(buf, "chrp,es", 7) == 0) {
+ if (ofw_bus_node_is_compatible(input, "chrp,es")) {
class = &uart_z8530_class;
di->bas.regshft = 4;
di->bas.chan = 1;
- } else if (strcmp(buf,"ns16550") == 0 || strcmp(buf,"ns8250") == 0) {
+ } else if (ofw_bus_node_is_compatible(input,"ns16550") ||
+ ofw_bus_node_is_compatible(input,"ns8250")) {
class = &uart_ns8250_class;
di->bas.regshft = 0;
di->bas.chan = 0;
diff --git a/sys/dev/uart/uart_dev_snps.c b/sys/dev/uart/uart_dev_snps.c
index af4000f..c0e3d79 100644
--- a/sys/dev/uart/uart_dev_snps.c
+++ b/sys/dev/uart/uart_dev_snps.c
@@ -119,12 +119,12 @@ snps_get_clocks(device_t dev, clk_t *baudclk, clk_t *apb_pclk)
/* Baud clock is either named "baudclk", or there is a single
* unnamed clock.
*/
- if (clk_get_by_ofw_name(dev, "baudclk", baudclk) != 0 &&
- clk_get_by_ofw_index(dev, 0, baudclk) != 0)
+ if (clk_get_by_ofw_name(dev, 0, "baudclk", baudclk) != 0 &&
+ clk_get_by_ofw_index(dev, 0, 0, baudclk) != 0)
return (ENOENT);
/* APB peripheral clock is optional */
- (void)clk_get_by_ofw_name(dev, "apb_pclk", apb_pclk);
+ (void)clk_get_by_ofw_name(dev, 0, "apb_pclk", apb_pclk);
return (0);
}
@@ -163,7 +163,7 @@ snps_probe(device_t dev)
clock = 0;
#ifdef EXT_RESOURCES
- if (hwreset_get_by_ofw_idx(dev, 0, &reset) == 0) {
+ if (hwreset_get_by_ofw_idx(dev, 0, 0, &reset) == 0) {
error = hwreset_deassert(reset);
if (error != 0) {
device_printf(dev, "cannot de-assert reset\n");
diff --git a/sys/dev/usb/controller/at91dci_atmelarm.c b/sys/dev/usb/controller/at91dci_atmelarm.c
index e352cc8..0dc1f9f 100644
--- a/sys/dev/usb/controller/at91dci_atmelarm.c
+++ b/sys/dev/usb/controller/at91dci_atmelarm.c
@@ -243,14 +243,8 @@ static int
at91_udp_detach(device_t dev)
{
struct at91_udp_softc *sc = device_get_softc(dev);
- device_t bdev;
int err;
- if (sc->sc_dci.sc_bus.bdev) {
- bdev = sc->sc_dci.sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/dev/usb/controller/at91dci_fdt.c b/sys/dev/usb/controller/at91dci_fdt.c
index ba5ce27..431b502 100644
--- a/sys/dev/usb/controller/at91dci_fdt.c
+++ b/sys/dev/usb/controller/at91dci_fdt.c
@@ -249,14 +249,8 @@ static int
at91_udp_detach(device_t dev)
{
struct at91_udp_softc *sc = device_get_softc(dev);
- device_t bdev;
int err;
- if (sc->sc_dci.sc_bus.bdev) {
- bdev = sc->sc_dci.sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/dev/usb/controller/atmegadci_atmelarm.c b/sys/dev/usb/controller/atmegadci_atmelarm.c
index 7c052e6..d89ba8b 100644
--- a/sys/dev/usb/controller/atmegadci_atmelarm.c
+++ b/sys/dev/usb/controller/atmegadci_atmelarm.c
@@ -155,14 +155,8 @@ static int
atmegadci_detach(device_t dev)
{
struct atmegadci_super_softc *sc = device_get_softc(dev);
- device_t bdev;
int err;
- if (sc->sc_otg.sc_bus.bdev) {
- bdev = sc->sc_otg.sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/dev/usb/controller/dwc_otg_fdt.c b/sys/dev/usb/controller/dwc_otg_fdt.c
index 20ab0c5..80d3388 100644
--- a/sys/dev/usb/controller/dwc_otg_fdt.c
+++ b/sys/dev/usb/controller/dwc_otg_fdt.c
@@ -163,14 +163,8 @@ static int
dwc_otg_detach(device_t dev)
{
struct dwc_otg_fdt_softc *sc = device_get_softc(dev);
- device_t bdev;
int err;
- if (sc->sc_otg.sc_bus.bdev) {
- bdev = sc->sc_otg.sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/dev/usb/controller/ehci_ixp4xx.c b/sys/dev/usb/controller/ehci_ixp4xx.c
index 1b2f640..02554ec 100644
--- a/sys/dev/usb/controller/ehci_ixp4xx.c
+++ b/sys/dev/usb/controller/ehci_ixp4xx.c
@@ -221,14 +221,8 @@ ehci_ixp_detach(device_t self)
{
struct ixp_ehci_softc *isc = device_get_softc(self);
ehci_softc_t *sc = &isc->base;
- device_t bdev;
int err;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(self);
diff --git a/sys/dev/usb/controller/ehci_mv.c b/sys/dev/usb/controller/ehci_mv.c
index cd7d549..f433b4b 100644
--- a/sys/dev/usb/controller/ehci_mv.c
+++ b/sys/dev/usb/controller/ehci_mv.c
@@ -264,14 +264,8 @@ static int
mv_ehci_detach(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
- device_t bdev;
int err;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(self);
diff --git a/sys/dev/usb/controller/ehci_pci.c b/sys/dev/usb/controller/ehci_pci.c
index cad351c..c69d28c 100644
--- a/sys/dev/usb/controller/ehci_pci.c
+++ b/sys/dev/usb/controller/ehci_pci.c
@@ -477,13 +477,7 @@ static int
ehci_pci_detach(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
- device_t bdev;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(self);
diff --git a/sys/dev/usb/controller/generic_ehci.c b/sys/dev/usb/controller/generic_ehci.c
index fcae7dd..5335652 100644
--- a/sys/dev/usb/controller/generic_ehci.c
+++ b/sys/dev/usb/controller/generic_ehci.c
@@ -156,14 +156,8 @@ static int
generic_ehci_detach(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
- device_t bdev;
int err;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(self);
diff --git a/sys/dev/usb/controller/generic_ohci.c b/sys/dev/usb/controller/generic_ohci.c
index 9656c8f..44d2419 100644
--- a/sys/dev/usb/controller/generic_ohci.c
+++ b/sys/dev/usb/controller/generic_ohci.c
@@ -161,7 +161,7 @@ generic_ohci_attach(device_t dev)
#ifdef EXT_RESOURCES
TAILQ_INIT(&sc->clk_list);
/* Enable clock */
- for (off = 0; clk_get_by_ofw_index(dev, off, &clk) == 0; off++) {
+ for (off = 0; clk_get_by_ofw_index(dev, 0, off, &clk) == 0; off++) {
err = clk_enable(clk);
if (err != 0) {
device_printf(dev, "Could not enable clock %s\n",
@@ -174,7 +174,7 @@ generic_ohci_attach(device_t dev)
}
/* De-assert reset */
- if (hwreset_get_by_ofw_idx(dev, 0, &sc->rst) == 0) {
+ if (hwreset_get_by_ofw_idx(dev, 0, 0, &sc->rst) == 0) {
err = hwreset_deassert(sc->rst);
if (err != 0) {
device_printf(dev, "Could not de-assert reset %d\n",
@@ -184,7 +184,7 @@ generic_ohci_attach(device_t dev)
}
/* Enable phy */
- if (phy_get_by_ofw_name(dev, "usb", &sc->phy) == 0) {
+ if (phy_get_by_ofw_name(dev, 0, "usb", &sc->phy) == 0) {
err = phy_enable(dev, sc->phy);
if (err != 0) {
device_printf(dev, "Could not enable phy\n");
@@ -214,18 +214,11 @@ static int
generic_ohci_detach(device_t dev)
{
struct generic_ohci_softc *sc = device_get_softc(dev);
- device_t bdev;
int err;
#ifdef EXT_RESOURCES
struct clk_list *clk, *clk_tmp;
#endif
- if (sc->ohci_sc.sc_bus.bdev) {
- bdev = sc->ohci_sc.sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
-
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/dev/usb/controller/musb_otg_atmelarm.c b/sys/dev/usb/controller/musb_otg_atmelarm.c
index 3f1b9f8..b752e63 100644
--- a/sys/dev/usb/controller/musb_otg_atmelarm.c
+++ b/sys/dev/usb/controller/musb_otg_atmelarm.c
@@ -204,14 +204,8 @@ static int
musbotg_detach(device_t dev)
{
struct musbotg_super_softc *sc = device_get_softc(dev);
- device_t bdev;
int err;
- if (sc->sc_otg.sc_bus.bdev) {
- bdev = sc->sc_otg.sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/dev/usb/controller/ohci_pci.c b/sys/dev/usb/controller/ohci_pci.c
index 96950a7..31a1f57 100644
--- a/sys/dev/usb/controller/ohci_pci.c
+++ b/sys/dev/usb/controller/ohci_pci.c
@@ -335,13 +335,7 @@ static int
ohci_pci_detach(device_t self)
{
ohci_softc_t *sc = device_get_softc(self);
- device_t bdev;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(self);
diff --git a/sys/dev/usb/controller/ohci_s3c24x0.c b/sys/dev/usb/controller/ohci_s3c24x0.c
index 28c195a..2e06827 100644
--- a/sys/dev/usb/controller/ohci_s3c24x0.c
+++ b/sys/dev/usb/controller/ohci_s3c24x0.c
@@ -148,14 +148,8 @@ static int
ohci_s3c24x0_detach(device_t dev)
{
struct ohci_softc *sc = device_get_softc(dev);
- device_t bdev;
int err;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/dev/usb/controller/saf1761_otg_boot.c b/sys/dev/usb/controller/saf1761_otg_boot.c
index a2acf06..cc9e9a1 100644
--- a/sys/dev/usb/controller/saf1761_otg_boot.c
+++ b/sys/dev/usb/controller/saf1761_otg_boot.c
@@ -124,13 +124,6 @@ static int
saf1761_otg_fdt_detach(device_t dev)
{
struct saf1761_otg_softc *sc = device_get_softc(dev);
- device_t bdev;
-
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/dev/usb/controller/saf1761_otg_fdt.c b/sys/dev/usb/controller/saf1761_otg_fdt.c
index 19c64e7..0d7f293 100644
--- a/sys/dev/usb/controller/saf1761_otg_fdt.c
+++ b/sys/dev/usb/controller/saf1761_otg_fdt.c
@@ -238,14 +238,8 @@ static int
saf1761_otg_fdt_detach(device_t dev)
{
struct saf1761_otg_softc *sc = device_get_softc(dev);
- device_t bdev;
int err;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/dev/usb/controller/uhci_pci.c b/sys/dev/usb/controller/uhci_pci.c
index 5916996..2f8b464 100644
--- a/sys/dev/usb/controller/uhci_pci.c
+++ b/sys/dev/usb/controller/uhci_pci.c
@@ -393,13 +393,7 @@ int
uhci_pci_detach(device_t self)
{
uhci_softc_t *sc = device_get_softc(self);
- device_t bdev;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(self);
diff --git a/sys/dev/usb/controller/uss820dci_atmelarm.c b/sys/dev/usb/controller/uss820dci_atmelarm.c
index dcd4db4..2684d38 100644
--- a/sys/dev/usb/controller/uss820dci_atmelarm.c
+++ b/sys/dev/usb/controller/uss820dci_atmelarm.c
@@ -164,14 +164,8 @@ static int
uss820_atmelarm_detach(device_t dev)
{
struct uss820dci_softc *sc = device_get_softc(dev);
- device_t bdev;
int err;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/dev/usb/controller/xhci_mv.c b/sys/dev/usb/controller/xhci_mv.c
index 06b35ce..9be09bb 100644
--- a/sys/dev/usb/controller/xhci_mv.c
+++ b/sys/dev/usb/controller/xhci_mv.c
@@ -171,15 +171,8 @@ static int
xhci_detach(device_t dev)
{
struct xhci_softc *sc = device_get_softc(dev);
- device_t bdev;
int err;
- if (sc->sc_bus.bdev != NULL) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
-
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/dev/usb/controller/xhci_pci.c b/sys/dev/usb/controller/xhci_pci.c
index 09fab21..35d1ea4 100644
--- a/sys/dev/usb/controller/xhci_pci.c
+++ b/sys/dev/usb/controller/xhci_pci.c
@@ -340,13 +340,7 @@ static int
xhci_pci_detach(device_t self)
{
struct xhci_softc *sc = device_get_softc(self);
- device_t bdev;
- if (sc->sc_bus.bdev != NULL) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(self);
diff --git a/sys/dev/usb/input/ums.c b/sys/dev/usb/input/ums.c
index 4d60517..a7c0600 100644
--- a/sys/dev/usb/input/ums.c
+++ b/sys/dev/usb/input/ums.c
@@ -173,6 +173,8 @@ static usb_fifo_ioctl_t ums_fifo_ioctl;
#ifdef EVDEV_SUPPORT
static evdev_open_t ums_ev_open;
static evdev_close_t ums_ev_close;
+static void ums_evdev_push(struct ums_softc *, int32_t, int32_t,
+ int32_t, int32_t, int32_t);
#endif
static void ums_start_rx(struct ums_softc *);
@@ -205,6 +207,9 @@ ums_put_queue_timeout(void *__sc)
mtx_assert(&sc->sc_mtx, MA_OWNED);
ums_put_queue(sc, 0, 0, 0, 0, 0);
+#ifdef EVDEV_SUPPORT
+ ums_evdev_push(sc, 0, 0, 0, 0, 0);
+#endif
}
static void
@@ -216,6 +221,9 @@ ums_intr_callback(struct usb_xfer *xfer, usb_error_t error)
uint8_t *buf = sc->sc_temp;
int32_t buttons = 0;
int32_t buttons_found = 0;
+#ifdef EVDEV_SUPPORT
+ int32_t buttons_reported = 0;
+#endif
int32_t dw = 0;
int32_t dx = 0;
int32_t dy = 0;
@@ -287,8 +295,11 @@ ums_intr_callback(struct usb_xfer *xfer, usb_error_t error)
}
if ((info->sc_flags & UMS_FLAG_T_AXIS) &&
- (id == info->sc_iid_t))
+ (id == info->sc_iid_t)) {
dt -= hid_get_data(buf, len, &info->sc_loc_t);
+ /* T-axis is translated into button presses */
+ buttons_found |= (1UL << 5) | (1UL << 6);
+ }
for (i = 0; i < info->sc_buttons; i++) {
uint32_t mask;
@@ -306,6 +317,9 @@ ums_intr_callback(struct usb_xfer *xfer, usb_error_t error)
if (++info != &sc->sc_info[UMS_INFO_MAX])
goto repeat;
+#ifdef EVDEV_SUPPORT
+ buttons_reported = buttons;
+#endif
/* keep old button value(s) for non-detected buttons */
buttons |= sc->sc_status.button & ~buttons_found;
@@ -316,10 +330,13 @@ ums_intr_callback(struct usb_xfer *xfer, usb_error_t error)
dx, dy, dz, dt, dw, buttons);
/* translate T-axis into button presses until further */
- if (dt > 0)
+ if (dt > 0) {
+ ums_put_queue(sc, 0, 0, 0, 0, buttons);
buttons |= 1UL << 5;
- else if (dt < 0)
+ } else if (dt < 0) {
+ ums_put_queue(sc, 0, 0, 0, 0, buttons);
buttons |= 1UL << 6;
+ }
sc->sc_status.button = buttons;
sc->sc_status.dx += dx;
@@ -351,6 +368,11 @@ ums_intr_callback(struct usb_xfer *xfer, usb_error_t error)
usb_callout_stop(&sc->sc_callout);
ums_put_queue(sc, dx, dy, dz, dt, buttons);
+#ifdef EVDEV_SUPPORT
+ ums_evdev_push(sc, dx, dy, dz, dt,
+ buttons_reported);
+#endif
+
}
}
case USB_ST_SETUP:
@@ -720,7 +742,7 @@ ums_attach(device_t dev)
for (i = 0; i < info->sc_buttons; i++)
evdev_support_key(sc->sc_evdev, BTN_MOUSE + i);
- err = evdev_register(sc->sc_evdev);
+ err = evdev_register_mtx(sc->sc_evdev, &sc->sc_mtx);
if (err)
goto detach;
#endif
@@ -891,27 +913,32 @@ ums_put_queue(struct ums_softc *sc, int32_t dx, int32_t dy,
}
usb_fifo_put_data_linear(sc->sc_fifo.fp[USB_FIFO_RX], buf,
sc->sc_mode.packetsize, 1);
-
-#ifdef EVDEV_SUPPORT
- if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) {
- /* Push evdev event */
- evdev_push_event(sc->sc_evdev, EV_REL, REL_X, dx);
- evdev_push_event(sc->sc_evdev, EV_REL, REL_Y, -dy);
- evdev_push_event(sc->sc_evdev, EV_REL, REL_WHEEL, -dz);
- evdev_push_event(sc->sc_evdev, EV_REL, REL_HWHEEL, dt);
- evdev_push_mouse_btn(sc->sc_evdev,
- (buttons & ~MOUSE_STDBUTTONS) |
- (buttons & (1 << 2) ? MOUSE_BUTTON1DOWN : 0) |
- (buttons & (1 << 1) ? MOUSE_BUTTON2DOWN : 0) |
- (buttons & (1 << 0) ? MOUSE_BUTTON3DOWN : 0));
- evdev_sync(sc->sc_evdev);
- }
-#endif
} else {
DPRINTF("Buffer full, discarded packet\n");
}
}
+#ifdef EVDEV_SUPPORT
+static void
+ums_evdev_push(struct ums_softc *sc, int32_t dx, int32_t dy,
+ int32_t dz, int32_t dt, int32_t buttons)
+{
+ if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) {
+ /* Push evdev event */
+ evdev_push_rel(sc->sc_evdev, REL_X, dx);
+ evdev_push_rel(sc->sc_evdev, REL_Y, -dy);
+ evdev_push_rel(sc->sc_evdev, REL_WHEEL, -dz);
+ evdev_push_rel(sc->sc_evdev, REL_HWHEEL, dt);
+ evdev_push_mouse_btn(sc->sc_evdev,
+ (buttons & ~MOUSE_STDBUTTONS) |
+ (buttons & (1 << 2) ? MOUSE_BUTTON1DOWN : 0) |
+ (buttons & (1 << 1) ? MOUSE_BUTTON2DOWN : 0) |
+ (buttons & (1 << 0) ? MOUSE_BUTTON3DOWN : 0));
+ evdev_sync(sc->sc_evdev);
+ }
+}
+#endif
+
static void
ums_reset_buf(struct ums_softc *sc)
{
@@ -925,7 +952,7 @@ ums_ev_open(struct evdev_dev *evdev, void *ev_softc)
{
struct ums_softc *sc = (struct ums_softc *)ev_softc;
- mtx_lock(&sc->sc_mtx);
+ mtx_assert(&sc->sc_mtx, MA_OWNED);
sc->sc_evflags = UMS_EVDEV_OPENED;
@@ -934,8 +961,6 @@ ums_ev_open(struct evdev_dev *evdev, void *ev_softc)
ums_start_rx(sc);
}
- mtx_unlock(&sc->sc_mtx);
-
return (0);
}
@@ -944,14 +969,12 @@ ums_ev_close(struct evdev_dev *evdev, void *ev_softc)
{
struct ums_softc *sc = (struct ums_softc *)ev_softc;
- mtx_lock(&sc->sc_mtx);
+ mtx_assert(&sc->sc_mtx, MA_OWNED);
sc->sc_evflags = 0;
if (sc->sc_fflags == 0)
ums_stop_rx(sc);
-
- mtx_unlock(&sc->sc_mtx);
}
#endif
diff --git a/sys/dev/usb/template/usb_template_mtp.c b/sys/dev/usb/template/usb_template_mtp.c
index f0528a5..d428e99 100644
--- a/sys/dev/usb/template/usb_template_mtp.c
+++ b/sys/dev/usb/template/usb_template_mtp.c
@@ -26,7 +26,7 @@
*/
/*
- * This file contains the USB templates for an USB Message Transfer
+ * This file contains the USB templates for an USB Media Transfer
* Protocol device.
*
* NOTE: It is common practice that MTP devices use some dummy
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index b9fa7d4..41675ed 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -1103,10 +1103,8 @@ usb_detach_device_sub(struct usb_device *udev, device_t *ppdev,
device_printf(dev, "Resume failed\n");
}
}
- if (device_detach(dev)) {
- goto error;
- }
}
+ /* detach and delete child */
if (device_delete_child(udev->parent_dev, dev)) {
goto error;
}
@@ -1725,8 +1723,8 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
/* Setup USB descriptors */
err = (usb_temp_setup_by_index_p) (udev, usb_template);
if (err) {
- DPRINTFN(0, "setting up USB template failed maybe the USB "
- "template module has not been loaded\n");
+ DPRINTFN(0, "setting up USB template failed - "
+ "usb_template(4) not loaded?\n");
goto done;
}
}
diff --git a/sys/dev/usb/video/udl.c b/sys/dev/usb/video/udl.c
index 1096ed3..a15d41b 100644
--- a/sys/dev/usb/video/udl.c
+++ b/sys/dev/usb/video/udl.c
@@ -443,14 +443,9 @@ udl_detach(device_t dev)
{
struct udl_softc *sc = device_get_softc(dev);
- if (sc->sc_fbdev != NULL) {
- device_t bdev;
+ /* delete all child devices */
+ device_delete_children(dev);
- bdev = sc->sc_fbdev;
- sc->sc_fbdev = NULL;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
UDL_LOCK(sc);
sc->sc_gone = 1;
callout_stop(&sc->sc_callout);
diff --git a/sys/dev/vnic/mrml_bridge.c b/sys/dev/vnic/mrml_bridge.c
index 8d5006b..7f4dc12 100644
--- a/sys/dev/vnic/mrml_bridge.c
+++ b/sys/dev/vnic/mrml_bridge.c
@@ -263,9 +263,7 @@ mrmlb_ofw_bus_attach(device_t dev)
resource_list_init(&di->di_rl);
ofw_bus_reg_to_rl(dev, node, sc->acells, sc->scells,
&di->di_rl);
-#ifndef INTRNG
ofw_bus_intr_to_rl(dev, node, &di->di_rl, NULL);
-#endif
/* Add newbus device for this FDT node */
child = device_add_child(dev, NULL, -1);
diff --git a/sys/dev/vnic/thunder_mdio_fdt.c b/sys/dev/vnic/thunder_mdio_fdt.c
index c05c906..cc94150 100644
--- a/sys/dev/vnic/thunder_mdio_fdt.c
+++ b/sys/dev/vnic/thunder_mdio_fdt.c
@@ -271,9 +271,7 @@ mdionexus_ofw_bus_attach(device_t dev)
resource_list_init(&di->di_rl);
ofw_bus_reg_to_rl(dev, node, sc->acells, sc->scells,
&di->di_rl);
-#ifndef INTRNG
ofw_bus_intr_to_rl(dev, node, &di->di_rl, NULL);
-#endif
/* Add newbus device for this FDT node */
child = device_add_child(dev, NULL, -1);
diff --git a/sys/fs/autofs/autofs_vnops.c b/sys/fs/autofs/autofs_vnops.c
index 781338b..3dfdb55 100644
--- a/sys/fs/autofs/autofs_vnops.c
+++ b/sys/fs/autofs/autofs_vnops.c
@@ -138,11 +138,9 @@ autofs_trigger_vn(struct vnode *vp, const char *path, int pathlen,
struct vnode **newvp)
{
struct autofs_node *anp;
- struct autofs_mount *amp;
int error, lock_flags;
anp = vp->v_data;
- amp = VFSTOAUTOFS(vp->v_mount);
/*
* Release the vnode lock, so that other operations, in partcular
@@ -331,6 +329,21 @@ autofs_mkdir(struct vop_mkdir_args *ap)
return (error);
}
+static int
+autofs_print(struct vop_print_args *ap)
+{
+ struct vnode *vp;
+ struct autofs_node *anp;
+
+ vp = ap->a_vp;
+ anp = vp->v_data;
+
+ printf(" name \"%s\", fileno %d, cached %d, wildcards %d\n",
+ anp->an_name, anp->an_fileno, anp->an_cached, anp->an_wildcards);
+
+ return (0);
+}
+
/*
* Write out a single 'struct dirent', based on 'name' and 'fileno' arguments.
*/
@@ -531,6 +544,7 @@ struct vop_vector autofs_vnodeops = {
.vop_link = VOP_EOPNOTSUPP,
.vop_mkdir = autofs_mkdir,
.vop_mknod = VOP_EOPNOTSUPP,
+ .vop_print = autofs_print,
.vop_read = VOP_EOPNOTSUPP,
.vop_readdir = autofs_readdir,
.vop_remove = VOP_EOPNOTSUPP,
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index 1b90d02..c60f643 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -70,6 +70,11 @@ SYSCTL_INT(_vfs_nfsd, OID_AUTO, v4statelimit, CTLFLAG_RWTUN,
&nfsrv_v4statelimit, 0,
"High water limit for NFSv4 opens+locks+delegations");
+static int nfsrv_writedelegifpos = 0;
+SYSCTL_INT(_vfs_nfsd, OID_AUTO, writedelegifpos, CTLFLAG_RW,
+ &nfsrv_writedelegifpos, 0,
+ "Issue a write delegation for read opens if possible");
+
/*
* Hash lists for nfs V4.
*/
@@ -80,7 +85,6 @@ struct nfssessionhash *nfssessionhash;
static u_int32_t nfsrv_openpluslock = 0, nfsrv_delegatecnt = 0;
static time_t nfsrvboottime;
-static int nfsrv_writedelegifpos = 1;
static int nfsrv_returnoldstateid = 0, nfsrv_clients = 0;
static int nfsrv_clienthighwater = NFSRV_CLIENTHIGHWATER;
static int nfsrv_nogsscallback = 0;
diff --git a/sys/fs/nullfs/null_subr.c b/sys/fs/nullfs/null_subr.c
index 4d29add..39aa689 100644
--- a/sys/fs/nullfs/null_subr.c
+++ b/sys/fs/nullfs/null_subr.c
@@ -238,7 +238,7 @@ null_nodeget(mp, lowervp, vpp)
*/
xp = malloc(sizeof(struct null_node), M_NULLFSNODE, M_WAITOK);
- error = getnewvnode("null", mp, &null_vnodeops, &vp);
+ error = getnewvnode("nullfs", mp, &null_vnodeops, &vp);
if (error) {
vput(lowervp);
free(xp, M_NULLFSNODE);
diff --git a/sys/i386/i386/db_disasm.c b/sys/i386/i386/db_disasm.c
index 2b398da..5728fe5 100644
--- a/sys/i386/i386/db_disasm.c
+++ b/sys/i386/i386/db_disasm.c
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
* Instruction disassembler.
*/
#include <sys/param.h>
+#include <sys/kdb.h>
#include <ddb/ddb.h>
#include <ddb/db_access.h>
@@ -1168,9 +1169,17 @@ db_disasm(db_addr_t loc, bool altfmt)
int len;
struct i_addr address;
+ if (db_segsize(kdb_frame) == 16)
+ altfmt = !altfmt;
get_value_inc(inst, loc, 1, FALSE);
- short_addr = FALSE;
- size = LONG;
+ if (altfmt) {
+ short_addr = TRUE;
+ size = WORD;
+ }
+ else {
+ short_addr = FALSE;
+ size = LONG;
+ }
seg = NULL;
/*
diff --git a/sys/i386/i386/db_interface.c b/sys/i386/i386/db_interface.c
index 7079e56..3c0ac81 100644
--- a/sys/i386/i386/db_interface.c
+++ b/sys/i386/i386/db_interface.c
@@ -135,6 +135,30 @@ db_write_bytes(vm_offset_t addr, size_t size, char *data)
return (ret);
}
+int
+db_segsize(struct trapframe *tfp)
+{
+ struct proc_ldt *plp;
+ struct segment_descriptor *sdp;
+ int sel;
+
+ if (tfp == NULL)
+ return (32);
+ if (tfp->tf_eflags & PSL_VM)
+ return (16);
+ sel = tfp->tf_cs & 0xffff;
+ if (sel == GSEL(GCODE_SEL, SEL_KPL))
+ return (32);
+ /* Rare cases follow. User mode cases are currently unreachable. */
+ if (ISLDT(sel)) {
+ plp = curthread->td_proc->p_md.md_ldt;
+ sdp = (plp != NULL) ? &plp->ldt_sd : &ldt[0].sd;
+ } else {
+ sdp = &gdt[PCPU_GET(cpuid) * NGDT].sd;
+ }
+ return (sdp[IDXSEL(sel)].sd_def32 == 0 ? 16 : 32);
+}
+
void
db_show_mdpcpu(struct pcpu *pc)
{
diff --git a/sys/i386/i386/db_trace.c b/sys/i386/i386/db_trace.c
index 3563579..4f5f413 100644
--- a/sys/i386/i386/db_trace.c
+++ b/sys/i386/i386/db_trace.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysent.h>
#include <machine/cpu.h>
+#include <machine/frame.h>
#include <machine/md_var.h>
#include <machine/pcb.h>
#include <machine/reg.h>
@@ -81,8 +82,7 @@ struct db_variable *db_eregs = db_regs + nitems(db_regs);
static __inline int
get_esp(struct trapframe *tf)
{
- return ((ISPL(tf->tf_cs)) ? tf->tf_esp :
- (db_expr_t)tf + (uintptr_t)DB_OFFSET(tf_esp));
+ return (TF_HAS_STACKREGS(tf) ? tf->tf_esp : (intptr_t)&tf->tf_esp);
}
static int
@@ -104,12 +104,32 @@ db_frame(struct db_variable *vp, db_expr_t *valuep, int op)
static int
db_frame_seg(struct db_variable *vp, db_expr_t *valuep, int op)
{
+ struct trapframe_vm86 *tfp;
+ int off;
uint16_t *reg;
if (kdb_frame == NULL)
return (0);
- reg = (uint16_t *)((uintptr_t)kdb_frame + (db_expr_t)vp->valuep);
+ off = (intptr_t)vp->valuep;
+ if (kdb_frame->tf_eflags & PSL_VM) {
+ tfp = (void *)kdb_frame;
+ switch ((intptr_t)vp->valuep) {
+ case (intptr_t)DB_OFFSET(tf_cs):
+ reg = (uint16_t *)&tfp->tf_cs;
+ break;
+ case (intptr_t)DB_OFFSET(tf_ds):
+ reg = (uint16_t *)&tfp->tf_vm86_ds;
+ break;
+ case (intptr_t)DB_OFFSET(tf_es):
+ reg = (uint16_t *)&tfp->tf_vm86_es;
+ break;
+ case (intptr_t)DB_OFFSET(tf_fs):
+ reg = (uint16_t *)&tfp->tf_vm86_fs;
+ break;
+ }
+ } else
+ reg = (uint16_t *)((uintptr_t)kdb_frame + off);
if (op == DB_VAR_GET)
*valuep = *reg;
else
@@ -126,7 +146,7 @@ db_esp(struct db_variable *vp, db_expr_t *valuep, int op)
if (op == DB_VAR_GET)
*valuep = get_esp(kdb_frame);
- else if (ISPL(kdb_frame->tf_cs))
+ else if (TF_HAS_STACKREGS(kdb_frame))
kdb_frame->tf_esp = *valuep;
return (1);
}
@@ -134,7 +154,16 @@ db_esp(struct db_variable *vp, db_expr_t *valuep, int op)
static int
db_gs(struct db_variable *vp, db_expr_t *valuep, int op)
{
+ struct trapframe_vm86 *tfp;
+ if (kdb_frame != NULL && kdb_frame->tf_eflags & PSL_VM) {
+ tfp = (void *)kdb_frame;
+ if (op == DB_VAR_GET)
+ *valuep = tfp->tf_vm86_gs;
+ else
+ tfp->tf_vm86_gs = *valuep;
+ return (1);
+ }
if (op == DB_VAR_GET)
*valuep = rgs();
else
@@ -150,8 +179,9 @@ db_ss(struct db_variable *vp, db_expr_t *valuep, int op)
return (0);
if (op == DB_VAR_GET)
- *valuep = (ISPL(kdb_frame->tf_cs)) ? kdb_frame->tf_ss : rss();
- else if (ISPL(kdb_frame->tf_cs))
+ *valuep = TF_HAS_STACKREGS(kdb_frame) ? kdb_frame->tf_ss :
+ rss();
+ else if (TF_HAS_STACKREGS(kdb_frame))
kdb_frame->tf_ss = *valuep;
return (1);
}
@@ -391,6 +421,17 @@ db_backtrace(struct thread *td, struct trapframe *tf, struct i386_frame *frame,
int instr, narg;
boolean_t first;
+ if (db_segsize(tf) == 16) {
+ db_printf(
+"--- 16-bit%s, cs:eip = %#x:%#x, ss:esp = %#x:%#x, ebp = %#x, tf = %p ---\n",
+ (tf->tf_eflags & PSL_VM) ? " (vm86)" : "",
+ tf->tf_cs, tf->tf_eip,
+ TF_HAS_STACKREGS(tf) ? tf->tf_ss : rss(),
+ TF_HAS_STACKREGS(tf) ? tf->tf_esp : (intptr_t)&tf->tf_esp,
+ tf->tf_ebp, tf);
+ return (0);
+ }
+
/*
* If an indirect call via an invalid pointer caused a trap,
* %pc contains the invalid address while the return address
@@ -408,7 +449,7 @@ db_backtrace(struct thread *td, struct trapframe *tf, struct i386_frame *frame,
* Find where the trap frame actually ends.
* It won't contain tf_esp or tf_ss unless crossing rings.
*/
- if (ISPL(kdb_frame->tf_cs))
+ if (TF_HAS_STACKREGS(kdb_frame))
instr = (int)(kdb_frame + 1);
else
instr = (int)&kdb_frame->tf_esp;
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index c540a49..3cf0c5a 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -158,14 +158,6 @@ static char *trap_msg[] = {
int has_f00f_bug = 0; /* Initialized so that it can be patched. */
#endif
-#ifdef KDB
-static int kdb_on_nmi = 1;
-SYSCTL_INT(_machdep, OID_AUTO, kdb_on_nmi, CTLFLAG_RWTUN,
- &kdb_on_nmi, 0, "Go to KDB on NMI");
-#endif
-static int panic_on_nmi = 1;
-SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RWTUN,
- &panic_on_nmi, 0, "Panic on NMI");
static int prot_fault_translation = 0;
SYSCTL_INT(_machdep, OID_AUTO, prot_fault_translation, CTLFLAG_RW,
&prot_fault_translation, 0, "Select signal to deliver on protection fault");
@@ -189,7 +181,10 @@ trap(struct trapframe *frame)
#endif
struct thread *td = curthread;
struct proc *p = td->td_proc;
- int i = 0, ucode = 0, code;
+#ifdef KDB
+ register_t dr6;
+#endif
+ int i = 0, ucode = 0;
u_int type;
register_t addr = 0;
vm_offset_t eva;
@@ -267,7 +262,8 @@ trap(struct trapframe *frame)
* interrupts disabled until they are accidentally
* enabled later.
*/
- if (ISPL(frame->tf_cs) == SEL_UPL || (frame->tf_eflags & PSL_VM))
+ if (TRAPF_USERMODE(frame) &&
+ (curpcb->pcb_flags & PCB_VM86CALL) == 0)
uprintf(
"pid %ld (%s): trap %d with interrupts disabled\n",
(long)curproc->p_pid, curthread->td_name, type);
@@ -291,7 +287,6 @@ trap(struct trapframe *frame)
}
}
eva = 0;
- code = frame->tf_err;
if (type == T_PAGEFLT) {
/*
* For some Cyrix CPUs, %cr2 is clobbered by
@@ -307,9 +302,7 @@ trap(struct trapframe *frame)
enable_intr();
}
- if ((ISPL(frame->tf_cs) == SEL_UPL) ||
- ((frame->tf_eflags & PSL_VM) &&
- !(curpcb->pcb_flags & PCB_VM86CALL))) {
+ if (TRAPF_USERMODE(frame) && (curpcb->pcb_flags & PCB_VM86CALL) == 0) {
/* user trap */
td->td_pticks = 0;
@@ -335,6 +328,7 @@ trap(struct trapframe *frame)
goto out;
}
#endif
+user_trctrap_out:
frame->tf_eflags &= ~PSL_T;
i = SIGTRAP;
ucode = (type == T_TRCTRAP ? TRAP_TRACE : TRAP_BRKPT);
@@ -360,6 +354,11 @@ trap(struct trapframe *frame)
case T_STKFLT: /* stack fault */
if (frame->tf_eflags & PSL_VM) {
i = vm86_emulate((struct vm86frame *)frame);
+ if (i == SIGTRAP) {
+ type = T_TRCTRAP;
+ load_dr6(rdr6() | 0x4000);
+ goto user_trctrap_out;
+ }
if (i == 0)
goto user;
break;
@@ -460,21 +459,7 @@ trap(struct trapframe *frame)
}
goto userout;
#else /* !POWERFAIL_NMI */
- /* machine/parity/power fail/"kitchen sink" faults */
- if (isa_nmi(code) == 0) {
-#ifdef KDB
- /*
- * NMI can be hooked up to a pushbutton
- * for debugging.
- */
- if (kdb_on_nmi) {
- printf ("NMI ... going to debugger\n");
- kdb_trap(type, 0, frame);
- }
-#endif /* KDB */
- goto userout;
- } else if (panic_on_nmi)
- panic("NMI indicates hardware failure");
+ nmi_handle_intr(type, frame);
break;
#endif /* POWERFAIL_NMI */
#endif /* DEV_ISA */
@@ -566,6 +551,11 @@ trap(struct trapframe *frame)
case T_STKFLT: /* stack fault */
if (frame->tf_eflags & PSL_VM) {
i = vm86_emulate((struct vm86frame *)frame);
+ if (i == SIGTRAP) {
+ type = T_TRCTRAP;
+ load_dr6(rdr6() | 0x4000);
+ goto kernel_trctrap;
+ }
if (i != 0)
/*
* returns to original process
@@ -654,6 +644,7 @@ trap(struct trapframe *frame)
break;
case T_TRCTRAP: /* trace trap */
+kernel_trctrap:
if (frame->tf_eip == (int)IDTVEC(lcall_syscall)) {
/*
* We've just entered system mode via the
@@ -687,7 +678,7 @@ trap(struct trapframe *frame)
* Reset breakpoint bits because the
* processor doesn't
*/
- load_dr6(rdr6() & 0xfffffff0);
+ load_dr6(rdr6() & ~0xf);
goto out;
}
/*
@@ -699,7 +690,10 @@ trap(struct trapframe *frame)
* Otherwise, debugger traps "can't happen".
*/
#ifdef KDB
- if (kdb_trap(type, 0, frame))
+ /* XXX %dr6 is not quite reentrant. */
+ dr6 = rdr6();
+ load_dr6(dr6 & ~0x4000);
+ if (kdb_trap(type, dr6, frame))
goto out;
#endif
break;
@@ -714,22 +708,8 @@ trap(struct trapframe *frame)
}
goto out;
#else /* !POWERFAIL_NMI */
- /* machine/parity/power fail/"kitchen sink" faults */
- if (isa_nmi(code) == 0) {
-#ifdef KDB
- /*
- * NMI can be hooked up to a pushbutton
- * for debugging.
- */
- if (kdb_on_nmi) {
- printf ("NMI ... going to debugger\n");
- kdb_trap(type, 0, frame);
- }
-#endif /* KDB */
- goto out;
- } else if (panic_on_nmi == 0)
- goto out;
- /* FALLTHROUGH */
+ nmi_handle_intr(type, frame);
+ goto out;
#endif /* POWERFAIL_NMI */
#endif /* DEV_ISA */
}
@@ -953,7 +933,7 @@ trap_fatal(frame, eva)
}
printf("instruction pointer = 0x%x:0x%x\n",
frame->tf_cs & 0xffff, frame->tf_eip);
- if ((ISPL(frame->tf_cs) == SEL_UPL) || (frame->tf_eflags & PSL_VM)) {
+ if (TF_HAS_STACKREGS(frame)) {
ss = frame->tf_ss & 0xffff;
esp = frame->tf_esp;
} else {
@@ -1107,7 +1087,8 @@ syscall(struct trapframe *frame)
ksiginfo_t ksi;
#ifdef DIAGNOSTIC
- if (ISPL(frame->tf_cs) != SEL_UPL) {
+ if (!(TRAPF_USERMODE(frame) &&
+ (curpcb->pcb_flags & PCB_VM86CALL) == 0)) {
panic("syscall");
/* NOT REACHED */
}
diff --git a/sys/i386/i386/vm86.c b/sys/i386/i386/vm86.c
index 93ff855..baa1912 100644
--- a/sys/i386/i386/vm86.c
+++ b/sys/i386/i386/vm86.c
@@ -171,7 +171,7 @@ vm86_emulate(vmf)
PUSHL((vmf->vmf_eflags & PUSH_MASK)
| PSL_IOPL, vmf);
vmf->vmf_ip += inc_ip;
- return (0);
+ return (retcode);
case POPF:
temp_flags = POPL(vmf) & POP_MASK;
@@ -185,7 +185,7 @@ vm86_emulate(vmf)
} else {
vmf->vmf_eflags &= ~PSL_VIF;
}
- return (0);
+ return (retcode);
}
break;
@@ -203,7 +203,7 @@ vm86_emulate(vmf)
case INTn:
break;
- /* VME if trying to set PSL_TF, or PSL_I when VIP is set */
+ /* VME if trying to set PSL_T, or PSL_I when VIP is set */
case POPF:
temp_flags = POP(vmf) & POP_MASK;
vmf->vmf_flags = (vmf->vmf_flags & ~POP_MASK)
@@ -218,7 +218,7 @@ vm86_emulate(vmf)
}
return (retcode);
- /* VME if trying to set PSL_TF, or PSL_I when VIP is set */
+ /* VME if trying to set PSL_T, or PSL_I when VIP is set */
case IRET:
vmf->vmf_ip = POP(vmf);
vmf->vmf_cs = POP(vmf);
diff --git a/sys/i386/include/cputypes.h b/sys/i386/include/cputypes.h
index fb0fa47..02af4f1 100644
--- a/sys/i386/include/cputypes.h
+++ b/sys/i386/include/cputypes.h
@@ -63,4 +63,9 @@
#define CPU_P4 16 /* Intel Pentium 4 */
#define CPU_GEODE1100 17 /* NS Geode SC1100 */
+#ifndef LOCORE
+extern int cpu;
+extern int cpu_class;
+#endif
+
#endif /* !_MACHINE_CPUTYPES_H_ */
diff --git a/sys/i386/include/db_machdep.h b/sys/i386/include/db_machdep.h
index 27207a8..e8d1d8e 100644
--- a/sys/i386/include/db_machdep.h
+++ b/sys/i386/include/db_machdep.h
@@ -35,7 +35,10 @@
typedef vm_offset_t db_addr_t; /* address - unsigned */
typedef int db_expr_t; /* expression - signed */
-#define PC_REGS() ((db_addr_t)kdb_thrctx->pcb_eip)
+#define PC_REGS() ((db_addr_t)(kdb_frame->tf_eflags & PSL_VM ? \
+ (kdb_frame->tf_eip & 0xffff) + \
+ ((kdb_frame->tf_cs & 0xffff) << 4) : \
+ kdb_frame->tf_eip))
#define BKPT_INST 0xcc /* breakpoint instruction */
#define BKPT_SIZE (1) /* size of breakpoint inst */
@@ -56,12 +59,16 @@ do { \
#define db_clear_single_step kdb_cpu_clear_singlestep
#define db_set_single_step kdb_cpu_set_singlestep
-#define IS_BREAKPOINT_TRAP(type, code) ((type) == T_BPTFLT)
/*
- * Watchpoints are not supported. The debug exception type is in %dr6
- * and not yet in the args to this macro.
+ * The debug exception type is copied from %dr6 to 'code' and used to
+ * disambiguate single step traps. Watchpoints have no special support.
+ * Our hardware breakpoints are not well integrated with ddb and are too
+ * different from watchpoints. ddb treats them as unknown traps with
+ * unknown addresses and doesn't turn them off while it is running.
*/
-#define IS_WATCHPOINT_TRAP(type, code) 0
+#define IS_BREAKPOINT_TRAP(type, code) ((type) == T_BPTFLT)
+#define IS_SSTEP_TRAP(type, code) ((type) == T_TRCTRAP && (code) & 0x4000)
+#define IS_WATCHPOINT_TRAP(type, code) 0
#define I_CALL 0xe8
#define I_CALLI 0xff
@@ -91,4 +98,6 @@ do { \
#define DB_SMALL_VALUE_MAX 0x7fffffff
#define DB_SMALL_VALUE_MIN (-0x400001)
+int db_segsize(struct trapframe *tfp);
+
#endif /* !_MACHINE_DB_MACHDEP_H_ */
diff --git a/sys/i386/include/md_var.h b/sys/i386/include/md_var.h
index c4c9ca9..337f541 100644
--- a/sys/i386/include/md_var.h
+++ b/sys/i386/include/md_var.h
@@ -65,6 +65,7 @@ void i686_pagezero(void *addr);
void sse2_pagezero(void *addr);
void init_AMD_Elan_sc520(void);
vm_paddr_t kvtop(void *addr);
+void panicifcpuunsupported(void);
void ppro_reenable_apic(void);
void setidt(int idx, alias_for_inthand_t *func, int typ, int dpl, int selec);
union savefpu *get_pcb_user_save_td(struct thread *td);
diff --git a/sys/kern/bus_if.m b/sys/kern/bus_if.m
index d5a0c45..2b75438 100644
--- a/sys/kern/bus_if.m
+++ b/sys/kern/bus_if.m
@@ -418,35 +418,6 @@ METHOD int release_resource {
};
/**
- * @brief Map an interrupt
- *
- * This method is used to get an interrupt mapping data according to provided
- * hints. The hints could be modified afterwards, but only if mapping data was
- * allocated. This method is intended to be called before BUS_ALLOC_RESOURCE().
- *
- * @param _dev the parent device of @p _child
- * @param _child the device which is requesting an allocation
- * @param _rid a pointer to the resource identifier
- * @param _start a pointer to the hint at the start of the resource
- * range - pass @c 0 for any start address
- * @param _end a pointer to the hint at the end of the resource
- * range - pass @c ~0 for any end address
- * @param _count a pointer to the hint at the size of resource
- * range required - pass @c 1 for any size
- * @param _imd a pointer to the interrupt mapping data which was
- * allocated
- */
-METHOD int map_intr {
- device_t _dev;
- device_t _child;
- int *_rid;
- rman_res_t *_start;
- rman_res_t *_end;
- rman_res_t *_count;
- struct intr_map_data **_imd;
-} DEFAULT bus_generic_map_intr;
-
-/**
* @brief Install an interrupt handler
*
* This method is used to associate an interrupt handler function with
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 358cce3..f12b1d2 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -170,13 +170,7 @@ _sleep(void *ident, struct lock_object *lock, int priority,
catch = priority & PCATCH;
pri = priority & PRIMASK;
- /*
- * If we are already on a sleep queue, then remove us from that
- * sleep queue first. We have to do this to handle recursive
- * sleeps.
- */
- if (TD_ON_SLEEPQ(td))
- sleepq_remove(td, td->td_wchan);
+ KASSERT(!TD_ON_SLEEPQ(td), ("recursive sleep"));
if ((uint8_t *)ident >= &pause_wchan[0] &&
(uint8_t *)ident <= &pause_wchan[MAXCPU - 1])
diff --git a/sys/kern/pic_if.m b/sys/kern/pic_if.m
index 3003c35..1787b06 100644
--- a/sys/kern/pic_if.m
+++ b/sys/kern/pic_if.m
@@ -43,7 +43,7 @@ CODE {
}
static int
- null_pic_alloc_intr(device_t dev, struct intr_irqsrc *isrc,
+ null_pic_activate_intr(device_t dev, struct intr_irqsrc *isrc,
struct resource *res, struct intr_map_data *data)
{
@@ -51,7 +51,7 @@ CODE {
}
static int
- null_pic_release_intr(device_t dev, struct intr_irqsrc *isrc,
+ null_pic_deactivate_intr(device_t dev, struct intr_irqsrc *isrc,
struct resource *res, struct intr_map_data *data)
{
@@ -92,12 +92,12 @@ CODE {
}
};
-METHOD int alloc_intr {
+METHOD int activate_intr {
device_t dev;
struct intr_irqsrc *isrc;
struct resource *res;
struct intr_map_data *data;
-} DEFAULT null_pic_alloc_intr;
+} DEFAULT null_pic_activate_intr;
METHOD int bind_intr {
device_t dev;
@@ -120,12 +120,12 @@ METHOD int map_intr {
struct intr_irqsrc **isrcp;
};
-METHOD int release_intr {
+METHOD int deactivate_intr {
device_t dev;
struct intr_irqsrc *isrc;
struct resource *res;
struct intr_map_data *data;
-} DEFAULT null_pic_release_intr;
+} DEFAULT null_pic_deactivate_intr;
METHOD int setup_intr {
device_t dev;
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index b28a8cb..66567ca 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -1949,15 +1949,17 @@ device_delete_child(device_t dev, device_t child)
PDEBUG(("%s from %s", DEVICENAME(child), DEVICENAME(dev)));
- /* remove children first */
+ /* detach parent before deleting children, if any */
+ if ((error = device_detach(child)) != 0)
+ return (error);
+
+ /* remove children second */
while ((grandchild = TAILQ_FIRST(&child->children)) != NULL) {
error = device_delete_child(child, grandchild);
if (error)
return (error);
}
- if ((error = device_detach(child)) != 0)
- return (error);
if (child->devclass)
devclass_delete_device(child->devclass, child);
if (child->parent)
@@ -3958,23 +3960,6 @@ bus_generic_new_pass(device_t dev)
}
/**
- * @brief Helper function for implementing BUS_MAP_INTR().
- *
- * This simple implementation of BUS_MAP_INTR() simply calls the
- * BUS_MAP_INTR() method of the parent of @p dev.
- */
-int
-bus_generic_map_intr(device_t dev, device_t child, int *rid, rman_res_t *start,
- rman_res_t *end, rman_res_t *count, struct intr_map_data **imd)
-{
- /* Propagate up the bus hierarchy until someone handles it. */
- if (dev->parent)
- return (BUS_MAP_INTR(dev->parent, child, rid, start, end, count,
- imd));
- return (EINVAL);
-}
-
-/**
* @brief Helper function for implementing BUS_SETUP_INTR().
*
* This simple implementation of BUS_SETUP_INTR() simply calls the
@@ -4429,41 +4414,6 @@ bus_release_resources(device_t dev, const struct resource_spec *rs,
}
}
-#ifdef INTRNG
-/**
- * @internal
- *
- * This can be converted to bus method later. (XXX)
- */
-static struct intr_map_data *
-bus_extend_resource(device_t dev, int type, int *rid, rman_res_t *start,
- rman_res_t *end, rman_res_t *count)
-{
- struct intr_map_data *imd;
- struct resource_list *rl;
- int rv;
-
- if (dev->parent == NULL)
- return (NULL);
- if (type != SYS_RES_IRQ)
- return (NULL);
-
- if (!RMAN_IS_DEFAULT_RANGE(*start, *end))
- return (NULL);
- rl = BUS_GET_RESOURCE_LIST(dev->parent, dev);
- if (rl != NULL) {
- if (resource_list_find(rl, type, *rid) != NULL)
- return (NULL);
- }
- rv = BUS_MAP_INTR(dev->parent, dev, rid, start, end, count, &imd);
- if (rv != 0)
- return (NULL);
- if (rl != NULL)
- resource_list_add(rl, type, *rid, *start, *end, *count);
- return (imd);
-}
-#endif
-
/**
* @brief Wrapper function for BUS_ALLOC_RESOURCE().
*
@@ -4475,26 +4425,11 @@ bus_alloc_resource(device_t dev, int type, int *rid, rman_res_t start,
rman_res_t end, rman_res_t count, u_int flags)
{
struct resource *res;
-#ifdef INTRNG
- struct intr_map_data *imd;
-#endif
if (dev->parent == NULL)
return (NULL);
-
-#ifdef INTRNG
- imd = bus_extend_resource(dev, type, rid, &start, &end, &count);
-#endif
res = BUS_ALLOC_RESOURCE(dev->parent, dev, type, rid, start, end,
count, flags);
-#ifdef INTRNG
- if (imd != NULL) {
- if (res != NULL && rman_get_virtual(res) == NULL)
- rman_set_virtual(res, imd);
- else
- imd->destruct(imd);
- }
-#endif
return (res);
}
@@ -4581,21 +4516,10 @@ int
bus_release_resource(device_t dev, int type, int rid, struct resource *r)
{
int rv;
-#ifdef INTRNG
- struct intr_map_data *imd;
-#endif
if (dev->parent == NULL)
return (EINVAL);
-
-#ifdef INTRNG
- imd = (type == SYS_RES_IRQ) ? rman_get_virtual(r) : NULL;
-#endif
rv = BUS_RELEASE_RESOURCE(dev->parent, dev, type, rid, r);
-#ifdef INTRNG
- if (imd != NULL)
- imd->destruct(imd);
-#endif
return (rv);
}
diff --git a/sys/kern/subr_intr.c b/sys/kern/subr_intr.c
index 64d37ed..98e7b47 100644
--- a/sys/kern/subr_intr.c
+++ b/sys/kern/subr_intr.c
@@ -31,8 +31,9 @@ __FBSDID("$FreeBSD$");
/*
* New-style Interrupt Framework
*
- * TODO: - to support IPI (PPI) enabling on other CPUs if already started
- * - to complete things for removable PICs
+ * TODO: - add support for disconnected PICs.
+ * - to support IPI (PPI) enabling on other CPUs if already started.
+ * - to complete things for removable PICs.
*/
#include "opt_ddb.h"
@@ -142,6 +143,12 @@ size_t sintrcnt = sizeof(intrcnt);
size_t sintrnames = sizeof(intrnames);
static u_int intrcnt_index;
+static struct intr_irqsrc *intr_map_get_isrc(u_int res_id);
+static void intr_map_set_isrc(u_int res_id, struct intr_irqsrc *isrc);
+static struct intr_map_data * intr_map_get_map_data(u_int res_id);
+static void intr_map_copy_map_data(u_int res_id, device_t *dev, intptr_t *xref,
+ struct intr_map_data **data);
+
/*
* Interrupt framework initialization routine.
*/
@@ -414,18 +421,6 @@ isrc_free_irq(struct intr_irqsrc *isrc)
}
/*
- * Lookup interrupt source by interrupt number (resource handle).
- */
-static inline struct intr_irqsrc *
-isrc_lookup(u_int irq)
-{
-
- if (irq < nitems(irq_sources))
- return (irq_sources[irq]);
- return (NULL);
-}
-
-/*
* Initialize interrupt source and register it into global interrupt table.
*/
int
@@ -899,13 +894,12 @@ intr_pic_add_handler(device_t parent, struct intr_pic *pic,
return (pic);
}
-int
-intr_map_irq(device_t dev, intptr_t xref, struct intr_map_data *data,
- u_int *irqp)
+static int
+intr_resolve_irq(device_t dev, intptr_t xref, struct intr_map_data *data,
+ struct intr_irqsrc **isrc)
{
- int error;
- struct intr_irqsrc *isrc;
struct intr_pic *pic;
+ struct intr_map_data_msi *msi;
if (data == NULL)
return (EINVAL);
@@ -914,48 +908,77 @@ intr_map_irq(device_t dev, intptr_t xref, struct intr_map_data *data,
if (pic == NULL)
return (ESRCH);
- KASSERT((pic->pic_flags & FLAG_PIC) != 0,
- ("%s: Found a non-PIC controller: %s", __func__,
- device_get_name(pic->pic_dev)));
+ switch (data->type) {
+ case INTR_MAP_DATA_MSI:
+ KASSERT((pic->pic_flags & FLAG_MSI) != 0,
+ ("%s: Found a non-MSI controller: %s", __func__,
+ device_get_name(pic->pic_dev)));
+ msi = (struct intr_map_data_msi *)data;
+ *isrc = msi->isrc;
+ return (0);
- error = PIC_MAP_INTR(pic->pic_dev, data, &isrc);
- if (error == 0)
- *irqp = isrc->isrc_irq;
- return (error);
+ default:
+ KASSERT((pic->pic_flags & FLAG_PIC) != 0,
+ ("%s: Found a non-PIC controller: %s", __func__,
+ device_get_name(pic->pic_dev)));
+ return (PIC_MAP_INTR(pic->pic_dev, data, isrc));
+
+ }
}
int
-intr_alloc_irq(device_t dev, struct resource *res)
+intr_activate_irq(device_t dev, struct resource *res)
{
+ device_t map_dev;
+ intptr_t map_xref;
struct intr_map_data *data;
struct intr_irqsrc *isrc;
+ u_int res_id;
+ int error;
KASSERT(rman_get_start(res) == rman_get_end(res),
("%s: more interrupts in resource", __func__));
- isrc = isrc_lookup(rman_get_start(res));
- if (isrc == NULL)
- return (EINVAL);
-
- data = rman_get_virtual(res);
- return (PIC_ALLOC_INTR(isrc->isrc_dev, isrc, res, data));
+ res_id = (u_int)rman_get_start(res);
+ if (intr_map_get_isrc(res_id) != NULL)
+ panic("Attempt to double activation of resource id: %u\n",
+ res_id);
+ intr_map_copy_map_data(res_id, &map_dev, &map_xref, &data);
+ error = intr_resolve_irq(map_dev, map_xref, data, &isrc);
+ if (error != 0) {
+ free(data, M_INTRNG);
+ /* XXX TODO DISCONECTED PICs */
+ /* if (error == EINVAL) return(0); */
+ return (error);
+ }
+ intr_map_set_isrc(res_id, isrc);
+ rman_set_virtual(res, data);
+ return (PIC_ACTIVATE_INTR(isrc->isrc_dev, isrc, res, data));
}
int
-intr_release_irq(device_t dev, struct resource *res)
+intr_deactivate_irq(device_t dev, struct resource *res)
{
struct intr_map_data *data;
struct intr_irqsrc *isrc;
+ u_int res_id;
+ int error;
KASSERT(rman_get_start(res) == rman_get_end(res),
("%s: more interrupts in resource", __func__));
- isrc = isrc_lookup(rman_get_start(res));
+ res_id = (u_int)rman_get_start(res);
+ isrc = intr_map_get_isrc(res_id);
if (isrc == NULL)
- return (EINVAL);
+ panic("Attempt to deactivate non-active resource id: %u\n",
+ res_id);
data = rman_get_virtual(res);
- return (PIC_RELEASE_INTR(isrc->isrc_dev, isrc, res, data));
+ error = PIC_DEACTIVATE_INTR(isrc->isrc_dev, isrc, res, data);
+ intr_map_set_isrc(res_id, NULL);
+ rman_set_virtual(res, NULL);
+ free(data, M_INTRNG);
+ return (error);
}
int
@@ -966,13 +989,17 @@ intr_setup_irq(device_t dev, struct resource *res, driver_filter_t filt,
struct intr_map_data *data;
struct intr_irqsrc *isrc;
const char *name;
+ u_int res_id;
KASSERT(rman_get_start(res) == rman_get_end(res),
("%s: more interrupts in resource", __func__));
- isrc = isrc_lookup(rman_get_start(res));
- if (isrc == NULL)
+ res_id = (u_int)rman_get_start(res);
+ isrc = intr_map_get_isrc(res_id);
+ if (isrc == NULL) {
+ /* XXX TODO DISCONECTED PICs */
return (EINVAL);
+ }
data = rman_get_virtual(res);
name = device_get_nameunit(dev);
@@ -1027,11 +1054,13 @@ intr_teardown_irq(device_t dev, struct resource *res, void *cookie)
int error;
struct intr_map_data *data;
struct intr_irqsrc *isrc;
+ u_int res_id;
KASSERT(rman_get_start(res) == rman_get_end(res),
("%s: more interrupts in resource", __func__));
- isrc = isrc_lookup(rman_get_start(res));
+ res_id = (u_int)rman_get_start(res);
+ isrc = intr_map_get_isrc(res_id);
if (isrc == NULL || isrc->isrc_handlers == 0)
return (EINVAL);
@@ -1075,11 +1104,13 @@ intr_describe_irq(device_t dev, struct resource *res, void *cookie,
{
int error;
struct intr_irqsrc *isrc;
+ u_int res_id;
KASSERT(rman_get_start(res) == rman_get_end(res),
("%s: more interrupts in resource", __func__));
- isrc = isrc_lookup(rman_get_start(res));
+ res_id = (u_int)rman_get_start(res);
+ isrc = intr_map_get_isrc(res_id);
if (isrc == NULL || isrc->isrc_handlers == 0)
return (EINVAL);
#ifdef INTR_SOLO
@@ -1107,11 +1138,13 @@ int
intr_bind_irq(device_t dev, struct resource *res, int cpu)
{
struct intr_irqsrc *isrc;
+ u_int res_id;
KASSERT(rman_get_start(res) == rman_get_end(res),
("%s: more interrupts in resource", __func__));
- isrc = isrc_lookup(rman_get_start(res));
+ res_id = (u_int)rman_get_start(res);
+ isrc = intr_map_get_isrc(res_id);
if (isrc == NULL || isrc->isrc_handlers == 0)
return (EINVAL);
#ifdef INTR_SOLO
@@ -1191,6 +1224,28 @@ intr_irq_next_cpu(u_int current_cpu, cpuset_t *cpumask)
#endif
/*
+ * Allocate memory for new intr_map_data structure.
+ * Initialize common fields.
+ */
+struct intr_map_data *
+intr_alloc_map_data(enum intr_map_data_type type, size_t len, int flags)
+{
+ struct intr_map_data *data;
+
+ data = malloc(len, M_INTRNG, flags);
+ data->type = type;
+ data->len = len;
+ return (data);
+}
+
+void intr_free_intr_map_data(struct intr_map_data *data)
+{
+
+ free(data, M_INTRNG);
+}
+
+
+/*
* Register a MSI/MSI-X interrupt controller
*/
int
@@ -1218,6 +1273,7 @@ intr_alloc_msi(device_t pci, device_t child, intptr_t xref, int count,
struct intr_irqsrc **isrc;
struct intr_pic *pic;
device_t pdev;
+ struct intr_map_data_msi *msi;
int err, i;
pic = pic_lookup(NULL, xref);
@@ -1230,12 +1286,19 @@ intr_alloc_msi(device_t pci, device_t child, intptr_t xref, int count,
isrc = malloc(sizeof(*isrc) * count, M_INTRNG, M_WAITOK);
err = MSI_ALLOC_MSI(pic->pic_dev, child, count, maxcount, &pdev, isrc);
- if (err == 0) {
- for (i = 0; i < count; i++) {
- irqs[i] = isrc[i]->isrc_irq;
- }
+ if (err != 0) {
+ free(isrc, M_INTRNG);
+ return (err);
}
+ for (i = 0; i < count; i++) {
+ msi = (struct intr_map_data_msi *)intr_alloc_map_data(
+ INTR_MAP_DATA_MSI, sizeof(*msi), M_WAITOK | M_ZERO);
+ msi-> isrc = isrc[i];
+ irqs[i] = intr_map_irq(pic->pic_dev, xref,
+ (struct intr_map_data *)msi);
+
+ }
free(isrc, M_INTRNG);
return (err);
@@ -1247,6 +1310,7 @@ intr_release_msi(device_t pci, device_t child, intptr_t xref, int count,
{
struct intr_irqsrc **isrc;
struct intr_pic *pic;
+ struct intr_map_data_msi *msi;
int i, err;
pic = pic_lookup(NULL, xref);
@@ -1260,14 +1324,21 @@ intr_release_msi(device_t pci, device_t child, intptr_t xref, int count,
isrc = malloc(sizeof(*isrc) * count, M_INTRNG, M_WAITOK);
for (i = 0; i < count; i++) {
- isrc[i] = isrc_lookup(irqs[i]);
- if (isrc == NULL) {
- free(isrc, M_INTRNG);
- return (EINVAL);
- }
+ msi = (struct intr_map_data_msi *)
+ intr_map_get_map_data(irqs[i]);
+ KASSERT(msi->hdr.type == INTR_MAP_DATA_MSI,
+ ("%s: irq %d map data is not MSI", __func__,
+ irqs[i]));
+ isrc[i] = msi->isrc;
}
err = MSI_RELEASE_MSI(pic->pic_dev, child, count, isrc);
+
+ for (i = 0; i < count; i++) {
+ if (isrc[i] != NULL)
+ intr_unmap_irq(irqs[i]);
+ }
+
free(isrc, M_INTRNG);
return (err);
}
@@ -1278,6 +1349,7 @@ intr_alloc_msix(device_t pci, device_t child, intptr_t xref, int *irq)
struct intr_irqsrc *isrc;
struct intr_pic *pic;
device_t pdev;
+ struct intr_map_data_msi *msi;
int err;
pic = pic_lookup(NULL, xref);
@@ -1288,11 +1360,15 @@ intr_alloc_msix(device_t pci, device_t child, intptr_t xref, int *irq)
("%s: Found a non-MSI controller: %s", __func__,
device_get_name(pic->pic_dev)));
+
err = MSI_ALLOC_MSIX(pic->pic_dev, child, &pdev, &isrc);
if (err != 0)
return (err);
- *irq = isrc->isrc_irq;
+ msi = (struct intr_map_data_msi *)intr_alloc_map_data(
+ INTR_MAP_DATA_MSI, sizeof(*msi), M_WAITOK | M_ZERO);
+ msi->isrc = isrc;
+ *irq = intr_map_irq(pic->pic_dev, xref, (struct intr_map_data *)msi);
return (0);
}
@@ -1301,6 +1377,7 @@ intr_release_msix(device_t pci, device_t child, intptr_t xref, int irq)
{
struct intr_irqsrc *isrc;
struct intr_pic *pic;
+ struct intr_map_data_msi *msi;
int err;
pic = pic_lookup(NULL, xref);
@@ -1311,11 +1388,20 @@ intr_release_msix(device_t pci, device_t child, intptr_t xref, int irq)
("%s: Found a non-MSI controller: %s", __func__,
device_get_name(pic->pic_dev)));
- isrc = isrc_lookup(irq);
- if (isrc == NULL)
+ msi = (struct intr_map_data_msi *)
+ intr_map_get_map_data(irq);
+ KASSERT(msi->hdr.type == INTR_MAP_DATA_MSI,
+ ("%s: irq %d map data is not MSI", __func__,
+ irq));
+ isrc = msi->isrc;
+ if (isrc == NULL) {
+ intr_unmap_irq(irq);
return (EINVAL);
+ }
err = MSI_RELEASE_MSIX(pic->pic_dev, child, isrc);
+ intr_unmap_irq(irq);
+
return (err);
}
@@ -1335,7 +1421,7 @@ intr_map_msi(device_t pci, device_t child, intptr_t xref, int irq,
("%s: Found a non-MSI controller: %s", __func__,
device_get_name(pic->pic_dev)));
- isrc = isrc_lookup(irq);
+ isrc = intr_map_get_isrc(irq);
if (isrc == NULL)
return (EINVAL);
@@ -1390,3 +1476,179 @@ DB_SHOW_COMMAND(irqs, db_show_irqs)
db_printf("irq total %u\n", irqsum);
}
#endif
+
+/*
+ * Interrupt mapping table functions.
+ *
+ * Please, keep this part separately, it can be transformed to
+ * extension of standard resources.
+ */
+struct intr_map_entry
+{
+ device_t dev;
+ intptr_t xref;
+ struct intr_map_data *map_data;
+ struct intr_irqsrc *isrc;
+ /* XXX TODO DISCONECTED PICs */
+ /*int flags */
+};
+
+/* XXX Convert irq_map[] to dynamicaly expandable one. */
+static struct intr_map_entry *irq_map[2 * NIRQ];
+static int irq_map_count = nitems(irq_map);
+static int irq_map_first_free_idx;
+static struct mtx irq_map_lock;
+
+static struct intr_irqsrc *
+intr_map_get_isrc(u_int res_id)
+{
+ struct intr_irqsrc *isrc;
+
+ mtx_lock(&irq_map_lock);
+ if ((res_id >= irq_map_count) || (irq_map[res_id] == NULL)) {
+ mtx_unlock(&irq_map_lock);
+ return (NULL);
+ }
+ isrc = irq_map[res_id]->isrc;
+ mtx_unlock(&irq_map_lock);
+ return (isrc);
+}
+
+static void
+intr_map_set_isrc(u_int res_id, struct intr_irqsrc *isrc)
+{
+
+ mtx_lock(&irq_map_lock);
+ if ((res_id >= irq_map_count) || (irq_map[res_id] == NULL)) {
+ mtx_unlock(&irq_map_lock);
+ return;
+ }
+ irq_map[res_id]->isrc = isrc;
+ mtx_unlock(&irq_map_lock);
+}
+
+/*
+ * Get a copy of intr_map_entry data
+ */
+static struct intr_map_data *
+intr_map_get_map_data(u_int res_id)
+{
+ struct intr_map_data *data;
+
+ data = NULL;
+ mtx_lock(&irq_map_lock);
+ if (res_id >= irq_map_count || irq_map[res_id] == NULL)
+ panic("Attempt to copy invalid resource id: %u\n", res_id);
+ data = irq_map[res_id]->map_data;
+ mtx_unlock(&irq_map_lock);
+
+ return (data);
+}
+
+/*
+ * Get a copy of intr_map_entry data
+ */
+static void
+intr_map_copy_map_data(u_int res_id, device_t *map_dev, intptr_t *map_xref,
+ struct intr_map_data **data)
+{
+ size_t len;
+
+ len = 0;
+ mtx_lock(&irq_map_lock);
+ if (res_id >= irq_map_count || irq_map[res_id] == NULL)
+ panic("Attempt to copy invalid resource id: %u\n", res_id);
+ if (irq_map[res_id]->map_data != NULL)
+ len = irq_map[res_id]->map_data->len;
+ mtx_unlock(&irq_map_lock);
+
+ if (len == 0)
+ *data = NULL;
+ else
+ *data = malloc(len, M_INTRNG, M_WAITOK | M_ZERO);
+ mtx_lock(&irq_map_lock);
+ if (irq_map[res_id] == NULL)
+ panic("Attempt to copy invalid resource id: %u\n", res_id);
+ if (len != 0) {
+ if (len != irq_map[res_id]->map_data->len)
+ panic("Resource id: %u has changed.\n", res_id);
+ memcpy(*data, irq_map[res_id]->map_data, len);
+ }
+ *map_dev = irq_map[res_id]->dev;
+ *map_xref = irq_map[res_id]->xref;
+ mtx_unlock(&irq_map_lock);
+}
+
+
+/*
+ * Allocate and fill new entry in irq_map table.
+ */
+u_int
+intr_map_irq(device_t dev, intptr_t xref, struct intr_map_data *data)
+{
+ u_int i;
+ struct intr_map_entry *entry;
+
+ /* Prepare new entry first. */
+ entry = malloc(sizeof(*entry), M_INTRNG, M_WAITOK | M_ZERO);
+
+ entry->dev = dev;
+ entry->xref = xref;
+ entry->map_data = data;
+ entry->isrc = NULL;
+
+ mtx_lock(&irq_map_lock);
+ for (i = irq_map_first_free_idx; i < irq_map_count; i++) {
+ if (irq_map[i] == NULL) {
+ irq_map[i] = entry;
+ irq_map_first_free_idx = i + 1;
+ mtx_unlock(&irq_map_lock);
+ return (i);
+ }
+ }
+ mtx_unlock(&irq_map_lock);
+
+ /* XXX Expand irq_map table */
+ panic("IRQ mapping table is full.");
+}
+
+/*
+ * Remove and free mapping entry.
+ */
+void
+intr_unmap_irq(u_int res_id)
+{
+ struct intr_map_entry *entry;
+
+ mtx_lock(&irq_map_lock);
+ if ((res_id >= irq_map_count) || (irq_map[res_id] == NULL))
+ panic("Attempt to unmap invalid resource id: %u\n", res_id);
+ entry = irq_map[res_id];
+ irq_map[res_id] = NULL;
+ irq_map_first_free_idx = res_id;
+ mtx_unlock(&irq_map_lock);
+ intr_free_intr_map_data(entry->map_data);
+ free(entry, M_INTRNG);
+}
+
+/*
+ * Clone mapping entry.
+ */
+u_int
+intr_map_clone_irq(u_int old_res_id)
+{
+ device_t map_dev;
+ intptr_t map_xref;
+ struct intr_map_data *data;
+
+ intr_map_copy_map_data(old_res_id, &map_dev, &map_xref, &data);
+ return (intr_map_irq(map_dev, map_xref, data));
+}
+
+static void
+intr_map_init(void *dummy __unused)
+{
+
+ mtx_init(&irq_map_lock, "intr map table", NULL, MTX_DEF);
+}
+SYSINIT(intr_map_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_map_init, NULL);
diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c
index 4f3b51d..2d1b8be 100644
--- a/sys/kern/subr_smp.c
+++ b/sys/kern/subr_smp.c
@@ -209,6 +209,11 @@ forward_signal(struct thread *td)
* 1: ok
*
*/
+#if defined(__amd64__) || defined(__i386__)
+#define X86 1
+#else
+#define X86 0
+#endif
static int
generic_stop_cpus(cpuset_t map, u_int type)
{
@@ -220,12 +225,11 @@ generic_stop_cpus(cpuset_t map, u_int type)
volatile cpuset_t *cpus;
KASSERT(
-#if defined(__amd64__) || defined(__i386__)
- type == IPI_STOP || type == IPI_STOP_HARD || type == IPI_SUSPEND,
-#else
- type == IPI_STOP || type == IPI_STOP_HARD,
+ type == IPI_STOP || type == IPI_STOP_HARD
+#if X86
+ || type == IPI_SUSPEND
#endif
- ("%s: invalid stop type", __func__));
+ , ("%s: invalid stop type", __func__));
if (!smp_started)
return (0);
@@ -233,7 +237,7 @@ generic_stop_cpus(cpuset_t map, u_int type)
CTR2(KTR_SMP, "stop_cpus(%s) with %u type",
cpusetobj_strprint(cpusetbuf, &map), type);
-#if defined(__amd64__) || defined(__i386__)
+#if X86
/*
* When suspending, ensure there are are no IPIs in progress.
* IPIs that have been issued, but not yet delivered (e.g.
@@ -245,6 +249,9 @@ generic_stop_cpus(cpuset_t map, u_int type)
mtx_lock_spin(&smp_ipi_mtx);
#endif
+#if X86
+ if (!nmi_is_broadcast || nmi_kdb_lock == 0) {
+#endif
if (stopping_cpu != PCPU_GET(cpuid))
while (atomic_cmpset_int(&stopping_cpu, NOCPU,
PCPU_GET(cpuid)) == 0)
@@ -253,8 +260,11 @@ generic_stop_cpus(cpuset_t map, u_int type)
/* send the stop IPI to all CPUs in map */
ipi_selected(map, type);
+#if X86
+ }
+#endif
-#if defined(__amd64__) || defined(__i386__)
+#if X86
if (type == IPI_SUSPEND)
cpus = &suspended_cpus;
else
@@ -272,7 +282,7 @@ generic_stop_cpus(cpuset_t map, u_int type)
}
}
-#if defined(__amd64__) || defined(__i386__)
+#if X86
if (type == IPI_SUSPEND)
mtx_unlock_spin(&smp_ipi_mtx);
#endif
@@ -295,7 +305,7 @@ stop_cpus_hard(cpuset_t map)
return (generic_stop_cpus(map, IPI_STOP_HARD));
}
-#if defined(__amd64__) || defined(__i386__)
+#if X86
int
suspend_cpus(cpuset_t map)
{
@@ -325,20 +335,18 @@ generic_restart_cpus(cpuset_t map, u_int type)
#endif
volatile cpuset_t *cpus;
- KASSERT(
-#if defined(__amd64__) || defined(__i386__)
- type == IPI_STOP || type == IPI_STOP_HARD || type == IPI_SUSPEND,
-#else
- type == IPI_STOP || type == IPI_STOP_HARD,
+ KASSERT(type == IPI_STOP || type == IPI_STOP_HARD
+#if X86
+ || type == IPI_SUSPEND
#endif
- ("%s: invalid stop type", __func__));
+ , ("%s: invalid stop type", __func__));
if (!smp_started)
- return 0;
+ return (0);
CTR1(KTR_SMP, "restart_cpus(%s)", cpusetobj_strprint(cpusetbuf, &map));
-#if defined(__amd64__) || defined(__i386__)
+#if X86
if (type == IPI_SUSPEND)
cpus = &suspended_cpus;
else
@@ -348,11 +356,17 @@ generic_restart_cpus(cpuset_t map, u_int type)
/* signal other cpus to restart */
CPU_COPY_STORE_REL(&map, &started_cpus);
+#if X86
+ if (!nmi_is_broadcast || nmi_kdb_lock == 0) {
+#endif
/* wait for each to clear its bit */
while (CPU_OVERLAP(cpus, &map))
cpu_spinwait();
+#if X86
+ }
+#endif
- return 1;
+ return (1);
}
int
@@ -362,7 +376,7 @@ restart_cpus(cpuset_t map)
return (generic_restart_cpus(map, IPI_STOP));
}
-#if defined(__amd64__) || defined(__i386__)
+#if X86
int
resume_cpus(cpuset_t map)
{
@@ -370,6 +384,7 @@ resume_cpus(cpuset_t map)
return (generic_restart_cpus(map, IPI_SUSPEND));
}
#endif
+#undef X86
/*
* All-CPU rendezvous. CPUs are signalled, all execute the setup function
diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c
index a678635..279423c 100644
--- a/sys/kern/subr_witness.c
+++ b/sys/kern/subr_witness.c
@@ -599,7 +599,7 @@ static struct witness_order_list_entry order_lists[] = {
* CDEV
*/
{ "vm map (system)", &lock_class_mtx_sleep },
- { "vm page queue", &lock_class_mtx_sleep },
+ { "vm pagequeue", &lock_class_mtx_sleep },
{ "vnode interlock", &lock_class_mtx_sleep },
{ "cdev", &lock_class_mtx_sleep },
{ NULL, NULL },
@@ -609,7 +609,7 @@ static struct witness_order_list_entry order_lists[] = {
{ "vm map (user)", &lock_class_sx },
{ "vm object", &lock_class_rw },
{ "vm page", &lock_class_mtx_sleep },
- { "vm page queue", &lock_class_mtx_sleep },
+ { "vm pagequeue", &lock_class_mtx_sleep },
{ "pmap pv global", &lock_class_rw },
{ "pmap", &lock_class_mtx_sleep },
{ "pmap pv list", &lock_class_rw },
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index 07244c9..a8c5dbf 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -73,13 +73,10 @@ SDT_PROBE_DEFINE3(vfs, namei, lookup, entry, "struct vnode *", "char *",
"unsigned long");
SDT_PROBE_DEFINE2(vfs, namei, lookup, return, "int", "struct vnode *");
-/*
- * Allocation zone for namei
- */
+/* Allocation zone for namei. */
uma_zone_t namei_zone;
-/*
- * Placeholder vnode for mp traversal
- */
+
+/* Placeholder vnode for mp traversal. */
static struct vnode *vp_crossmp;
static void
@@ -97,11 +94,12 @@ SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_SECOND, nameiinit, NULL);
static int lookup_shared = 1;
SYSCTL_INT(_vfs, OID_AUTO, lookup_shared, CTLFLAG_RWTUN, &lookup_shared, 0,
- "Enables/Disables shared locks for path name translation");
+ "enables shared locks for path name translation");
static void
namei_cleanup_cnp(struct componentname *cnp)
{
+
uma_zfree(namei_zone, cnp->cn_pnbuf);
#ifdef DIAGNOSTIC
cnp->cn_pnbuf = NULL;
@@ -158,12 +156,16 @@ namei(struct nameidata *ndp)
char *cp; /* pointer into pathname argument */
struct vnode *dp; /* the directory we are searching */
struct iovec aiov; /* uio for reading symbolic links */
+ struct componentname *cnp;
+ struct thread *td;
+ struct proc *p;
+ cap_rights_t rights;
struct uio auio;
int error, linklen, startdir_used;
- struct componentname *cnp = &ndp->ni_cnd;
- struct thread *td = cnp->cn_thread;
- struct proc *p = td->td_proc;
+ cnp = &ndp->ni_cnd;
+ td = cnp->cn_thread;
+ p = td->td_proc;
ndp->ni_cnd.cn_cred = ndp->ni_cnd.cn_thread->td_ucred;
KASSERT(cnp->cn_cred && p, ("namei: bad cred/proc"));
KASSERT((cnp->cn_nameiop & (~OPMASK)) == 0,
@@ -186,11 +188,11 @@ namei(struct nameidata *ndp)
if ((cnp->cn_flags & HASBUF) == 0)
cnp->cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK);
if (ndp->ni_segflg == UIO_SYSSPACE)
- error = copystr(ndp->ni_dirp, cnp->cn_pnbuf,
- MAXPATHLEN, (size_t *)&ndp->ni_pathlen);
+ error = copystr(ndp->ni_dirp, cnp->cn_pnbuf, MAXPATHLEN,
+ &ndp->ni_pathlen);
else
- error = copyinstr(ndp->ni_dirp, cnp->cn_pnbuf,
- MAXPATHLEN, (size_t *)&ndp->ni_pathlen);
+ error = copyinstr(ndp->ni_dirp, cnp->cn_pnbuf, MAXPATHLEN,
+ &ndp->ni_pathlen);
/*
* Don't allow empty pathnames.
@@ -258,8 +260,6 @@ namei(struct nameidata *ndp)
dp = fdp->fd_cdir;
VREF(dp);
} else {
- cap_rights_t rights;
-
rights = ndp->ni_rightsneeded;
cap_rights_set(&rights, CAP_LOOKUP);
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 6e45a2c..a4c9671 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -1207,6 +1207,9 @@ sys_unmount(struct thread *td, struct unmount_args *uap)
/*
* Return error if any of the vnodes, ignoring the root vnode
* and the syncer vnode, have non-zero usecount.
+ *
+ * This function is purely advisory - it can return false positives
+ * and negatives.
*/
static int
vfs_check_usecounts(struct mount *mp)
@@ -1288,6 +1291,10 @@ dounmount(struct mount *mp, int flags, struct thread *td)
MNT_ILOCK(mp);
if (error != 0) {
mp->mnt_kern_flag &= ~(MNTK_UNMOUNT | MNTK_NOINSMNTQ);
+ if (mp->mnt_kern_flag & MNTK_MWAIT) {
+ mp->mnt_kern_flag &= ~MNTK_MWAIT;
+ wakeup(mp);
+ }
MNT_IUNLOCK(mp);
if (coveredvp != NULL) {
VOP_UNLOCK(coveredvp, 0);
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index cd70ccf..cf701c6 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -4402,6 +4402,10 @@ int vfs_badlock_print = 1; /* Print lock violations. */
SYSCTL_INT(_debug, OID_AUTO, vfs_badlock_print, CTLFLAG_RW, &vfs_badlock_print,
0, "Print lock violations");
+int vfs_badlock_vnode = 1; /* Print vnode details on lock violations. */
+SYSCTL_INT(_debug, OID_AUTO, vfs_badlock_vnode, CTLFLAG_RW, &vfs_badlock_vnode,
+ 0, "Print vnode details on lock violations");
+
#ifdef KDB
int vfs_badlock_backtrace = 1; /* Print backtrace at lock violations. */
SYSCTL_INT(_debug, OID_AUTO, vfs_badlock_backtrace, CTLFLAG_RW,
@@ -4416,6 +4420,8 @@ vfs_badlock(const char *msg, const char *str, struct vnode *vp)
if (vfs_badlock_backtrace)
kdb_backtrace();
#endif
+ if (vfs_badlock_vnode)
+ vn_printf(vp, "vnode ");
if (vfs_badlock_print)
printf("%s: %p %s\n", str, (void *)vp, msg);
if (vfs_badlock_ddb)
diff --git a/sys/mips/atheros/ar71xx_ehci.c b/sys/mips/atheros/ar71xx_ehci.c
index 07e06b9..19e9a0e 100644
--- a/sys/mips/atheros/ar71xx_ehci.c
+++ b/sys/mips/atheros/ar71xx_ehci.c
@@ -231,14 +231,8 @@ ar71xx_ehci_detach(device_t self)
{
struct ar71xx_ehci_softc *isc = device_get_softc(self);
ehci_softc_t *sc = &isc->base;
- device_t bdev;
int err;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(self);
diff --git a/sys/mips/atheros/ar71xx_ohci.c b/sys/mips/atheros/ar71xx_ohci.c
index 30f2c7d..aac32ec 100644
--- a/sys/mips/atheros/ar71xx_ohci.c
+++ b/sys/mips/atheros/ar71xx_ohci.c
@@ -156,13 +156,7 @@ static int
ar71xx_ohci_detach(device_t dev)
{
struct ar71xx_ohci_softc *sc = device_get_softc(dev);
- device_t bdev;
- if (sc->sc_ohci.sc_bus.bdev) {
- bdev = sc->sc_ohci.sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/mips/cavium/usb/octusb_octeon.c b/sys/mips/cavium/usb/octusb_octeon.c
index a49a363..5852e14 100644
--- a/sys/mips/cavium/usb/octusb_octeon.c
+++ b/sys/mips/cavium/usb/octusb_octeon.c
@@ -160,16 +160,10 @@ static int
octusb_octeon_detach(device_t dev)
{
struct octusb_octeon_softc *sc = device_get_softc(dev);
- device_t bdev;
int err;
int nports;
int i;
- if (sc->sc_dci.sc_bus.bdev) {
- bdev = sc->sc_dci.sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/mips/include/intr.h b/sys/mips/include/intr.h
index 6e00643..ee8d093 100644
--- a/sys/mips/include/intr.h
+++ b/sys/mips/include/intr.h
@@ -63,6 +63,8 @@ void cpu_establish_hardintr(const char *, driver_filter_t *, driver_intr_t *,
void *, int, int, void **);
void cpu_establish_softintr(const char *, driver_filter_t *, void (*)(void*),
void *, int, int, void **);
+int cpu_create_intr_map(int);
+struct resource *cpu_get_irq_resource(int);
/* MIPS interrupt C entry point */
void cpu_intr(struct trapframe *);
diff --git a/sys/mips/mediatek/mtk_dotg.c b/sys/mips/mediatek/mtk_dotg.c
index d7421ad..e685eac 100644
--- a/sys/mips/mediatek/mtk_dotg.c
+++ b/sys/mips/mediatek/mtk_dotg.c
@@ -161,14 +161,8 @@ static int
dotg_fdt_detach(device_t dev)
{
struct dwc_otg_softc *sc = device_get_softc(dev);
- device_t bdev;
int err;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/mips/mediatek/mtk_ehci.c b/sys/mips/mediatek/mtk_ehci.c
index acc30eb..ed1d2fc 100644
--- a/sys/mips/mediatek/mtk_ehci.c
+++ b/sys/mips/mediatek/mtk_ehci.c
@@ -162,14 +162,8 @@ static int
ehci_fdt_detach(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
- device_t bdev;
int err;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(self);
diff --git a/sys/mips/mediatek/mtk_ohci.c b/sys/mips/mediatek/mtk_ohci.c
index 0b554e7..ad5c68f 100644
--- a/sys/mips/mediatek/mtk_ohci.c
+++ b/sys/mips/mediatek/mtk_ohci.c
@@ -162,14 +162,8 @@ static int
ohci_fdt_detach(device_t self)
{
ohci_softc_t *sc = device_get_softc(self);
- device_t bdev;
int err;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(self);
diff --git a/sys/mips/mediatek/mtk_xhci.c b/sys/mips/mediatek/mtk_xhci.c
index 138a4d4..55f39d5 100644
--- a/sys/mips/mediatek/mtk_xhci.c
+++ b/sys/mips/mediatek/mtk_xhci.c
@@ -161,14 +161,8 @@ static int
mtk_xhci_fdt_detach(device_t self)
{
struct xhci_softc *sc = device_get_softc(self);
- device_t bdev;
int err;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(self);
diff --git a/sys/mips/mips/mips_pic.c b/sys/mips/mips/mips_pic.c
index c2e8db7..18ecb5c 100644
--- a/sys/mips/mips/mips_pic.c
+++ b/sys/mips/mips/mips_pic.c
@@ -71,6 +71,11 @@ __FBSDID("$FreeBSD$");
static int mips_pic_intr(void *);
+struct intr_map_data_mips_pic {
+ struct intr_map_data hdr;
+ u_int irq;
+};
+
struct mips_pic_irqsrc {
struct intr_irqsrc isrc;
struct resource *res;
@@ -304,24 +309,37 @@ static int
mips_pic_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
-#ifdef FDT
- struct intr_map_data_fdt *daf;
struct mips_pic_softc *sc;
-
- if (data->type != INTR_MAP_DATA_FDT)
- return (ENOTSUP);
+ int res;
sc = device_get_softc(dev);
- daf = (struct intr_map_data_fdt *)data;
+ res = 0;
+#ifdef FDT
+ if (data->type == INTR_MAP_DATA_FDT) {
+ struct intr_map_data_fdt *daf;
- if (daf->ncells != 1 || daf->cells[0] >= sc->nirqs)
- return (EINVAL);
+ daf = (struct intr_map_data_fdt *)data;
- *isrcp = PIC_INTR_ISRC(sc, daf->cells[0]);
- return (0);
-#else
- return (ENOTSUP);
+ if (daf->ncells != 1 || daf->cells[0] >= sc->nirqs)
+ return (EINVAL);
+
+ *isrcp = PIC_INTR_ISRC(sc, daf->cells[0]);
+ } else
#endif
+ if (data->type == INTR_MAP_DATA_PLAT_1) {
+ struct intr_map_data_mips_pic *mpd;
+
+ mpd = (struct intr_map_data_mips_pic *)data;
+
+ if (mpd->irq < 0 || mpd->irq >= sc->nirqs)
+ return (EINVAL);
+
+ *isrcp = PIC_INTR_ISRC(sc, mpd->irq);
+ } else {
+ res = ENOTSUP;
+ }
+
+ return (res);
}
static void
@@ -383,6 +401,46 @@ cpu_init_interrupts(void)
{
}
+int
+cpu_create_intr_map(int irq)
+{
+ struct intr_map_data_mips_pic *mips_pic_data;
+ intptr_t iparent;
+ size_t len;
+ u_int new_irq;
+
+ len = sizeof(*mips_pic_data);
+ iparent = pic_xref(pic_sc->pic_dev);
+
+ /* Allocate mips_pic data and fill it in */
+ mips_pic_data = (struct intr_map_data_mips_pic *)intr_alloc_map_data(
+ INTR_MAP_DATA_PLAT_1, len, M_WAITOK | M_ZERO);
+ mips_pic_data->irq = irq;
+
+ /* Get the new irq number */
+ new_irq = intr_map_irq(pic_sc->pic_dev, iparent,
+ (struct intr_map_data *)mips_pic_data);
+
+ /* Adjust the resource accordingly */
+ rman_set_start(pic_sc->pic_irqs[irq].res, new_irq);
+ rman_set_end(pic_sc->pic_irqs[irq].res, new_irq);
+
+ /* Activate the new irq */
+ return (intr_activate_irq(pic_sc->pic_dev, pic_sc->pic_irqs[irq].res));
+}
+
+struct resource *
+cpu_get_irq_resource(int irq)
+{
+
+ KASSERT(pic_sc != NULL, ("%s: no pic", __func__));
+
+ if (irq < 0 || irq >= pic_sc->nirqs)
+ panic("%s called for unknown irq %d", __func__, irq);
+
+ return pic_sc->pic_irqs[irq].res;
+}
+
void
cpu_establish_hardintr(const char *name, driver_filter_t *filt,
void (*handler)(void*), void *arg, int irq, int flags, void **cookiep)
@@ -398,6 +456,10 @@ cpu_establish_hardintr(const char *name, driver_filter_t *filt,
KASSERT(pic_sc != NULL, ("%s: no pic", __func__));
irq += NSOFT_IRQS;
+
+ res = cpu_create_intr_map(irq);
+ if (res != 0) panic("Unable to create map for hard IRQ %d", irq);
+
res = intr_setup_irq(pic_sc->pic_dev, pic_sc->pic_irqs[irq].res, filt,
handler, arg, flags, cookiep);
if (res != 0) panic("Unable to add hard IRQ %d handler", irq);
@@ -415,6 +477,9 @@ cpu_establish_softintr(const char *name, driver_filter_t *filt,
KASSERT(pic_sc != NULL, ("%s: no pic", __func__));
+ res = cpu_create_intr_map(irq);
+ if (res != 0) panic("Unable to create map for soft IRQ %d", irq);
+
res = intr_setup_irq(pic_sc->pic_dev, pic_sc->pic_irqs[irq].res, filt,
handler, arg, flags, cookiep);
if (res != 0) panic("Unable to add soft IRQ %d handler", irq);
diff --git a/sys/mips/mips/nexus.c b/sys/mips/mips/nexus.c
index a253b7e..a5bac7f 100644
--- a/sys/mips/mips/nexus.c
+++ b/sys/mips/mips/nexus.c
@@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
#endif
#ifdef FDT
+#include <dev/ofw/ofw_bus_subr.h>
#include <dev/ofw/openfirm.h>
#include "ofw_bus_if.h"
#endif
@@ -429,6 +430,23 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid,
}
rman_set_virtual(r, vaddr);
rman_set_bushandle(r, (bus_space_handle_t)(uintptr_t)vaddr);
+ } else if (type == SYS_RES_IRQ) {
+#ifdef INTRNG
+#ifdef FDT
+ err = intr_activate_irq(child, r);
+ if (err != 0) {
+ rman_deactivate_resource(r);
+ return (err);
+ }
+#else
+ /*
+ * INTRNG without FDT needs to have the interrupt properly
+ * mapped first. cpu_create_intr_map() will do that and
+ * call intr_activate_irq() at the end.
+ */
+ cpu_create_intr_map(rman_get_start(r));
+#endif
+#endif
}
return (rman_activate_resource(r));
@@ -448,6 +466,10 @@ nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
bus_space_unmap(rman_get_bustag(r), vaddr, psize);
rman_set_virtual(r, NULL);
rman_set_bushandle(r, 0);
+ } else if (type == SYS_RES_IRQ) {
+#ifdef INTRNG
+ intr_deactivate_irq(child, r);
+#endif
}
return (rman_deactivate_resource(r));
@@ -457,9 +479,13 @@ static int
nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep)
{
-
#ifdef INTRNG
- return (intr_setup_irq(child, res, filt, intr, arg, flags, cookiep));
+ struct resource *r = res;
+
+#ifndef FDT
+ r = cpu_get_irq_resource(rman_get_start(r));
+#endif
+ return (intr_setup_irq(child, r, filt, intr, arg, flags, cookiep));
#else
int irq;
register_t s;
@@ -523,12 +549,18 @@ static int
nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells,
pcell_t *intr)
{
-
-#ifdef INTRNG
- return (INTR_IRQ_INVALID);
-#else
- return (intr_fdt_map_irq(iparent, intr, icells));
-#endif
+ u_int irq;
+ struct intr_map_data_fdt *fdt_data;
+ size_t len;
+
+ len = sizeof(*fdt_data) + icells * sizeof(pcell_t);
+ fdt_data = (struct intr_map_data_fdt *)intr_alloc_map_data(
+ INTR_MAP_DATA_FDT, len, M_WAITOK | M_ZERO);
+ fdt_data->iparent = iparent;
+ fdt_data->ncells = icells;
+ memcpy(fdt_data->cells, intr, icells * sizeof(pcell_t));
+ irq = intr_map_irq(NULL, iparent, (struct intr_map_data *)fdt_data);
+ return (irq);
}
#endif
#endif /* INTRNG */
diff --git a/sys/mips/rmi/xls_ehci.c b/sys/mips/rmi/xls_ehci.c
index 81758b2..4451d13 100644
--- a/sys/mips/rmi/xls_ehci.c
+++ b/sys/mips/rmi/xls_ehci.c
@@ -164,14 +164,8 @@ static int
ehci_xls_detach(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
- device_t bdev;
int err;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(self);
diff --git a/sys/mips/rt305x/rt305x_dotg.c b/sys/mips/rt305x/rt305x_dotg.c
index 607b215..b39046f 100644
--- a/sys/mips/rt305x/rt305x_dotg.c
+++ b/sys/mips/rt305x/rt305x_dotg.c
@@ -173,14 +173,8 @@ static int
dotg_obio_detach(device_t dev)
{
struct dwc_otg_softc *sc = device_get_softc(dev);
- device_t bdev;
int err;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(dev);
diff --git a/sys/mips/rt305x/rt305x_ehci.c b/sys/mips/rt305x/rt305x_ehci.c
index 9b2fa22..0930aff 100644
--- a/sys/mips/rt305x/rt305x_ehci.c
+++ b/sys/mips/rt305x/rt305x_ehci.c
@@ -175,14 +175,8 @@ static int
ehci_obio_detach(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
- device_t bdev;
int err;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(self);
diff --git a/sys/mips/rt305x/rt305x_ohci.c b/sys/mips/rt305x/rt305x_ohci.c
index e726e60..b700603 100644
--- a/sys/mips/rt305x/rt305x_ohci.c
+++ b/sys/mips/rt305x/rt305x_ohci.c
@@ -175,14 +175,8 @@ static int
ohci_obio_detach(device_t self)
{
ohci_softc_t *sc = device_get_softc(self);
- device_t bdev;
int err;
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
/* during module unload there are lots of children leftover */
device_delete_children(self);
diff --git a/sys/modules/dtb/allwinner/Makefile b/sys/modules/dtb/allwinner/Makefile
index 541e8c0..ae8ba90 100644
--- a/sys/modules/dtb/allwinner/Makefile
+++ b/sys/modules/dtb/allwinner/Makefile
@@ -8,6 +8,7 @@ DTS= \
olimex-a20-som-evb.dts \
olinuxino-lime.dts \
pcduino3.dts \
- sinovoip-bpi-m3.dts
+ sinovoip-bpi-m3.dts \
+ sun5i-a13-olinuxino.dts
.include <bsd.dtb.mk>
diff --git a/sys/modules/dtb/nvidia/Makefile b/sys/modules/dtb/nvidia/Makefile
new file mode 100644
index 0000000..9291ba9
--- /dev/null
+++ b/sys/modules/dtb/nvidia/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+# All the dts files for Nvidia ARM systems we support.
+DTS= \
+ tegra124-jetson-tk1-fbsd.dts
+
+.include <bsd.dtb.mk>
diff --git a/sys/modules/i2c/Makefile b/sys/modules/i2c/Makefile
index a2199f5..8e9bdf9 100644
--- a/sys/modules/i2c/Makefile
+++ b/sys/modules/i2c/Makefile
@@ -1,6 +1,6 @@
# $FreeBSD$
SUBDIR =
-SUBDIR += controllers if_ic smbus iicbus iicbb iicsmb iic cyapa smb isl
+SUBDIR += controllers if_ic smbus iicbus iicbb iicsmb iic cyapa smb isl jedec_ts
.include <bsd.subdir.mk>
diff --git a/sys/modules/i2c/jedec_ts/Makefile b/sys/modules/i2c/jedec_ts/Makefile
new file mode 100644
index 0000000..66e6206
--- /dev/null
+++ b/sys/modules/i2c/jedec_ts/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../dev/jedec_ts
+KMOD = jedec_ts
+SRCS = jedec_ts.c bus_if.h device_if.h smbus_if.h
+
+.include <bsd.kmod.mk>
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index f4d15f4..74a84c7 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -918,10 +918,6 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
tp->t_keepcnt = sototcpcb(lso)->t_keepcnt;
tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp));
- if ((so->so_options & SO_ACCEPTFILTER) == 0) {
- soisconnected(so);
- }
-
TCPSTAT_INC(tcps_accepts);
return (so);
diff --git a/sys/ofed/drivers/net/mlx4/en_tx.c b/sys/ofed/drivers/net/mlx4/en_tx.c
index 9090c51..e98aec3 100644
--- a/sys/ofed/drivers/net/mlx4/en_tx.c
+++ b/sys/ofed/drivers/net/mlx4/en_tx.c
@@ -707,20 +707,19 @@ static int mlx4_en_xmit(struct mlx4_en_priv *priv, int tx_ind, struct mbuf **mbp
/* check if TX ring is full */
if (unlikely(mlx4_en_tx_ring_is_full(ring))) {
- /* every full native Tx ring stops queue */
- if (ring->blocked == 0)
- atomic_add_int(&priv->blocked, 1);
- /* Set HW-queue-is-full flag */
- atomic_set_int(&ifp->if_drv_flags, IFF_DRV_OACTIVE);
- priv->port_stats.queue_stopped++;
- ring->blocked = 1;
+ /* every full native Tx ring stops queue */
+ if (ring->blocked == 0)
+ atomic_add_int(&priv->blocked, 1);
+ /* Set HW-queue-is-full flag */
+ atomic_set_int(&ifp->if_drv_flags, IFF_DRV_OACTIVE);
priv->port_stats.queue_stopped++;
+ ring->blocked = 1;
ring->queue_stopped++;
/* Use interrupts to find out when queue opened */
mlx4_en_arm_cq(priv, priv->tx_cq[tx_ind]);
return (ENOBUFS);
- }
+ }
/* sanity check we are not wrapping around */
KASSERT(((~ring->prod) & ring->size_mask) >=
diff --git a/sys/sys/bus.h b/sys/sys/bus.h
index 30a5333..9139eda 100644
--- a/sys/sys/bus.h
+++ b/sys/sys/bus.h
@@ -276,17 +276,6 @@ enum intr_polarity {
INTR_POLARITY_LOW = 2
};
-enum intr_map_data_type {
- INTR_MAP_DATA_ACPI,
- INTR_MAP_DATA_FDT,
- INTR_MAP_DATA_GPIO,
-};
-
-struct intr_map_data {
- enum intr_map_data_type type;
- void (*destruct)(struct intr_map_data *);
-};
-
/**
* CPU sets supported by bus_get_cpus(). Note that not all sets may be
* supported for a given device. If a request is not supported by a
@@ -463,9 +452,6 @@ int bus_generic_release_resource(device_t bus, device_t child,
int type, int rid, struct resource *r);
int bus_generic_resume(device_t dev);
int bus_generic_resume_child(device_t dev, device_t child);
-int bus_generic_map_intr(device_t dev, device_t child, int *rid,
- rman_res_t *start, rman_res_t *end,
- rman_res_t *count, struct intr_map_data **imd);
int bus_generic_setup_intr(device_t dev, device_t child,
struct resource *irq, int flags,
driver_filter_t *filter, driver_intr_t *intr,
diff --git a/sys/sys/intr.h b/sys/sys/intr.h
index 394aa5c..a82ffda 100644
--- a/sys/sys/intr.h
+++ b/sys/sys/intr.h
@@ -29,11 +29,38 @@
#ifndef _SYS_INTR_H_
#define _SYS_INTR_H_
+#ifndef INTRNG
+#error Need INTRNG for this file
+#endif
#include <sys/systm.h>
#define INTR_IRQ_INVALID 0xFFFFFFFF
+enum intr_map_data_type {
+ INTR_MAP_DATA_ACPI = 0,
+ INTR_MAP_DATA_FDT,
+ INTR_MAP_DATA_GPIO,
+ INTR_MAP_DATA_MSI,
+
+ /* Placeholders for platform specific types */
+ INTR_MAP_DATA_PLAT_1 = 1000,
+ INTR_MAP_DATA_PLAT_2,
+ INTR_MAP_DATA_PLAT_3,
+ INTR_MAP_DATA_PLAT_4,
+ INTR_MAP_DATA_PLAT_5,
+};
+
+struct intr_map_data {
+ size_t len;
+ enum intr_map_data_type type;
+};
+
+struct intr_map_data_msi {
+ struct intr_map_data hdr;
+ struct intr_irqsrc *isrc;
+};
+
#ifdef notyet
#define INTR_SOLO INTR_MD1
typedef int intr_irq_filter_t(void *arg, struct trapframe *tf);
@@ -88,10 +115,9 @@ struct intr_pic *intr_pic_add_handler(device_t, struct intr_pic *,
extern device_t intr_irq_root_dev;
/* Intr interface for BUS. */
-int intr_map_irq(device_t, intptr_t, struct intr_map_data *, u_int *);
-int intr_alloc_irq(device_t, struct resource *);
-int intr_release_irq(device_t, struct resource *);
+int intr_activate_irq(device_t, struct resource *);
+int intr_deactivate_irq(device_t, struct resource *);
int intr_setup_irq(device_t, struct resource *, driver_filter_t, driver_intr_t,
void *, int, void **);
@@ -100,6 +126,13 @@ int intr_teardown_irq(device_t, struct resource *, void *);
int intr_describe_irq(device_t, struct resource *, void *, const char *);
int intr_child_irq_handler(struct intr_pic *, uintptr_t);
+/* Intr resources mapping. */
+struct intr_map_data *intr_alloc_map_data(enum intr_map_data_type, size_t, int);
+void intr_free_intr_map_data(struct intr_map_data *);
+u_int intr_map_irq(device_t, intptr_t, struct intr_map_data *);
+void intr_unmap_irq(u_int );
+u_int intr_map_clone_irq(u_int );
+
/* MSI/MSI-X handling */
int intr_msi_register(device_t, intptr_t);
int intr_alloc_msi(device_t, device_t, intptr_t, int, int, int *);
diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c
index 2080fdf..bce8b12 100644
--- a/sys/vm/device_pager.c
+++ b/sys/vm/device_pager.c
@@ -169,7 +169,10 @@ cdev_pager_allocate(void *handle, enum obj_type tp, struct cdev_pager_ops *ops,
if (pindex > object->size)
object->size = pindex;
KASSERT(object->type == tp,
- ("Inconsistent device pager type %p %d", object, tp));
+ ("Inconsistent device pager type %p %d",
+ object, tp));
+ KASSERT(object->un_pager.devp.ops == ops,
+ ("Inconsistent devops %p %p", object, ops));
} else {
object = object1;
object1 = NULL;
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 03c68dd..1199305 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -122,7 +122,7 @@ struct faultstate {
vm_pindex_t first_pindex;
vm_map_t map;
vm_map_entry_t entry;
- int lookup_still_valid;
+ bool lookup_still_valid;
struct vnode *vp;
};
@@ -148,7 +148,17 @@ unlock_map(struct faultstate *fs)
if (fs->lookup_still_valid) {
vm_map_lookup_done(fs->map, fs->entry);
- fs->lookup_still_valid = FALSE;
+ fs->lookup_still_valid = false;
+ }
+}
+
+static void
+unlock_vp(struct faultstate *fs)
+{
+
+ if (fs->vp != NULL) {
+ vput(fs->vp);
+ fs->vp = NULL;
}
}
@@ -168,18 +178,15 @@ unlock_and_deallocate(struct faultstate *fs)
fs->first_m = NULL;
}
vm_object_deallocate(fs->first_object);
- unlock_map(fs);
- if (fs->vp != NULL) {
- vput(fs->vp);
- fs->vp = NULL;
- }
+ unlock_map(fs);
+ unlock_vp(fs);
}
static void
vm_fault_dirty(vm_map_entry_t entry, vm_page_t m, vm_prot_t prot,
- vm_prot_t fault_type, int fault_flags, boolean_t set_wd)
+ vm_prot_t fault_type, int fault_flags, bool set_wd)
{
- boolean_t need_dirty;
+ bool need_dirty;
if (((prot & VM_PROT_WRITE) == 0 &&
(fault_flags & VM_FAULT_DIRTY) == 0) ||
@@ -284,24 +291,23 @@ vm_fault_hold(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type,
int fault_flags, vm_page_t *m_hold)
{
vm_prot_t prot;
- int alloc_req, era, faultcount, nera, result;
- boolean_t dead, growstack, is_first_object_locked, wired;
- int map_generation;
vm_object_t next_object;
- int hardfault;
struct faultstate fs;
struct vnode *vp;
vm_offset_t e_end, e_start;
vm_page_t m;
- int ahead, behind, cluster_offset, error, locked, rv;
+ int ahead, alloc_req, behind, cluster_offset, error, era, faultcount;
+ int locked, map_generation, nera, result, rv;
u_char behavior;
+ boolean_t wired; /* Passed by reference. */
+ bool dead, growstack, hardfault, is_first_object_locked;
- hardfault = 0;
- growstack = TRUE;
PCPU_INC(cnt.v_vm_faults);
fs.vp = NULL;
faultcount = 0;
nera = -1;
+ growstack = true;
+ hardfault = false;
RetryFault:;
@@ -318,11 +324,10 @@ RetryFault:;
result = vm_map_growstack(curproc, vaddr);
if (result != KERN_SUCCESS)
return (KERN_FAILURE);
- growstack = FALSE;
+ growstack = false;
goto RetryFault;
}
- if (fs.vp != NULL)
- vput(fs.vp);
+ unlock_vp(&fs);
return (result);
}
@@ -339,10 +344,7 @@ RetryFault:;
vm_map_lock(fs.map);
if (vm_map_lookup_entry(fs.map, vaddr, &fs.entry) &&
(fs.entry->eflags & MAP_ENTRY_IN_TRANSITION)) {
- if (fs.vp != NULL) {
- vput(fs.vp);
- fs.vp = NULL;
- }
+ unlock_vp(&fs);
fs.entry->eflags |= MAP_ENTRY_NEEDS_WAKEUP;
vm_map_unlock_and_wait(fs.map, 0);
} else
@@ -395,7 +397,7 @@ RetryFault:;
vm_page_unlock(m);
}
vm_fault_dirty(fs.entry, m, prot, fault_type, fault_flags,
- FALSE);
+ false);
VM_OBJECT_RUNLOCK(fs.first_object);
if (!wired)
vm_fault_prefault(&fs, vaddr, PFBAK, PFFOR);
@@ -418,13 +420,12 @@ fast_failed:
* they will stay around as well.
*
* Bump the paging-in-progress count to prevent size changes (e.g.
- * truncation operations) during I/O. This must be done after
- * obtaining the vnode lock in order to avoid possible deadlocks.
+ * truncation operations) during I/O.
*/
vm_object_reference_locked(fs.first_object);
vm_object_pip_add(fs.first_object, 1);
- fs.lookup_still_valid = TRUE;
+ fs.lookup_still_valid = true;
fs.first_m = NULL;
@@ -563,6 +564,14 @@ fast_failed:
readrest:
/*
+ * At this point, we have either allocated a new page or found
+ * an existing page that is only partially valid.
+ *
+ * We hold a reference on the current object and the page is
+ * exclusive busied.
+ */
+
+ /*
* If the pager for the current object might have the page,
* then determine the number of additional pages to read and
* potentially reprioritize previously read pages for earlier
@@ -631,26 +640,32 @@ readrest:
*/
if (fs.object->type != OBJT_DEFAULT) {
/*
- * We have either allocated a new page or found an
- * existing page that is only partially valid. We
- * hold a reference on fs.object and the page is
- * exclusive busied.
+ * Release the map lock before locking the vnode or
+ * sleeping in the pager. (If the current object has
+ * a shadow, then an earlier iteration of this loop
+ * may have already unlocked the map.)
*/
unlock_map(&fs);
- if (fs.object->type == OBJT_VNODE) {
- vp = fs.object->handle;
- if (vp == fs.vp)
- goto vnode_locked;
- else if (fs.vp != NULL) {
- vput(fs.vp);
- fs.vp = NULL;
- }
- locked = VOP_ISLOCKED(vp);
+ if (fs.object->type == OBJT_VNODE &&
+ (vp = fs.object->handle) != fs.vp) {
+ /*
+ * Perform an unlock in case the desired vnode
+ * changed while the map was unlocked during a
+ * retry.
+ */
+ unlock_vp(&fs);
+ locked = VOP_ISLOCKED(vp);
if (locked != LK_EXCLUSIVE)
locked = LK_SHARED;
- /* Do not sleep for vnode lock while fs.m is busy */
+
+ /*
+ * We must not sleep acquiring the vnode lock
+ * while we have the page exclusive busied or
+ * the object's paging-in-progress count
+ * incremented. Otherwise, we could deadlock.
+ */
error = vget(vp, locked | LK_CANRECURSE |
LK_NOWAIT, curthread);
if (error != 0) {
@@ -667,7 +682,6 @@ readrest:
}
fs.vp = vp;
}
-vnode_locked:
KASSERT(fs.vp == NULL || !fs.map->system_map,
("vm_fault: vnode-backed object mapped by system map"));
@@ -708,7 +722,7 @@ vnode_locked:
&behind, &ahead);
if (rv == VM_PAGER_OK) {
faultcount = behind + 1 + ahead;
- hardfault++;
+ hardfault = true;
break; /* break to PAGE HAS BEEN FOUND */
}
if (rv == VM_PAGER_ERROR)
@@ -836,7 +850,7 @@ vnode_locked:
* dirty in the first object so that it will go out
* to swap when needed.
*/
- is_first_object_locked = FALSE;
+ is_first_object_locked = false;
if (
/*
* Only one shadow object
@@ -941,7 +955,7 @@ vnode_locked:
unlock_and_deallocate(&fs);
goto RetryFault;
}
- fs.lookup_still_valid = TRUE;
+ fs.lookup_still_valid = true;
if (fs.map->timestamp != map_generation) {
result = vm_map_lookup_locked(&fs.map, vaddr, fault_type,
&fs.entry, &retry_object, &retry_pindex, &retry_prot, &wired);
@@ -991,7 +1005,7 @@ vnode_locked:
if (hardfault)
fs.entry->next_read = vaddr + ptoa(ahead) + PAGE_SIZE;
- vm_fault_dirty(fs.entry, fs.m, prot, fault_type, fault_flags, TRUE);
+ vm_fault_dirty(fs.entry, fs.m, prot, fault_type, fault_flags, true);
vm_page_assert_xbusied(fs.m);
/*
diff --git a/sys/vm/vm_pager.h b/sys/vm/vm_pager.h
index 4b7d100..f73cd00 100644
--- a/sys/vm/vm_pager.h
+++ b/sys/vm/vm_pager.h
@@ -109,7 +109,6 @@ void vm_pager_deallocate(vm_object_t);
int vm_pager_get_pages(vm_object_t, vm_page_t *, int, int *, int *);
int vm_pager_get_pages_async(vm_object_t, vm_page_t *, int, 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 *);
diff --git a/sys/x86/include/cputypes.h b/sys/x86/include/cputypes.h
index ca6ce83..4b8bd10 100644
--- a/sys/x86/include/cputypes.h
+++ b/sys/x86/include/cputypes.h
@@ -46,9 +46,4 @@
#define CPU_VENDOR_RISE 0xdead2bad /* Rise */
#define CPU_VENDOR_CENTAUR CPU_VENDOR_IDT
-#ifndef LOCORE
-extern int cpu;
-extern int cpu_class;
-#endif
-
#endif /* !_X86_CPUTYPES_H_ */
diff --git a/sys/x86/include/frame.h b/sys/x86/include/frame.h
index a32ef7c..7418736 100644
--- a/sys/x86/include/frame.h
+++ b/sys/x86/include/frame.h
@@ -64,7 +64,7 @@ struct trapframe {
int tf_eip;
int tf_cs;
int tf_eflags;
- /* below only when crossing rings (e.g. user to kernel) */
+ /* below only when crossing rings (user to kernel) */
int tf_esp;
int tf_ss;
};
@@ -89,15 +89,24 @@ struct trapframe_vm86 {
int tf_eip;
int tf_cs;
int tf_eflags;
- /* below only when crossing rings (e.g. user to kernel) */
+ /* below only when crossing rings (user (including vm86) to kernel) */
int tf_esp;
int tf_ss;
- /* below only when switching out of VM86 mode */
+ /* below only when crossing from vm86 mode to kernel */
int tf_vm86_es;
int tf_vm86_ds;
int tf_vm86_fs;
int tf_vm86_gs;
};
+
+/*
+ * This alias for the MI TRAPF_USERMODE() should be used when we don't
+ * care about user mode itself, but need to know if a frame has stack
+ * registers. The difference is only logical, but on i386 the logic
+ * for using TRAPF_USERMODE() is complicated by sometimes treating vm86
+ * bioscall mode (which is a special ring 3 user mode) as kernel mode.
+ */
+#define TF_HAS_STACKREGS(tf) TRAPF_USERMODE(tf)
#endif /* __i386__ */
#ifdef __amd64__
@@ -136,6 +145,7 @@ struct trapframe {
register_t tf_rip;
register_t tf_cs;
register_t tf_rflags;
+ /* the amd64 frame always has the stack registers */
register_t tf_rsp;
register_t tf_ss;
};
diff --git a/sys/x86/include/x86_smp.h b/sys/x86/include/x86_smp.h
index 7c906dd..84a0eba 100644
--- a/sys/x86/include/x86_smp.h
+++ b/sys/x86/include/x86_smp.h
@@ -45,6 +45,9 @@ extern u_int ipi_page;
extern u_int ipi_range;
extern u_int ipi_range_size;
+extern int nmi_kdb_lock;
+extern int nmi_is_broadcast;
+
struct cpu_info {
int cpu_present:1;
int cpu_bsp:1;
diff --git a/sys/x86/include/x86_var.h b/sys/x86/include/x86_var.h
index 07e9d80..12bc1e0 100644
--- a/sys/x86/include/x86_var.h
+++ b/sys/x86/include/x86_var.h
@@ -85,6 +85,7 @@ struct reg;
struct fpreg;
struct dbreg;
struct dumperinfo;
+struct trapframe;
/*
* The interface type of the interrupt handler entry point cannot be
@@ -107,7 +108,9 @@ bool fix_cpuid(void);
void fillw(int /*u_short*/ pat, void *base, size_t cnt);
int is_physical_memory(vm_paddr_t addr);
int isa_nmi(int cd);
-void panicifcpuunsupported(void);
+void nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame);
+void nmi_call_kdb_smp(u_int type, struct trapframe *frame);
+void nmi_handle_intr(u_int type, struct trapframe *frame);
void pagecopy(void *from, void *to);
void printcpuinfo(void);
int user_dbreg_trap(void);
diff --git a/sys/x86/x86/cpu_machdep.c b/sys/x86/x86/cpu_machdep.c
index f07b97e..4e75402 100644
--- a/sys/x86/x86/cpu_machdep.c
+++ b/sys/x86/x86/cpu_machdep.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include "opt_ddb.h"
#include "opt_inet.h"
#include "opt_isa.h"
+#include "opt_kdb.h"
#include "opt_kstack_pages.h"
#include "opt_maxmem.h"
#include "opt_mp_watchdog.h"
@@ -526,3 +527,55 @@ idle_sysctl(SYSCTL_HANDLER_ARGS)
SYSCTL_PROC(_machdep, OID_AUTO, idle, CTLTYPE_STRING | CTLFLAG_RW, 0, 0,
idle_sysctl, "A", "currently selected idle function");
+
+static int panic_on_nmi = 1;
+SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RWTUN,
+ &panic_on_nmi, 0,
+ "Panic on NMI");
+int nmi_is_broadcast = 1;
+SYSCTL_INT(_machdep, OID_AUTO, nmi_is_broadcast, CTLFLAG_RWTUN,
+ &nmi_is_broadcast, 0,
+ "Chipset NMI is broadcast");
+#ifdef KDB
+int kdb_on_nmi = 1;
+SYSCTL_INT(_machdep, OID_AUTO, kdb_on_nmi, CTLFLAG_RWTUN,
+ &kdb_on_nmi, 0,
+ "Go to KDB on NMI");
+#endif
+
+#ifdef DEV_ISA
+void
+nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame)
+{
+
+ /* machine/parity/power fail/"kitchen sink" faults */
+ if (isa_nmi(frame->tf_err) == 0) {
+#ifdef KDB
+ /*
+ * NMI can be hooked up to a pushbutton for debugging.
+ */
+ if (kdb_on_nmi) {
+ printf("NMI/cpu%d ... going to debugger\n", cpu);
+ kdb_trap(type, 0, frame);
+ }
+#endif /* KDB */
+ } else if (panic_on_nmi) {
+ panic("NMI indicates hardware failure");
+ }
+}
+#endif
+
+void
+nmi_handle_intr(u_int type, struct trapframe *frame)
+{
+
+#ifdef DEV_ISA
+#ifdef SMP
+ if (nmi_is_broadcast) {
+ nmi_call_kdb_smp(type, frame);
+ return;
+ }
+#endif
+ nmi_call_kdb(PCPU_GET(cpuid), type, frame);
+#endif
+}
diff --git a/sys/x86/x86/identcpu.c b/sys/x86/x86/identcpu.c
index 10d02f3..11627ce 100644
--- a/sys/x86/x86/identcpu.c
+++ b/sys/x86/x86/identcpu.c
@@ -87,8 +87,10 @@ static void print_svm_info(void);
static void print_via_padlock_info(void);
static void print_vmx_info(void);
+#ifdef __i386__
int cpu; /* Are we 386, 386sx, 486, etc? */
int cpu_class;
+#endif
u_int cpu_feature; /* Feature flags */
u_int cpu_feature2; /* Feature flags */
u_int amd_feature; /* AMD feature flags */
@@ -184,13 +186,11 @@ static const char *cpu_brandtable[MAX_BRAND_INDEX + 1] = {
NULL,
"Intel Pentium 4"
};
-#endif
static struct {
char *cpu_name;
int cpu_class;
} cpus[] = {
-#ifdef __i386__
{ "Intel 80286", CPUCLASS_286 }, /* CPU_286 */
{ "i386SX", CPUCLASS_386 }, /* CPU_386SX */
{ "i386DX", CPUCLASS_386 }, /* CPU_386 */
@@ -208,11 +208,8 @@ static struct {
{ "Pentium II", CPUCLASS_686 }, /* CPU_PII */
{ "Pentium III", CPUCLASS_686 }, /* CPU_PIII */
{ "Pentium 4", CPUCLASS_686 }, /* CPU_P4 */
-#else
- { "Clawhammer", CPUCLASS_K8 }, /* CPU_CLAWHAMMER */
- { "Sledgehammer", CPUCLASS_K8 }, /* CPU_SLEDGEHAMMER */
-#endif
};
+#endif
static struct {
char *vendor;
@@ -242,9 +239,13 @@ printcpuinfo(void)
u_int regs[4], i;
char *brand;
- cpu_class = cpus[cpu].cpu_class;
printf("CPU: ");
+#ifdef __i386__
+ cpu_class = cpus[cpu].cpu_class;
strncpy(cpu_model, cpus[cpu].cpu_name, sizeof (cpu_model));
+#else
+ strncpy(cpu_model, "Hammer", sizeof (cpu_model));
+#endif
/* Check for extended CPUID information and a processor name. */
if (cpu_exthigh >= 0x80000004) {
@@ -697,8 +698,8 @@ printcpuinfo(void)
(intmax_t)(tsc_freq + 4999) / 1000000,
(u_int)((tsc_freq + 4999) / 10000) % 100);
}
- switch(cpu_class) {
#ifdef __i386__
+ switch(cpu_class) {
case CPUCLASS_286:
printf("286");
break;
@@ -720,14 +721,12 @@ printcpuinfo(void)
printf("686");
break;
#endif
-#else
- case CPUCLASS_K8:
- printf("K8");
- break;
-#endif
default:
printf("Unknown"); /* will panic below... */
}
+#else
+ printf("K8");
+#endif
printf("-class CPU)\n");
if (*cpu_vendor)
printf(" Origin=\"%s\"", cpu_vendor);
@@ -1051,28 +1050,22 @@ printcpuinfo(void)
print_hypervisor_info();
}
+#ifdef __i386__
void
panicifcpuunsupported(void)
{
-#ifdef __i386__
#if !defined(lint)
#if !defined(I486_CPU) && !defined(I586_CPU) && !defined(I686_CPU)
#error This kernel is not configured for one of the supported CPUs
#endif
#else /* lint */
#endif /* lint */
-#else /* __amd64__ */
-#ifndef HAMMER
-#error "You need to specify a cpu type"
-#endif
-#endif
/*
* Now that we have told the user what they have,
* let them know if that machine type isn't configured.
*/
switch (cpu_class) {
-#ifdef __i386__
case CPUCLASS_286: /* a 286 should not make it this far, anyway */
case CPUCLASS_386:
#if !defined(I486_CPU)
@@ -1084,19 +1077,12 @@ panicifcpuunsupported(void)
#if !defined(I686_CPU)
case CPUCLASS_686:
#endif
-#else /* __amd64__ */
- case CPUCLASS_X86:
-#ifndef HAMMER
- case CPUCLASS_K8:
-#endif
-#endif
panic("CPU class not configured");
default:
break;
}
}
-#ifdef __i386__
static volatile u_int trap_by_rdmsr;
/*
@@ -1580,9 +1566,6 @@ identify_cpu(void)
return;
}
}
-#else
- /* XXX */
- cpu = CPU_CLAWHAMMER;
#endif
}
diff --git a/sys/x86/x86/mp_x86.c b/sys/x86/x86/mp_x86.c
index 6ef72f9..9de5339 100644
--- a/sys/x86/x86/mp_x86.c
+++ b/sys/x86/x86/mp_x86.c
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
#include "opt_apic.h"
#endif
#include "opt_cpu.h"
+#include "opt_isa.h"
#include "opt_kstack_pages.h"
#include "opt_pmap.h"
#include "opt_sched.h"
@@ -140,6 +141,7 @@ int cpu_apic_ids[MAXCPU];
volatile u_int cpu_ipi_pending[MAXCPU];
static void release_aps(void *dummy);
+static void cpustop_handler_post(u_int cpu);
static int hyperthreading_allowed = 1;
SYSCTL_INT(_machdep, OID_AUTO, hyperthreading_allowed, CTLFLAG_RDTUN,
@@ -1215,6 +1217,32 @@ ipi_nmi_handler(void)
return (0);
}
+#ifdef DEV_ISA
+int nmi_kdb_lock;
+
+void
+nmi_call_kdb_smp(u_int type, struct trapframe *frame)
+{
+ int cpu;
+ bool call_post;
+
+ cpu = PCPU_GET(cpuid);
+ if (atomic_cmpset_acq_int(&nmi_kdb_lock, 0, 1)) {
+ nmi_call_kdb(cpu, type, frame);
+ call_post = false;
+ } else {
+ savectx(&stoppcbs[cpu]);
+ CPU_SET_ATOMIC(cpu, &stopped_cpus);
+ while (!atomic_cmpset_acq_int(&nmi_kdb_lock, 0, 1))
+ ia32_pause();
+ call_post = true;
+ }
+ atomic_store_rel_int(&nmi_kdb_lock, 0);
+ if (call_post)
+ cpustop_handler_post(cpu);
+}
+#endif
+
/*
* Handle an IPI_STOP by saving our current context and spinning until we
* are resumed.
@@ -1235,6 +1263,13 @@ cpustop_handler(void)
while (!CPU_ISSET(cpu, &started_cpus))
ia32_pause();
+ cpustop_handler_post(cpu);
+}
+
+static void
+cpustop_handler_post(u_int cpu)
+{
+
CPU_CLR_ATOMIC(cpu, &started_cpus);
CPU_CLR_ATOMIC(cpu, &stopped_cpus);
diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc
index b21f32e..380b9a7 100644
--- a/tools/build/mk/OptionalObsoleteFiles.inc
+++ b/tools/build/mk/OptionalObsoleteFiles.inc
@@ -1095,6 +1095,7 @@ OLD_FILES+=boot/gptzfsboot
OLD_FILES+=boot/zfsboot
OLD_FILES+=boot/zfsloader
OLD_FILES+=etc/rc.d/zfs
+OLD_FILES+=etc/rc.d/zfsbe
OLD_FILES+=etc/rc.d/zvol
OLD_FILES+=etc/devd/zfs.conf
OLD_FILES+=etc/periodic/daily/404.status-zfs
diff --git a/usr.bin/calendar/Makefile b/usr.bin/calendar/Makefile
index 5e8ba88..38cf6db 100644
--- a/usr.bin/calendar/Makefile
+++ b/usr.bin/calendar/Makefile
@@ -15,20 +15,22 @@ FR_LINKS= fr_FR.ISO8859-15
TEXTMODE?= 444
beforeinstall:
- ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${TEXTMODE} \
+ ${INSTALL} ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m ${TEXTMODE} \
${.CURDIR}/calendars/calendar.* ${DESTDIR}${SHAREDIR}/calendar
.for lang in ${INTER}
- ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${TEXTMODE} \
+ ${INSTALL} ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m ${TEXTMODE} \
${.CURDIR}/calendars/${lang}/calendar.* \
${DESTDIR}${SHAREDIR}/calendar/${lang}
.endfor
.for link in ${DE_LINKS}
rm -rf ${DESTDIR}${SHAREDIR}/calendar/${link}
- ln -s de_DE.ISO8859-1 ${DESTDIR}${SHAREDIR}/calendar/${link}
+ ${INSTALL} ${TAG_ARGS} -l s de_DE.ISO8859-1 \
+ ${DESTDIR}${SHAREDIR}/calendar/${link}
.endfor
.for link in ${FR_LINKS}
rm -rf ${DESTDIR}${SHAREDIR}/calendar/${link}
- ln -s fr_FR.ISO8859-1 ${DESTDIR}${SHAREDIR}/calendar/${link}
+ ${INSTALL} ${TAG_ARGS} -l s fr_FR.ISO8859-1 \
+ ${DESTDIR}${SHAREDIR}/calendar/${link}
.endfor
.if ${MK_TESTS} != "no"
diff --git a/usr.bin/localedef/ctype.c b/usr.bin/localedef/ctype.c
index e737ed5..0e238d7 100644
--- a/usr.bin/localedef/ctype.c
+++ b/usr.bin/localedef/ctype.c
@@ -407,9 +407,9 @@ dump_ctype(void)
continue;
}
- if ((last_ct != NULL) && (last_ct->ctype == ctn->ctype)) {
+ if ((last_ct != NULL) && (last_ct->ctype == ctn->ctype) &&
+ (last_ct->wc + 1 == wc)) {
ct[rl.runetype_ext_nranges-1].max = wc;
- last_ct = ctn;
} else {
rl.runetype_ext_nranges++;
ct = realloc(ct,
@@ -417,8 +417,8 @@ dump_ctype(void)
ct[rl.runetype_ext_nranges - 1].min = wc;
ct[rl.runetype_ext_nranges - 1].max = wc;
ct[rl.runetype_ext_nranges - 1].map = ctn->ctype;
- last_ct = ctn;
}
+ last_ct = ctn;
if (ctn->tolower == 0) {
last_lo = NULL;
} else if ((last_lo != NULL) &&
diff --git a/usr.bin/localedef/parser.y b/usr.bin/localedef/parser.y
index 87ff95d..73bc6f9 100644
--- a/usr.bin/localedef/parser.y
+++ b/usr.bin/localedef/parser.y
@@ -27,6 +27,8 @@
* 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$
*/
/*
@@ -321,21 +323,18 @@ ctype_kw : T_ISUPPER cc_list T_NL
| T_TOLOWER conv_list T_NL
;
+cc_list : cc_list T_SEMI cc_range_end
+ | cc_list T_SEMI cc_char
+ | cc_char
+ ;
-cc_list : cc_list T_SEMI T_CHAR
- {
- add_ctype($3);
- }
- | cc_list T_SEMI T_SYMBOL
- {
- add_charmap_undefined($3);
- }
- | cc_list T_SEMI T_ELLIPSIS T_SEMI T_CHAR
+cc_range_end : T_ELLIPSIS T_SEMI T_CHAR
{
- /* note that the endpoints *must* be characters */
- add_ctype_range($5);
+ add_ctype_range($3);
}
- | T_CHAR
+ ;
+
+cc_char : T_CHAR
{
add_ctype($1);
}
diff --git a/usr.bin/mkcsmapper/yacc.y b/usr.bin/mkcsmapper/yacc.y
index 97aade1..89ce5fd 100644
--- a/usr.bin/mkcsmapper/yacc.y
+++ b/usr.bin/mkcsmapper/yacc.y
@@ -664,7 +664,7 @@ do_mkpv(FILE *in)
if (ret && output)
unlink(output); /* dump failure */
if (ret)
- errc(EXIT_FAILURE, ret, "");
+ errx(EXIT_FAILURE, "%s\n", strerror(ret));
}
static void
diff --git a/usr.bin/sed/compile.c b/usr.bin/sed/compile.c
index b5bc3e2..3e79097 100644
--- a/usr.bin/sed/compile.c
+++ b/usr.bin/sed/compile.c
@@ -746,6 +746,9 @@ compile_text(void)
while (cu_fgets(lbuf, sizeof(lbuf), NULL)) {
op = s = text + size;
p = lbuf;
+#ifdef LEGACY_BSDSED_COMPAT
+ EATSPACE();
+#endif
for (esc_nl = 0; *p != '\0'; p++) {
if (*p == '\\' && p[1] != '\0' && *++p == '\n')
esc_nl = 1;
diff --git a/usr.sbin/amd/Makefile.inc b/usr.sbin/amd/Makefile.inc
index 1b19acd..d558fa4 100644
--- a/usr.sbin/amd/Makefile.inc
+++ b/usr.sbin/amd/Makefile.inc
@@ -32,8 +32,8 @@ CFLAGS+= -DYES_HESIOD
CFLAGS+= -DHOST_CPU=\"${MACHINE_CPUARCH}\" -DHOST_ARCH=\"${MACHINE_ARCH}\"
RPCCOM= RPCGEN_CPP=${CPP:Q} rpcgen
-MOUNT_X= ${DESTDIR}/usr/include/rpcsvc/mount.x
-NFS_PROT_X= ${DESTDIR}/usr/include/rpcsvc/nfs_prot.x
+MOUNT_X= ${SRCTOP}/include/rpcsvc/mount.x
+NFS_PROT_X= ${SRCTOP}/include/rpcsvc/nfs_prot.x
WARNS?= 1
diff --git a/usr.sbin/amd/amd/Makefile b/usr.sbin/amd/amd/Makefile
index 602c941..e1a715d 100644
--- a/usr.sbin/amd/amd/Makefile
+++ b/usr.sbin/amd/amd/Makefile
@@ -25,13 +25,13 @@ SRCS+= ops_unionfs.c opts.c readdir.c restart.c rpc_fwd.c sched.c
SRCS+= srvr_amfs_auto.c srvr_nfs.c
CFLAGS+= -I${.CURDIR}/../../../contrib/amd/amd \
- -I${DESTDIR}/usr/include/rpcsvc
+ -I${.OBJDIR}/../../../include/rpcsvc
LIBADD= amu wrap
CLEANFILES+= conf_parse.c conf_parse.h conf_tok.c
-conf_tok.o: conf_parse.h
+conf_tok.o: conf_parse.h
# These are generated at compile time
SRCS+= mount_xdr.c
diff --git a/usr.sbin/amd/libamu/Makefile b/usr.sbin/amd/libamu/Makefile
index fa8e3ab..d82a8cf 100644
--- a/usr.sbin/amd/libamu/Makefile
+++ b/usr.sbin/amd/libamu/Makefile
@@ -23,7 +23,7 @@ SRCS+= nfs_prot_x.c xdr_func_%undef.c
CLEANFILES+= nfs_prot_x.c xdr_func_%undef.c
CFLAGS+= -I${.CURDIR}/../../../contrib/amd/libamu \
- -I${DESTDIR}/usr/include/rpcsvc
+ -I${.OBJDIR}/../../../include/rpcsvc
nfs_prot_x.c: ${NFS_PROT_X}
${RPCCOM} -c -C -DWANT_NFS3 ${NFS_PROT_X} -o ${.TARGET}
diff --git a/usr.sbin/cron/cron/cron.8 b/usr.sbin/cron/cron/cron.8
index 697629f..b765c64 100644
--- a/usr.sbin/cron/cron/cron.8
+++ b/usr.sbin/cron/cron/cron.8
@@ -17,7 +17,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 29, 2008
+.Dd August 21, 2016
.Dt CRON 8
.Os
.Sh NAME
@@ -28,6 +28,7 @@
.Op Fl j Ar jitter
.Op Fl J Ar rootjitter
.Op Fl m Ar mailto
+.Op Fl n
.Op Fl s
.Op Fl o
.Op Fl x Ar debugflag Ns Op , Ns Ar ...
@@ -132,6 +133,8 @@ set to a null string, usually specified in a shell as
.Li ''
or
.Li \*q\*q .
+.It Fl n
+Don't daemonize, run in foreground instead.
.It Fl s
Enable special handling of situations when the GMT offset of the local
timezone changes, such as the switches between the standard time and
diff --git a/usr.sbin/cron/cron/cron.c b/usr.sbin/cron/cron/cron.c
index 21243e7..8626518 100644
--- a/usr.sbin/cron/cron/cron.c
+++ b/usr.sbin/cron/cron/cron.c
@@ -49,6 +49,7 @@ static int run_at_secres(cron_db *);
static time_t last_time = 0;
static int dst_enabled = 0;
+static int dont_daemonize = 0;
struct pidfh *pfh;
static void
@@ -58,7 +59,7 @@ usage() {
#endif
fprintf(stderr, "usage: cron [-j jitter] [-J rootjitter] "
- "[-m mailto] [-s] [-o] [-x debugflag[,...]]\n");
+ "[-m mailto] [-n ] [-s] [-o] [-x debugflag[,...]]\n");
#if DEBUGGING
fprintf(stderr, "\ndebugflags: ");
@@ -136,7 +137,7 @@ main(argc, argv)
if (0) {
# endif
(void) fprintf(stderr, "[%d] cron started\n", getpid());
- } else {
+ } else if (dont_daemonize == 0) {
if (daemon(1, 0) == -1) {
pidfile_remove(pfh);
log_it("CRON",getpid(),"DEATH","can't become daemon");
@@ -512,7 +513,7 @@ parse_args(argc, argv)
int argch;
char *endp;
- while ((argch = getopt(argc, argv, "j:J:m:osx:")) != -1) {
+ while ((argch = getopt(argc, argv, "j:J:m:nosx:")) != -1) {
switch (argch) {
case 'j':
Jitter = strtoul(optarg, &endp, 10);
@@ -529,6 +530,9 @@ parse_args(argc, argv)
case 'm':
defmailto = optarg;
break;
+ case 'n':
+ dont_daemonize = 1;
+ break;
case 'o':
dst_enabled = 0;
break;
diff --git a/usr.sbin/mountd/mountd.8 b/usr.sbin/mountd/mountd.8
index 4dbf5ff..ac0a3a2 100644
--- a/usr.sbin/mountd/mountd.8
+++ b/usr.sbin/mountd/mountd.8
@@ -28,7 +28,7 @@
.\" @(#)mountd.8 8.4 (Berkeley) 4/28/95
.\" $FreeBSD$
.\"
-.Dd October 14, 2012
+.Dd October 24, 2016
.Dt MOUNTD 8
.Os
.Sh NAME
@@ -95,7 +95,7 @@ requests to be logged.
Allow non-root mount requests to be served.
This should only be specified if there are clients such as PC's,
that require it.
-It will automatically clear the vfs.nfsrv.nfs_privport sysctl flag, which
+It will automatically clear the vfs.nfsd.nfs_privport sysctl flag, which
controls if the kernel will accept NFS requests from reserved ports only.
.It Fl p Ar port
Force
diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c
index e4b04b0..d893387 100644
--- a/usr.sbin/mountd/mountd.c
+++ b/usr.sbin/mountd/mountd.c
@@ -476,7 +476,7 @@ main(int argc, char **argv)
rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec);
if (!resvport_only) {
- if (sysctlbyname("vfs.nfsrv.nfs_privport", NULL, NULL,
+ if (sysctlbyname("vfs.nfsd.nfs_privport", NULL, NULL,
&resvport_only, sizeof(resvport_only)) != 0 &&
errno != ENOENT) {
syslog(LOG_ERR, "sysctl: %m");
OpenPOWER on IntegriCloud