[Zrouter-src-freebsd] ZRouter.org: push to FreeBSD HEAD tree
zrouter-src-freebsd at zrouter.org
zrouter-src-freebsd at zrouter.org
Wed Jul 25 14:36:14 UTC 2012
details: http://zrouter.org/hg/FreeBSD/head//rev/58b18bd1429e
changeset: 496:58b18bd1429e
user: Aleksandr Rybalko <ray at ddteam.net>
date: Wed Jul 25 16:45:04 2012 +0300
description:
Lazy update
diffstat:
head/sys/boot/Makefile.sparc64 | 3 +-
head/sys/boot/arm/at91/boot0spi/main.c | 18 +-
head/sys/boot/arm/at91/boot2/boot2.c | 14 +-
head/sys/boot/arm/at91/bootspi/ee.c | 10 +-
head/sys/boot/arm/at91/libat91/Makefile | 6 +-
head/sys/boot/arm/at91/libat91/at91rm9200.h | 6 +-
head/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.c | 6 +-
head/sys/boot/arm/at91/libat91/eeprom.c | 10 +-
head/sys/boot/arm/at91/libat91/emac_init.c | 30 +-
head/sys/boot/arm/at91/libat91/lib_AT91RM9200.h | 14 +-
head/sys/boot/arm/at91/libat91/spi_flash.c | 10 +-
head/sys/boot/arm/at91/linker.cfg | 234 +-
head/sys/boot/arm/ixp425/boot2/boot2.c | 9 +-
head/sys/boot/arm/uboot/Makefile | 29 +-
head/sys/boot/arm/uboot/conf.c | 5 +-
head/sys/boot/arm/uboot/ldscript.arm | 4 +-
head/sys/boot/arm/uboot/start.S | 13 +-
head/sys/boot/arm/uboot/version | 3 +-
head/sys/boot/common/boot.c | 20 +-
head/sys/boot/common/bootstrap.h | 16 +-
head/sys/boot/common/load_elf.c | 4 +-
head/sys/boot/common/load_elf_obj.c | 4 +-
head/sys/boot/common/loader.8 | 4 +-
head/sys/boot/common/ufsread.c | 18 +-
head/sys/boot/fdt/dts/bindings-localbus.txt | 83 +
head/sys/boot/fdt/dts/db78100.dts | 21 +-
head/sys/boot/fdt/dts/db88f6281.dts | 50 +-
head/sys/boot/fdt/dts/p2041rdb.dts | 490 +
head/sys/boot/fdt/dts/p2041si.dtsi | 1296 +
head/sys/boot/fdt/dts/p3041ds.dts | 998 +-
head/sys/boot/fdt/dts/p3041si.dtsi | 1339 +
head/sys/boot/fdt/dts/p5020ds.dts | 583 +
head/sys/boot/fdt/dts/p5020si.dtsi | 1389 +
head/sys/boot/fdt/dts/sheevaplug.dts | 45 +-
head/sys/boot/fdt/fdt_loader_cmd.c | 107 +-
head/sys/boot/forth/beastie.4th | 4 +-
head/sys/boot/forth/beastie.4th.8 | 6 +-
head/sys/boot/forth/brand.4th | 4 +-
head/sys/boot/forth/brand.4th.8 | 6 +-
head/sys/boot/forth/check-password.4th | 4 +-
head/sys/boot/forth/check-password.4th.8 | 6 +-
head/sys/boot/forth/color.4th | 4 +-
head/sys/boot/forth/color.4th.8 | 6 +-
head/sys/boot/forth/delay.4th | 4 +-
head/sys/boot/forth/delay.4th.8 | 6 +-
head/sys/boot/forth/menu-commands.4th | 4 +-
head/sys/boot/forth/menu.4th | 4 +-
head/sys/boot/forth/menu.4th.8 | 6 +-
head/sys/boot/forth/shortcuts.4th | 4 +-
head/sys/boot/forth/version.4th | 4 +-
head/sys/boot/forth/version.4th.8 | 6 +-
head/sys/boot/i386/boot2/boot2.c | 13 +-
head/sys/boot/i386/btx/btx/Makefile | 3 +-
head/sys/boot/i386/btx/btx/btx.S | 6 +-
head/sys/boot/i386/btx/btxldr/Makefile | 3 +-
head/sys/boot/i386/btx/btxldr/btxldr.S | 24 +-
head/sys/boot/i386/btx/lib/Makefile | 5 +-
head/sys/boot/i386/btx/lib/btxcsu.S | 49 +
head/sys/boot/i386/btx/lib/btxcsu.s | 51 -
head/sys/boot/i386/cdboot/Makefile | 10 +-
head/sys/boot/i386/cdboot/cdboot.S | 597 +
head/sys/boot/i386/cdboot/cdboot.s | 600 -
head/sys/boot/i386/common/bootargs.h | 69 +
head/sys/boot/i386/efi/reloc.c | 13 +-
head/sys/boot/i386/gptboot/gptboot.c | 9 +-
head/sys/boot/i386/libi386/Makefile | 4 +-
head/sys/boot/i386/libi386/biosdisk.c | 3 +-
head/sys/boot/i386/libi386/biospnp.c | 3 +-
head/sys/boot/i386/libi386/devicename.c | 13 +-
head/sys/boot/i386/libi386/libi386.h | 14 +-
head/sys/boot/i386/loader/Makefile | 13 +-
head/sys/boot/i386/loader/conf.c | 16 +-
head/sys/boot/i386/loader/main.c | 114 +-
head/sys/boot/i386/pxeldr/Makefile | 4 +-
head/sys/boot/i386/pxeldr/pxeldr.S | 8 +-
head/sys/boot/i386/zfsboot/zfsboot.c | 73 +-
head/sys/boot/ofw/libofw/Makefile | 4 +-
head/sys/boot/ofw/libofw/devicename.c | 23 +-
head/sys/boot/ofw/libofw/libofw.h | 10 +-
head/sys/boot/ofw/libofw/ofw_disk.c | 124 +-
head/sys/boot/pc98/boot2/boot2.c | 9 +-
head/sys/boot/pc98/btx/btx/Makefile | 3 +-
head/sys/boot/pc98/btx/btx/btx.S | 6 +-
head/sys/boot/pc98/btx/btxldr/Makefile | 3 +-
head/sys/boot/pc98/btx/btxldr/btxldr.S | 24 +-
head/sys/boot/pc98/btx/lib/Makefile | 5 +-
head/sys/boot/pc98/btx/lib/btxcsu.S | 49 +
head/sys/boot/pc98/btx/lib/btxcsu.s | 51 -
head/sys/boot/pc98/cdboot/Makefile | 6 +-
head/sys/boot/pc98/cdboot/cdboot.S | 808 +
head/sys/boot/pc98/cdboot/cdboot.s | 811 -
head/sys/boot/pc98/libpc98/Makefile | 4 +-
head/sys/boot/pc98/libpc98/biosdisk.c | 3 +-
head/sys/boot/pc98/loader/main.c | 20 +-
head/sys/boot/powerpc/boot1.chrp/boot1.c | 5 +-
head/sys/boot/sparc64/Makefile | 4 +-
head/sys/boot/sparc64/boot1/Makefile | 13 +-
head/sys/boot/sparc64/boot1/boot1.c | 139 +-
head/sys/boot/sparc64/loader/Makefile | 29 +-
head/sys/boot/sparc64/loader/main.c | 107 +-
head/sys/boot/sparc64/zfsboot/Makefile | 9 +
head/sys/boot/sparc64/zfsloader/Makefile | 9 +
head/sys/boot/uboot/common/metadata.c | 17 +-
head/sys/boot/uboot/lib/api_public.h | 3 +-
head/sys/boot/uboot/lib/copy.c | 50 +-
head/sys/boot/uboot/lib/devicename.c | 9 +-
head/sys/boot/uboot/lib/disk.c | 99 +-
head/sys/boot/uboot/lib/elf_freebsd.c | 9 +-
head/sys/boot/uboot/lib/glue.c | 5 +-
head/sys/boot/uboot/lib/libuboot.h | 4 +-
head/sys/boot/userboot/libstand/Makefile | 19 +-
head/sys/boot/zfs/devicename_stubs.c | 47 +
head/sys/boot/zfs/libzfs.h | 66 +
head/sys/boot/zfs/zfs.c | 256 +-
head/sys/boot/zfs/zfsimpl.c | 444 +-
head/sys/cam/ata/ata_all.c | 120 +-
head/sys/cam/ata/ata_all.h | 38 +-
head/sys/cam/ata/ata_da.c | 147 +-
head/sys/cam/ata/ata_pmp.c | 60 +-
head/sys/cam/ata/ata_xpt.c | 551 +-
head/sys/cam/cam.h | 11 +-
head/sys/cam/cam_ccb.h | 16 +-
head/sys/cam/cam_debug.h | 52 +-
head/sys/cam/cam_periph.c | 650 +-
head/sys/cam/cam_periph.h | 3 +-
head/sys/cam/cam_sim.h | 3 +-
head/sys/cam/cam_xpt.c | 145 +-
head/sys/cam/cam_xpt.h | 24 +-
head/sys/cam/cam_xpt_periph.h | 5 +-
head/sys/cam/cam_xpt_sim.h | 4 +-
head/sys/cam/ctl/ctl.c | 14 +-
head/sys/cam/ctl/ctl_backend.c | 7 +-
head/sys/cam/ctl/ctl_frontend_cam_sim.c | 7 +-
head/sys/cam/ctl/ctl_frontend_internal.c | 7 +-
head/sys/cam/ctl/scsi_ctl.c | 61 +-
head/sys/cam/scsi/scsi_all.c | 298 +-
head/sys/cam/scsi/scsi_all.h | 49 +-
head/sys/cam/scsi/scsi_cd.c | 123 +-
head/sys/cam/scsi/scsi_ch.c | 28 +-
head/sys/cam/scsi/scsi_da.c | 238 +-
head/sys/cam/scsi/scsi_da.h | 3 +-
head/sys/cam/scsi/scsi_enc.c | 1023 +
head/sys/cam/scsi/scsi_enc.h | 219 +
head/sys/cam/scsi/scsi_enc_internal.h | 230 +
head/sys/cam/scsi/scsi_enc_safte.c | 1137 +
head/sys/cam/scsi/scsi_enc_ses.c | 2816 ++
head/sys/cam/scsi/scsi_pass.c | 109 +-
head/sys/cam/scsi/scsi_pt.c | 13 +-
head/sys/cam/scsi/scsi_sa.c | 8 +-
head/sys/cam/scsi/scsi_ses.c | 2533 --
head/sys/cam/scsi/scsi_ses.h | 2452 +-
head/sys/cam/scsi/scsi_sg.c | 27 +-
head/sys/cam/scsi/scsi_target.c | 6 +-
head/sys/cam/scsi/scsi_xpt.c | 93 +-
head/sys/cddl/boot/zfs/zfsimpl.h | 16 +-
head/sys/cddl/contrib/opensolaris/common/nvpair/fnvpair.c | 498 +
head/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c | 155 +
head/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h | 70 +
head/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c | 26 +-
head/sys/cddl/contrib/opensolaris/uts/common/Makefile.files | 10 +-
head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c | 107 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c | 4 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c | 224 +
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c | 3 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c | 9 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c | 126 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c | 280 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c | 107 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c | 5 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c | 19 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c | 4 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c | 202 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deleg.c | 8 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c | 57 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c | 187 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c | 16 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c | 483 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c | 9 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c | 57 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c | 5 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/bptree.h | 64 +
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h | 101 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_impl.h | 30 +
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_traverse.h | 4 +
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h | 13 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h | 9 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_scan.h | 4 +
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h | 17 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h | 9 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h | 5 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h | 8 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap.h | 9 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfeature.h | 52 +
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h | 14 +
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio_impl.h | 2 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c | 30 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c | 64 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c | 6 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c | 7 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c | 103 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c | 8 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c | 8 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c | 6 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_root.c | 8 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c | 14 +
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c | 6 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfeature.c | 414 +
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c | 92 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c | 2 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c | 11 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c | 2 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c | 46 +-
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c | 12 +-
head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h | 34 +
head/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h | 28 +-
head/sys/cddl/contrib/opensolaris/uts/common/sys/nvpair.h | 68 +
head/sys/cddl/dev/dtrace/amd64/dis_tables.c | 12 +-
head/sys/cddl/dev/dtrace/amd64/dtrace_subr.c | 32 +-
head/sys/cddl/dev/dtrace/i386/dis_tables.c | 12 +-
head/sys/cddl/dev/dtrace/i386/dtrace_subr.c | 32 +-
head/sys/compat/freebsd32/freebsd32.h | 4 +-
head/sys/compat/freebsd32/freebsd32_misc.c | 5 +-
head/sys/compat/freebsd32/freebsd32_proto.h | 132 +-
head/sys/compat/freebsd32/freebsd32_syscall.h | 4 +-
head/sys/compat/freebsd32/freebsd32_syscalls.c | 4 +-
head/sys/compat/freebsd32/freebsd32_sysent.c | 4 +-
head/sys/compat/freebsd32/freebsd32_systrace_args.c | 238 +-
head/sys/compat/freebsd32/syscalls.master | 76 +-
head/sys/compat/ia32/ia32_sysvec.c | 4 +-
head/sys/compat/ia32/ia32_util.h | 19 +-
head/sys/compat/linux/check_error.d | 144 +
head/sys/compat/linux/check_internal_locks.d | 132 +
head/sys/compat/linux/linux_dtrace.h | 95 +
head/sys/compat/linux/linux_emul.c | 127 +-
head/sys/compat/linux/linux_emul.h | 43 +-
head/sys/compat/linux/linux_file.c | 7 +-
head/sys/compat/linux/linux_fork.c | 12 +-
head/sys/compat/linux/linux_futex.c | 511 +-
head/sys/compat/linux/linux_mib.c | 316 +-
head/sys/compat/linux/linux_misc.c | 16 +-
head/sys/compat/linux/linux_sysctl.c | 60 +-
head/sys/compat/linux/linux_time.c | 231 +-
head/sys/compat/linux/linux_uid16.c | 191 +-
head/sys/compat/linux/linux_util.c | 124 +-
head/sys/compat/linux/linux_util.h | 10 +-
head/sys/compat/linux/stats_timing.d | 94 +
head/sys/compat/linux/trace_futexes.d | 182 +
head/sys/compat/ndis/subr_ntoskrnl.c | 3 +-
head/sys/contrib/dev/acpica/acpica_prep.sh | 11 +-
head/sys/contrib/dev/acpica/changes.txt | 277 +-
head/sys/contrib/dev/acpica/common/adfile.c | 19 +-
head/sys/contrib/dev/acpica/common/adwalk.c | 30 +-
head/sys/contrib/dev/acpica/common/ahpredef.c | 323 +
head/sys/contrib/dev/acpica/common/dmextern.c | 36 +-
head/sys/contrib/dev/acpica/common/dmrestag.c | 21 +-
head/sys/contrib/dev/acpica/compiler/aslcompile.c | 178 +-
head/sys/contrib/dev/acpica/compiler/aslcompiler.h | 24 +-
head/sys/contrib/dev/acpica/compiler/aslcompiler.l | 712 +-
head/sys/contrib/dev/acpica/compiler/aslcompiler.y | 228 +-
head/sys/contrib/dev/acpica/compiler/aslerror.c | 40 +-
head/sys/contrib/dev/acpica/compiler/aslfiles.c | 184 +-
head/sys/contrib/dev/acpica/compiler/aslglobal.h | 5 +-
head/sys/contrib/dev/acpica/compiler/asllookup.c | 2 +-
head/sys/contrib/dev/acpica/compiler/aslmain.c | 91 +-
head/sys/contrib/dev/acpica/compiler/aslmap.c | 3 +-
head/sys/contrib/dev/acpica/compiler/aslmessages.h | 11 +-
head/sys/contrib/dev/acpica/compiler/aslrestype1.c | 8 +
head/sys/contrib/dev/acpica/compiler/aslstartup.c | 78 +-
head/sys/contrib/dev/acpica/compiler/aslsupport.l | 804 +
head/sys/contrib/dev/acpica/compiler/aslutils.c | 90 +-
head/sys/contrib/dev/acpica/compiler/dtio.c | 60 +-
head/sys/contrib/dev/acpica/compiler/dttemplate.c | 2 +-
head/sys/contrib/dev/acpica/compiler/preprocess.h | 17 -
head/sys/contrib/dev/acpica/compiler/prscan.c | 73 +-
head/sys/contrib/dev/acpica/compiler/prutils.c | 125 +-
head/sys/contrib/dev/acpica/components/debugger/dbcmds.c | 120 +-
head/sys/contrib/dev/acpica/components/debugger/dbdisply.c | 15 +-
head/sys/contrib/dev/acpica/components/debugger/dbexec.c | 6 +-
head/sys/contrib/dev/acpica/components/debugger/dbfileio.c | 13 +
head/sys/contrib/dev/acpica/components/debugger/dbinput.c | 4 +-
head/sys/contrib/dev/acpica/components/debugger/dbstats.c | 28 +-
head/sys/contrib/dev/acpica/components/debugger/dbutils.c | 9 +-
head/sys/contrib/dev/acpica/components/disassembler/dmopcode.c | 213 +
head/sys/contrib/dev/acpica/components/disassembler/dmwalk.c | 55 +-
head/sys/contrib/dev/acpica/components/dispatcher/dsfield.c | 88 +-
head/sys/contrib/dev/acpica/components/dispatcher/dsopcode.c | 14 +-
head/sys/contrib/dev/acpica/components/events/evgpe.c | 15 +-
head/sys/contrib/dev/acpica/components/events/evgpeutil.c | 19 +
head/sys/contrib/dev/acpica/components/events/evmisc.c | 203 +-
head/sys/contrib/dev/acpica/components/events/evxface.c | 362 +-
head/sys/contrib/dev/acpica/components/events/evxfgpe.c | 86 +-
head/sys/contrib/dev/acpica/components/executer/exconfig.c | 2 +-
head/sys/contrib/dev/acpica/components/executer/exdump.c | 29 +-
head/sys/contrib/dev/acpica/components/executer/exprep.c | 4 +-
head/sys/contrib/dev/acpica/components/executer/exresolv.c | 2 +-
head/sys/contrib/dev/acpica/components/executer/exstore.c | 6 +-
head/sys/contrib/dev/acpica/components/executer/exutils.c | 2 +-
head/sys/contrib/dev/acpica/components/hardware/hwesleep.c | 8 +-
head/sys/contrib/dev/acpica/components/hardware/hwsleep.c | 25 -
head/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c | 8 +
head/sys/contrib/dev/acpica/components/namespace/nspredef.c | 2 +-
head/sys/contrib/dev/acpica/components/parser/psxface.c | 4 +-
head/sys/contrib/dev/acpica/components/resources/rscreate.c | 6 +-
head/sys/contrib/dev/acpica/components/resources/rsutils.c | 2 +-
head/sys/contrib/dev/acpica/components/tables/tbfadt.c | 64 +-
head/sys/contrib/dev/acpica/components/tables/tbinstal.c | 5 +-
head/sys/contrib/dev/acpica/components/tables/tbutils.c | 45 +-
head/sys/contrib/dev/acpica/components/tables/tbxface.c | 169 +-
head/sys/contrib/dev/acpica/components/tables/tbxfload.c | 415 +
head/sys/contrib/dev/acpica/components/tables/tbxfroot.c | 2 +-
head/sys/contrib/dev/acpica/components/utilities/utdecode.c | 62 +-
head/sys/contrib/dev/acpica/components/utilities/utdelete.c | 21 +-
head/sys/contrib/dev/acpica/components/utilities/utexcep.c | 174 +
head/sys/contrib/dev/acpica/components/utilities/utglobal.c | 9 +-
head/sys/contrib/dev/acpica/components/utilities/utmisc.c | 87 +-
head/sys/contrib/dev/acpica/components/utilities/utobject.c | 6 +-
head/sys/contrib/dev/acpica/components/utilities/utresrc.c | 4 +-
head/sys/contrib/dev/acpica/components/utilities/uttrack.c | 6 +-
head/sys/contrib/dev/acpica/components/utilities/utxferror.c | 81 +
head/sys/contrib/dev/acpica/include/acdebug.h | 5 +-
head/sys/contrib/dev/acpica/include/acdisasm.h | 8 +
head/sys/contrib/dev/acpica/include/acexcep.h | 5 +-
head/sys/contrib/dev/acpica/include/acglobal.h | 22 +-
head/sys/contrib/dev/acpica/include/aclocal.h | 45 +-
head/sys/contrib/dev/acpica/include/acmacros.h | 4 +-
head/sys/contrib/dev/acpica/include/acobject.h | 15 +-
head/sys/contrib/dev/acpica/include/acoutput.h | 4 +
head/sys/contrib/dev/acpica/include/acpiosxf.h | 2 +-
head/sys/contrib/dev/acpica/include/acpixf.h | 36 +-
head/sys/contrib/dev/acpica/include/acpredef.h | 6 +-
head/sys/contrib/dev/acpica/include/actbl1.h | 2 +-
head/sys/contrib/dev/acpica/include/actypes.h | 7 +-
head/sys/contrib/dev/acpica/include/acutils.h | 6 +-
head/sys/contrib/dev/acpica/include/platform/acenv.h | 2 +-
head/sys/contrib/dev/acpica/os_specific/service_layers/osunixxf.c | 21 +
head/sys/contrib/dev/iwn/iwlwifi-6000g2a-17.168.5.3.fw.uu | 7833 ++++++
head/sys/contrib/dev/iwn/iwlwifi-6000g2b-18.168.6.1.fw.uu | 11961 ++++++++++
head/sys/contrib/dev/ral/LICENSE.orig | 16 +
head/sys/contrib/dev/ral/rt2561.fw.uu.orig | 202 +
head/sys/contrib/dev/ral/rt2561s.fw.uu.orig | 202 +
head/sys/contrib/dev/ral/rt2661.fw.uu.orig | 202 +
head/sys/contrib/dev/ral/rt2860.fw.uu.orig | 202 +
head/sys/contrib/libfdt/fdt.c | 9 +
head/sys/contrib/libfdt/fdt_empty_tree.c | 84 +
head/sys/contrib/libfdt/fdt_ro.c | 125 +-
head/sys/contrib/libfdt/fdt_rw.c | 27 +
head/sys/contrib/libfdt/libfdt.h | 378 +-
head/sys/contrib/libfdt/libfdt_env.h | 16 +-
head/sys/contrib/libfdt/libfdt_internal.h | 1 +
head/sys/contrib/pf/net/pf.c | 6 +-
head/sys/contrib/pf/net/pf_if.c | 5 +-
head/sys/contrib/pf/net/pf_ioctl.c | 6 +-
head/sys/contrib/pf/net/pf_table.c | 3 +-
head/sys/contrib/pf/net/pfvar.h | 2 +
head/sys/contrib/rdma/krping/krping.c | 50 +-
head/sys/contrib/rdma/krping/krping.h | 6 +-
head/sys/contrib/rdma/krping/krping_dev.c | 8 +-
head/sys/contrib/rdma/rdma_addr.c | 7 +-
head/sys/contrib/rdma/rdma_cache.c | 4 +-
head/sys/geom/bde/g_bde.c | 8 +-
head/sys/geom/eli/g_eli.c | 4 +-
head/sys/geom/eli/g_eli.h | 19 +-
head/sys/geom/eli/g_eli_ctl.c | 8 +-
head/sys/geom/eli/g_eli_integrity.c | 9 +-
head/sys/geom/eli/g_eli_key.c | 6 +-
head/sys/geom/eli/g_eli_key_cache.c | 12 +-
head/sys/geom/gate/g_gate.c | 322 +-
head/sys/geom/gate/g_gate.h | 31 +-
head/sys/geom/geom.h | 9 +-
head/sys/geom/geom_aes.c | 6 +-
head/sys/geom/geom_dev.c | 4 +-
head/sys/geom/geom_disk.c | 75 +-
head/sys/geom/geom_disk.h | 8 +-
head/sys/geom/geom_flashmap.c | 256 +
head/sys/geom/geom_map.c | 21 +-
head/sys/geom/geom_slice.c | 6 +-
head/sys/geom/geom_subr.c | 88 +-
head/sys/geom/label/g_label_ufs.c | 8 +-
head/sys/geom/mirror/g_mirror.c | 28 +-
head/sys/geom/mirror/g_mirror.h | 7 +-
head/sys/geom/mirror/g_mirror_ctl.c | 15 +-
head/sys/geom/mountver/g_mountver.c | 16 +-
head/sys/geom/multipath/g_multipath.c | 31 +-
head/sys/geom/nop/g_nop.c | 30 +-
head/sys/geom/nop/g_nop.h | 3 +-
head/sys/geom/part/g_part.c | 14 +-
head/sys/geom/part/g_part.h | 3 +-
head/sys/geom/part/g_part_apm.c | 9 +-
head/sys/geom/part/g_part_bsd.c | 9 +-
head/sys/geom/part/g_part_gpt.c | 27 +-
head/sys/geom/part/g_part_vtoc8.c | 9 +-
head/sys/geom/raid/g_raid.c | 178 +-
head/sys/geom/raid/g_raid.h | 41 +-
head/sys/geom/raid/g_raid_ctl.c | 4 +-
head/sys/geom/raid/g_raid_md_if.m | 21 +-
head/sys/geom/raid/md_ddf.c | 3068 ++
head/sys/geom/raid/md_ddf.h | 345 +
head/sys/geom/raid/md_intel.c | 7 +-
head/sys/geom/raid/md_jmicron.c | 5 +-
head/sys/geom/raid/md_nvidia.c | 5 +-
head/sys/geom/raid/md_promise.c | 7 +-
head/sys/geom/raid/md_sii.c | 5 +-
head/sys/geom/raid/tr_raid1.c | 16 +-
head/sys/geom/raid/tr_raid1e.c | 26 +-
head/sys/geom/raid/tr_raid5.c | 112 +-
head/sys/geom/uncompress/g_uncompress.c | 6 +-
head/sys/geom/uzip/g_uzip.c | 6 +-
head/sys/gnu/fs/reiserfs/reiserfs_inode.c | 6 +-
head/sys/gnu/fs/xfs/FreeBSD/xfs_buf.c | 6 +-
head/sys/ofed/drivers/infiniband/core/cma.c | 21 +-
head/sys/ofed/drivers/infiniband/core/iwcm.c | 3 +
head/sys/ofed/drivers/net/mlx4/en_netdev.c | 2 +-
head/sys/ofed/include/linux/net.h | 8 +-
head/sys/ofed/include/linux/workqueue.h | 2 +-
head/sys/ofed/include/net/netevent.h | 7 +-
head/sys/ofed/include/rdma/iw_cm.h | 4 +-
head/sys/security/mac_mls/mac_mls.c | 5 +-
head/sys/ufs/ffs/ffs_alloc.c | 9 +-
head/sys/ufs/ffs/ffs_extern.h | 4 +-
head/sys/ufs/ffs/ffs_inode.c | 7 +-
head/sys/ufs/ffs/ffs_snapshot.c | 12 +-
head/sys/ufs/ffs/ffs_softdep.c | 79 +-
head/sys/ufs/ffs/ffs_vfsops.c | 6 +-
head/sys/ufs/ffs/ffs_vnops.c | 25 +-
head/sys/ufs/ufs/ufs_extattr.c | 44 +-
head/sys/ufs/ufs/ufs_inode.c | 10 +-
head/sys/ufs/ufs/ufs_lookup.c | 4 +-
head/sys/ufs/ufs/ufs_vnops.c | 27 +-
head/sys/ufs/ufs/ufsmount.h | 6 +-
head/sys/vm/device_pager.c | 57 +-
head/sys/vm/memguard.c | 28 +-
head/sys/vm/memguard.h | 4 +-
head/sys/vm/pmap.h | 5 +-
head/sys/vm/swap_pager.c | 4 +-
head/sys/vm/uma_core.c | 10 +-
head/sys/vm/vm.h | 4 +-
head/sys/vm/vm_contig.c | 351 -
head/sys/vm/vm_fault.c | 169 +-
head/sys/vm/vm_kern.c | 144 +-
head/sys/vm/vm_map.c | 19 +-
head/sys/vm/vm_map.h | 17 +-
head/sys/vm/vm_mmap.c | 8 +-
head/sys/vm/vm_object.c | 11 +-
head/sys/vm/vm_object.h | 17 +-
head/sys/vm/vm_page.c | 90 +-
head/sys/vm/vm_page.h | 57 +-
head/sys/vm/vm_pageout.c | 236 +-
head/sys/vm/vm_pageout.h | 6 +-
head/sys/vm/vm_pager.c | 18 +-
head/sys/vm/vm_pager.h | 3 +-
head/sys/vm/vm_phys.c | 119 +-
head/sys/vm/vm_phys.h | 6 +-
head/sys/vm/vm_reserv.c | 4 +-
head/sys/vm/vnode_pager.c | 6 +-
454 files changed, 55199 insertions(+), 11136 deletions(-)
diffs (85172 lines):
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/Makefile.sparc64
--- a/head/sys/boot/Makefile.sparc64 Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/Makefile.sparc64 Wed Jul 25 16:45:04 2012 +0300
@@ -1,3 +1,4 @@
-# $FreeBSD$
+# $FreeBSD: head/sys/boot/Makefile.sparc64 235364 2012-05-12 20:27:33Z avg $
SUBDIR+= ofw
+SUBDIR+= zfs
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/arm/at91/boot0spi/main.c
--- a/head/sys/boot/arm/at91/boot0spi/main.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/arm/at91/boot0spi/main.c Wed Jul 25 16:45:04 2012 +0300
@@ -21,7 +21,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/boot/arm/at91/boot0spi/main.c 238188 2012-07-07 04:55:42Z imp $
*/
#include "at91rm9200.h"
@@ -29,31 +29,26 @@
#include "at91rm9200_lowlevel.h"
#include "spi_flash.h"
-#define LOADER_OFFSET 0
-#define FPGA_OFFSET (15 * FLASH_PAGE_SIZE)
-#define OFFSET FPGA_OFFSET
+#define OFFSET 0
-int
+void
main(void)
{
int len, i, j, off, sec;
char *addr = (char *)SDRAM_BASE + (1 << 20); /* download at + 1MB */
char *addr2 = (char *)SDRAM_BASE + (2 << 20); /* readback to + 2MB */
- char *addr3 = (char *)SDRAM_BASE + (3 << 20); /* extra copy at + 3MB */
SPI_InitFlash();
printf("Waiting for data\n");
while ((len = xmodem_rx(addr)) == -1)
continue;
- // Need extra copy at addr3
- memcpy(addr3, addr, (len + FLASH_PAGE_SIZE - 1) / FLASH_PAGE_SIZE * FLASH_PAGE_SIZE);
- printf("Writing %u bytes to flash at %u\n", len, OFFSET);
+ printf("Writing %u bytes at %u\n", len, OFFSET);
for (i = 0; i < len; i+= FLASH_PAGE_SIZE) {
+ off = i + OFFSET;
for (j = 0; j < 10; j++) {
- off = i + OFFSET;
SPI_WriteFlash(off, addr + i, FLASH_PAGE_SIZE);
SPI_ReadFlash(off, addr2 + i, FLASH_PAGE_SIZE);
- if (p_memcmp(addr3 + i, addr2 + i, FLASH_PAGE_SIZE) == 0)
+ if (p_memcmp(addr + i, addr2 + i, FLASH_PAGE_SIZE) == 0)
break;
}
if (j >= 10)
@@ -64,5 +59,4 @@
continue;
printf("Done\n");
reset();
- return (1);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/arm/at91/boot2/boot2.c
--- a/head/sys/boot/arm/at91/boot2/boot2.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/arm/at91/boot2/boot2.c Wed Jul 25 16:45:04 2012 +0300
@@ -16,7 +16,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/boot/arm/at91/boot2/boot2.c 226506 2011-10-18 09:46:52Z des $");
+__FBSDID("$FreeBSD: head/sys/boot/arm/at91/boot2/boot2.c 235988 2012-05-25 09:36:39Z gleb $");
#include <sys/param.h>
#include <sys/disklabel.h>
@@ -86,15 +86,15 @@
RBX_VERBOSE
};
+unsigned board_id; /* board type to pass to kernel, if set by board_* code */
unsigned dsk_start;
static char cmd[512];
static char kname[1024];
static uint32_t opts;
-static int dsk_meta;
+static uint8_t dsk_meta;
static void load(void);
static int parse(void);
-static int xfsread(ino_t, void *, size_t);
static int dskread(void *, unsigned, unsigned);
#ifdef FIXUP_BOOT_DRV
static void fixup_boot_drv(caddr_t, int, int, int);
@@ -110,7 +110,7 @@
#endif
static inline int
-xfsread(ino_t inode, void *buf, size_t nbyte)
+xfsread(ufs_ino_t inode, void *buf, size_t nbyte)
{
if ((size_t)fsread(inode, buf, nbyte) != nbyte)
return -1;
@@ -153,7 +153,7 @@
main(void)
{
int autoboot, c = 0;
- ino_t ino;
+ ufs_ino_t ino;
dmadat = (void *)(0x20000000 + (16 << 20));
board_init();
@@ -198,7 +198,7 @@
Elf32_Ehdr eh;
static Elf32_Phdr ep[2];
caddr_t p;
- ino_t ino;
+ ufs_ino_t ino;
uint32_t addr;
int i, j;
#ifdef FIXUP_BOOT_DRV
@@ -241,7 +241,7 @@
#ifdef FIXUP_BOOT_DRV
fixup_boot_drv(staddr, klen, bootslice, bootpart);
#endif
- ((void(*)(int))addr)(opts & RBX_MASK);
+ ((void(*)(int, int, int, int))addr)(opts & RBX_MASK, board_id, 0, 0);
}
static int
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/arm/at91/bootspi/ee.c
--- a/head/sys/boot/arm/at91/bootspi/ee.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/arm/at91/bootspi/ee.c Wed Jul 25 16:45:04 2012 +0300
@@ -18,7 +18,7 @@
* only.
* END_BLOCK
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/boot/arm/at91/bootspi/ee.c 238463 2012-07-15 05:35:14Z imp $
*****************************************************************************/
#include "at91rm9200_lowlevel.h"
@@ -59,11 +59,11 @@
AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC;
- pPio->PIO_ASR = AT91C_PA25_TWD | AT91C_PA26_TWCK;
- pPio->PIO_PDR = AT91C_PA25_TWD | AT91C_PA26_TWCK;
+ pPio->PIO_ASR = AT91C_PIO_PA25 | AT91C_PIO_PA26;
+ pPio->PIO_PDR = AT91C_PIO_PA25 | AT91C_PIO_PA26;
- pPio->PIO_MDDR = ~AT91C_PA25_TWD;
- pPio->PIO_MDER = AT91C_PA25_TWD;
+ pPio->PIO_MDDR = ~AT91C_PIO_PA25;
+ pPio->PIO_MDER = AT91C_PIO_PA25;
pPMC->PMC_PCER = 1u << AT91C_ID_TWI;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/arm/at91/libat91/Makefile
--- a/head/sys/boot/arm/at91/libat91/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/arm/at91/libat91/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,10 +1,12 @@
-# $FreeBSD$
+# $FreeBSD: head/sys/boot/arm/at91/libat91/Makefile 238187 2012-07-07 04:51:59Z imp $
.include "${.CURDIR}/../Makefile.inc"
+SOC?=at91rm9200
+
LIB= at91
INTERNALLIB=
-SRCS=at91rm9200_lowlevel.c delay.c eeprom.c emac.c emac_init.c getc.c \
+SRCS=${SOC}_lowlevel.c delay.c eeprom.c emac.c emac_init.c getc.c \
putchar.c printf.c reset.c spi_flash.c xmodem.c \
sd-card.c strcvt.c strlen.c strcmp.c memcpy.c strcpy.c \
memset.c memcmp.c
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/arm/at91/libat91/at91rm9200.h
--- a/head/sys/boot/arm/at91/libat91/at91rm9200.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/arm/at91/libat91/at91rm9200.h Wed Jul 25 16:45:04 2012 +0300
@@ -7,7 +7,7 @@
// fitness for any particular purpose, or against the infringements of
// intellectual property rights of others.
// ----------------------------------------------------------------------------
-// $FreeBSD$
+// $FreeBSD: head/sys/boot/arm/at91/libat91/at91rm9200.h 238463 2012-07-15 05:35:14Z imp $
//
// File Name : AT91RM9200.h
// Object : AT91RM9200 definitions
@@ -41,6 +41,8 @@
#ifndef AT91RM9200_H
#define AT91RM9200_H
+#define ATMEL_ENV
+
typedef volatile unsigned int AT91_REG;// Hardware register definition
// *****************************************************************************
@@ -2309,7 +2311,7 @@
// ========== Register definition for BFC peripheral ==========
#define AT91C_BFC_MR ((AT91_REG *) 0xFFFFFFC0) // (BFC) BFC Mode Register
-#include <at91/at91_pio_rm9200.h>
+#include <at91/at91_pioreg.h>
// *****************************************************************************
// PERIPHERAL ID DEFINITIONS FOR AT91RM9200
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.c
--- a/head/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.c Wed Jul 25 16:45:04 2012 +0300
@@ -24,7 +24,7 @@
* This software is derived from software provide by Kwikbyte who specifically
* disclaimed copyright on the code.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/boot/arm/at91/libat91/at91rm9200_lowlevel.c 238463 2012-07-15 05:35:14Z imp $
*/
#include "at91rm9200.h"
@@ -188,8 +188,8 @@
AT91C_BASE_PIOC->PIO_PDR = 0xffff0000;
#endif
// Configure DBGU -use local routine optimized for space
- AT91C_BASE_PIOA->PIO_ASR = AT91C_PA31_DTXD | AT91C_PA30_DRXD;
- AT91C_BASE_PIOA->PIO_PDR = AT91C_PA31_DTXD | AT91C_PA30_DRXD;
+ AT91C_BASE_PIOA->PIO_ASR = AT91C_PIO_PA31 | AT91C_PIO_PA30;
+ AT91C_BASE_PIOA->PIO_PDR = AT91C_PIO_PA31 | AT91C_PIO_PA30;
pUSART->US_IDR = (unsigned int) -1;
pUSART->US_CR =
AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/arm/at91/libat91/eeprom.c
--- a/head/sys/boot/arm/at91/libat91/eeprom.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/arm/at91/libat91/eeprom.c Wed Jul 25 16:45:04 2012 +0300
@@ -18,7 +18,7 @@
* only.
* END_BLOCK
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/boot/arm/at91/libat91/eeprom.c 238463 2012-07-15 05:35:14Z imp $
*****************************************************************************/
#include "at91rm9200_lowlevel.h"
@@ -58,11 +58,11 @@
AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC;
- pPio->PIO_ASR = AT91C_PA25_TWD | AT91C_PA26_TWCK;
- pPio->PIO_PDR = AT91C_PA25_TWD | AT91C_PA26_TWCK;
+ pPio->PIO_ASR = AT91C_PIO_PA25 | AT91C_PIO_PA26;
+ pPio->PIO_PDR = AT91C_PIO_PA25 | AT91C_PIO_PA26;
- pPio->PIO_MDDR = ~AT91C_PA25_TWD;
- pPio->PIO_MDER = AT91C_PA25_TWD;
+ pPio->PIO_MDDR = ~AT91C_PIO_PA25;
+ pPio->PIO_MDER = AT91C_PIO_PA25;
pPMC->PMC_PCER = 1u << AT91C_ID_TWI;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/arm/at91/libat91/emac_init.c
--- a/head/sys/boot/arm/at91/libat91/emac_init.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/arm/at91/libat91/emac_init.c Wed Jul 25 16:45:04 2012 +0300
@@ -24,7 +24,7 @@
* This software is derived from software provide by Kwikbyte who specifically
* disclaimed copyright on the code.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/boot/arm/at91/libat91/emac_init.c 238463 2012-07-15 05:35:14Z imp $
*/
/******************************************************************************
@@ -85,24 +85,24 @@
AT91C_BASE_PMC->PMC_PCER = 1u << AT91C_ID_EMAC;
AT91C_BASE_PIOA->PIO_ASR =
- AT91C_PA14_ERXER | AT91C_PA12_ERX0 | AT91C_PA13_ERX1 |
- AT91C_PA8_ETXEN | AT91C_PA16_EMDIO | AT91C_PA9_ETX0 |
- AT91C_PA10_ETX1 | AT91C_PA11_ECRS_ECRSDV | AT91C_PA15_EMDC |
- AT91C_PA7_ETXCK_EREFCK;
+ AT91C_PIO_PA14 | AT91C_PIO_PA12 | AT91C_PIO_PA13 |
+ AT91C_PIO_PA8 | AT91C_PIO_PA16 | AT91C_PIO_PA9 |
+ AT91C_PIO_PA10 | AT91C_PIO_PA11 | AT91C_PIO_PA15 |
+ AT91C_PIO_PA7;
AT91C_BASE_PIOA->PIO_PDR =
- AT91C_PA14_ERXER | AT91C_PA12_ERX0 | AT91C_PA13_ERX1 |
- AT91C_PA8_ETXEN | AT91C_PA16_EMDIO | AT91C_PA9_ETX0 |
- AT91C_PA10_ETX1 | AT91C_PA11_ECRS_ECRSDV | AT91C_PA15_EMDC |
- AT91C_PA7_ETXCK_EREFCK;
+ AT91C_PIO_PA14 | AT91C_PIO_PA12 | AT91C_PIO_PA13 |
+ AT91C_PIO_PA8 | AT91C_PIO_PA16 | AT91C_PIO_PA9 |
+ AT91C_PIO_PA10 | AT91C_PIO_PA11 | AT91C_PIO_PA15 |
+ AT91C_PIO_PA7;
#if defined(BOOT_KB920X) | defined(BOOT_BWCT) /* Really !RMII */
AT91C_BASE_PIOB->PIO_BSR =
- AT91C_PB12_ETX2 | AT91C_PB13_ETX3 | AT91C_PB14_ETXER |
- AT91C_PB15_ERX2 | AT91C_PB16_ERX3 | AT91C_PB17_ERXDV |
- AT91C_PB18_ECOL | AT91C_PB19_ERXCK;
+ AT91C_PIO_PB12 | AT91C_PIO_PB13 | AT91C_PIO_PB14 |
+ AT91C_PIO_PB15 | AT91C_PIO_PB16 | AT91C_PIO_PB17 |
+ AT91C_PIO_PB18 | AT91C_PIO_PB19;
AT91C_BASE_PIOB->PIO_PDR =
- AT91C_PB12_ETX2 | AT91C_PB13_ETX3 | AT91C_PB14_ETXER |
- AT91C_PB15_ERX2 | AT91C_PB16_ERX3 | AT91C_PB17_ERXDV |
- AT91C_PB18_ECOL | AT91C_PB19_ERXCK;
+ AT91C_PIO_PB12 | AT91C_PIO_PB13 | AT91C_PIO_PB14 |
+ AT91C_PIO_PB15 | AT91C_PIO_PB16 | AT91C_PIO_PB17 |
+ AT91C_PIO_PB18 | AT91C_PIO_PB19;
#endif
pEmac->EMAC_CTL = 0;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/arm/at91/libat91/lib_AT91RM9200.h
--- a/head/sys/boot/arm/at91/libat91/lib_AT91RM9200.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/arm/at91/libat91/lib_AT91RM9200.h Wed Jul 25 16:45:04 2012 +0300
@@ -24,7 +24,7 @@
* This software is derived from software provide by Kwikbyte who specifically
* disclaimed copyright on the code.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/boot/arm/at91/libat91/lib_AT91RM9200.h 238463 2012-07-15 05:35:14Z imp $
*/
#ifndef __LIBAT91RM9200_H
@@ -134,17 +134,17 @@
// Configure PIO controllers to periph mode
AT91F_PIO_CfgPeriph(
AT91C_BASE_PIOA, // PIO controller base address
- ((unsigned int) AT91C_PA28_MCCDA ) |
- ((unsigned int) AT91C_PA29_MCDA0 ) |
- ((unsigned int) AT91C_PA27_MCCK ), // Peripheral A
+ ((unsigned int) AT91C_PIO_PA28 ) |
+ ((unsigned int) AT91C_PIO_PA29 ) |
+ ((unsigned int) AT91C_PIO_PA27 ), // Peripheral A
0); // Peripheral B
// Configure PIO controllers to periph mode
AT91F_PIO_CfgPeriph(
AT91C_BASE_PIOB, // PIO controller base address
0, // Peripheral A
- ((unsigned int) AT91C_PB5_MCDA3 ) |
- ((unsigned int) AT91C_PB3_MCDA1 ) |
- ((unsigned int) AT91C_PB4_MCDA2 )); // Peripheral B
+ ((unsigned int) AT91C_PIO_PB5 ) |
+ ((unsigned int) AT91C_PIO_PB3 ) |
+ ((unsigned int) AT91C_PIO_PB4 )); // Peripheral B
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/arm/at91/libat91/spi_flash.c
--- a/head/sys/boot/arm/at91/libat91/spi_flash.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/arm/at91/libat91/spi_flash.c Wed Jul 25 16:45:04 2012 +0300
@@ -19,7 +19,7 @@
* only.
* END_BLOCK
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/boot/arm/at91/libat91/spi_flash.c 238463 2012-07-15 05:35:14Z imp $
*****************************************************************************/
#include "at91rm9200.h"
@@ -223,10 +223,10 @@
// enable CS0, CLK, MOSI, MISO
pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
- pPio->PIO_ASR = AT91C_PA3_NPCS0 | AT91C_PA1_MOSI | AT91C_PA0_MISO |
- AT91C_PA2_SPCK;
- pPio->PIO_PDR = AT91C_PA3_NPCS0 | AT91C_PA1_MOSI | AT91C_PA0_MISO |
- AT91C_PA2_SPCK;
+ pPio->PIO_ASR = AT91C_PIO_PA3 | AT91C_PIO_PA1 | AT91C_PIO_PA0 |
+ AT91C_PIO_PA2;
+ pPio->PIO_PDR = AT91C_PIO_PA3 | AT91C_PIO_PA1 | AT91C_PIO_PA0 |
+ AT91C_PIO_PA2;
// enable clocks to SPI
AT91C_BASE_PMC->PMC_PCER = 1u << AT91C_ID_SPI;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/arm/at91/linker.cfg
--- a/head/sys/boot/arm/at91/linker.cfg Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/arm/at91/linker.cfg Wed Jul 25 16:45:04 2012 +0300
@@ -18,7 +18,7 @@
* only.
* END_BLOCK
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/boot/arm/at91/linker.cfg 238186 2012-07-07 04:49:53Z imp $
******************************************************************************/
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
"elf32-littlearm")
@@ -31,258 +31,26 @@
.text :
{
*(.text)
- *(.text.*)
- *(.stub)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- *(.gnu.linkonce.t.*)
- *(.glue_7t) *(.glue_7)
}
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
- .rel.text :
- {
- *(.rel.text)
- *(.rel.text.*)
- *(.rel.gnu.linkonce.t.*)
- }
- .rela.text :
- {
- *(.rela.text)
- *(.rela.text.*)
- *(.rela.gnu.linkonce.t.*)
- }
- .rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
- .rel.rodata :
- {
- *(.rel.rodata)
- *(.rel.rodata.*)
- *(.rel.gnu.linkonce.r.*)
- }
- .rela.rodata :
- {
- *(.rela.rodata)
- *(.rela.rodata.*)
- *(.rela.gnu.linkonce.r.*)
- }
- .rel.data :
- {
- *(.rel.data)
- *(.rel.data.*)
- *(.rel.gnu.linkonce.d.*)
- }
- .rela.data :
- {
- *(.rela.data)
- *(.rela.data.*)
- *(.rela.gnu.linkonce.d.*)
- }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.sdata :
- {
- *(.rel.sdata)
- *(.rel.sdata.*)
- *(.rel.gnu.linkonce.s.*)
- }
- .rela.sdata :
- {
- *(.rela.sdata)
- *(.rela.sdata.*)
- *(.rela.gnu.linkonce.s.*)
- }
- .rel.sbss :
- {
- *(.rel.sbss)
- *(.rel.sbss.*)
- *(.rel.gnu.linkonce.sb.*)
- }
- .rela.sbss :
- {
- *(.rela.sbss)
- *(.rela.sbss.*)
- *(.rel.gnu.linkonce.sb.*)
- }
- .rel.sdata2 :
- {
- *(.rel.sdata2)
- *(.rel.sdata2.*)
- *(.rel.gnu.linkonce.s2.*)
- }
- .rela.sdata2 :
- {
- *(.rela.sdata2)
- *(.rela.sdata2.*)
- *(.rela.gnu.linkonce.s2.*)
- }
- .rel.sbss2 :
- {
- *(.rel.sbss2)
- *(.rel.sbss2.*)
- *(.rel.gnu.linkonce.sb2.*)
- }
- .rela.sbss2 :
- {
- *(.rela.sbss2)
- *(.rela.sbss2.*)
- *(.rela.gnu.linkonce.sb2.*)
- }
- .rel.bss :
- {
- *(.rel.bss)
- *(.rel.bss.*)
- *(.rel.gnu.linkonce.b.*)
- }
- .rela.bss :
- {
- *(.rela.bss)
- *(.rela.bss.*)
- *(.rela.gnu.linkonce.b.*)
- }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init :
- {
- KEEP (*(.init))
- } =0
- .plt : { *(.plt) }
- .fini :
- {
- KEEP (*(.fini))
- } =0
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
- .rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) }
- .rodata1 : { *(.rodata1) }
- .sdata2 : { *(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*) }
- .sbss2 : { *(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*) }
.data :
{
__data_start = . ;
*(.data)
- *(.data.*)
- *(.gnu.linkonce.d.*)
- SORT(CONSTRUCTORS)
- }
- .data1 : { *(.data1) }
- . = 0x21200000;
- .eh_frame : { KEEP (*(.eh_frame)) }
- .gcc_except_table : { *(.gcc_except_table) }
- .ctors :
- {
- /* gcc uses crtbegin.o to find the start of
- the constructors, so we make sure it is
- first. Because this is a wildcard, it
- doesn't matter if the user does not
- actually link against crtbegin.o; the
- linker won't look for a file to match a
- wildcard. The wildcard also means that it
- doesn't matter which directory crtbegin.o
- is in. */
- KEEP (*crtbegin.o(.ctors))
- /* We don't want to include the .ctor section from
- from the crtend.o file until after the sorted ctors.
- The .ctor section from the crtend file contains the
- end of ctors marker and it must be last */
- KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
- KEEP (*(SORT(.ctors.*)))
- KEEP (*(.ctors))
- }
- .dtors :
- {
- KEEP (*crtbegin.o(.dtors))
- KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
- KEEP (*(SORT(.dtors.*)))
- KEEP (*(.dtors))
- }
- .got : { *(.got.plt) *(.got) }
- .dynamic : { *(.dynamic) }
- /* We want the small data sections together, so single-instruction offsets
- can access them all, and initialized data all before uninitialized, so
- we can shorten the on-disk segment size. */
- .sdata :
- {
- *(.sdata)
- *(.sdata.*)
- *(.gnu.linkonce.s.*)
}
_edata = .;
PROVIDE (edata = .);
__bss_start = .;
__bss_start__ = .;
- .sbss :
- {
- PROVIDE (__sbss_start = .);
- PROVIDE (___sbss_start = .);
- *(.dynsbss)
- *(.sbss)
- *(.sbss.*)
- *(.gnu.linkonce.sb.*)
- *(.scommon)
- PROVIDE (__sbss_end = .);
- PROVIDE (___sbss_end = .);
- }
.bss :
{
- *(.dynbss)
*(.bss)
- *(.bss.*)
- *(.gnu.linkonce.b.*)
- *(COMMON)
- /* Align here to ensure that the .bss section occupies space up to
- _end. Align after .bss to ensure correct alignment even if the
- .bss section disappears because there are no input sections. */
. = ALIGN(32 / 8);
}
. = ALIGN(32 / 8);
_end = .;
_bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
PROVIDE (end = .);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
- /* These must appear regardless of . */
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/arm/ixp425/boot2/boot2.c
--- a/head/sys/boot/arm/ixp425/boot2/boot2.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/arm/ixp425/boot2/boot2.c Wed Jul 25 16:45:04 2012 +0300
@@ -15,7 +15,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/boot/arm/ixp425/boot2/boot2.c 226506 2011-10-18 09:46:52Z des $");
+__FBSDID("$FreeBSD: head/sys/boot/arm/ixp425/boot2/boot2.c 235988 2012-05-25 09:36:39Z gleb $");
#include <sys/param.h>
#include <sys/disklabel.h>
@@ -98,7 +98,6 @@
static void load(void);
static int parse(void);
-static int xfsread(ino_t, void *, size_t);
static int dskread(void *, unsigned, unsigned);
static int drvread(void *, unsigned, unsigned);
#ifdef FIXUP_BOOT_DRV
@@ -114,7 +113,7 @@
#endif
static inline int
-xfsread(ino_t inode, void *buf, size_t nbyte)
+xfsread(ufs_ino_t inode, void *buf, size_t nbyte)
{
if ((size_t)fsread(inode, buf, nbyte) != nbyte)
return -1;
@@ -158,7 +157,7 @@
{
const char *bt;
int autoboot, c = 0;
- ino_t ino;
+ ufs_ino_t ino;
dmadat = (void *)(0x1c0000);
p_memset((char *)dmadat, 0, 32 * 1024);
@@ -207,7 +206,7 @@
Elf32_Ehdr eh;
static Elf32_Phdr ep[2];
caddr_t p;
- ino_t ino;
+ ufs_ino_t ino;
uint32_t addr;
int i, j;
#ifdef FIXUP_BOOT_DRV
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/arm/uboot/Makefile
--- a/head/sys/boot/arm/uboot/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/arm/uboot/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-# $FreeBSD$
+# $FreeBSD: head/sys/boot/arm/uboot/Makefile 236159 2012-05-27 16:27:04Z kientzle $
.include <bsd.own.mk>
@@ -7,6 +7,9 @@
BINDIR?= /boot
INSTALLFLAGS= -b
WARNS?= 1
+# Address at which ubldr will be loaded.
+# This varies for different boards and SOCs.
+UBLDR_LOADADDR?= 0x1000000
# Architecture-specific loader code
SRCS= start.S conf.c vers.c
@@ -15,6 +18,11 @@
LOADER_UFS_SUPPORT?= yes
LOADER_CD9660_SUPPORT?= no
LOADER_EXT2FS_SUPPORT?= no
+.if ${MK_NAND} != "no"
+LOADER_NANDFS_SUPPORT?= yes
+.else
+LOADER_NANDFS_SUPPORT?= no
+.endif
LOADER_NET_SUPPORT?= yes
LOADER_NFS_SUPPORT?= yes
LOADER_TFTP_SUPPORT?= no
@@ -38,6 +46,9 @@
.if ${LOADER_EXT2FS_SUPPORT} == "yes"
CFLAGS+= -DLOADER_EXT2FS_SUPPORT
.endif
+.if ${LOADER_NANDFS_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_NANDFS_SUPPORT
+.endif
.if ${LOADER_GZIP_SUPPORT} == "yes"
CFLAGS+= -DLOADER_GZIP_SUPPORT
.endif
@@ -77,7 +88,9 @@
CFLAGS+= -ffreestanding
-LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.${MACHINE_CPUARCH}
+LDFLAGS= -nostdlib -static
+LDFLAGS+= -T ldscript.generated
+LDFLAGS+= -T ${.CURDIR}/ldscript.${MACHINE_CPUARCH}
# Pull in common loader code
.PATH: ${.CURDIR}/../../uboot/common
@@ -102,6 +115,18 @@
cat ${.ALLSRC} | \
awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET}
+${PROG}: ldscript.generated ${.CURDIR}/ldscript.${MACHINE_CPUARCH}
+
+ldscript.generated::
+ rm -f ldscript.generated.tmp
+ echo "UBLDR_LOADADDR = ${UBLDR_LOADADDR};" >ldscript.generated.tmp
+ if diff ldscript.generated ldscript.generated.tmp > /dev/null; then \
+ true; \
+ else \
+ rm -f ldscript.generated; \
+ mv ldscript.generated.tmp ldscript.generated; \
+ fi
+
.PATH: ${.CURDIR}/../../forth
FILES= loader.help
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/arm/uboot/conf.c
--- a/head/sys/boot/arm/uboot/conf.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/arm/uboot/conf.c Wed Jul 25 16:45:04 2012 +0300
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/boot/arm/uboot/conf.c 235537 2012-05-17 10:11:18Z gber $");
#include <stand.h>
#include "bootstrap.h"
@@ -56,6 +56,9 @@
#if defined(LOADER_EXT2FS_SUPPORT)
&ext2fs_fsops,
#endif
+#if defined(LOADER_NANDFS_SUPPORT)
+ &nandfs_fsops,
+#endif
#if defined(LOADER_NFS_SUPPORT)
&nfs_fsops,
#endif
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/arm/uboot/ldscript.arm
--- a/head/sys/boot/arm/uboot/ldscript.arm Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/arm/uboot/ldscript.arm Wed Jul 25 16:45:04 2012 +0300
@@ -1,11 +1,11 @@
-/* $FreeBSD$ */
+/* $FreeBSD: head/sys/boot/arm/uboot/ldscript.arm 236159 2012-05-27 16:27:04Z kientzle $ */
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
/* Read-only sections, merged into text segment: */
- . = 0x1000000 + SIZEOF_HEADERS;
+ . = UBLDR_LOADADDR + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/arm/uboot/start.S
--- a/head/sys/boot/arm/uboot/start.S Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/arm/uboot/start.S Wed Jul 25 16:45:04 2012 +0300
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/boot/arm/uboot/start.S 234908 2012-05-02 05:49:58Z kientzle $
*/
#include <machine/asm.h>
@@ -49,27 +49,20 @@
* syscall()
*/
ENTRY(syscall)
- /* Save caller's lr */
+ /* Save caller's lr and r8 */
ldr ip, =saved_regs
str lr, [ip, #4]
- /* Save loader's r8 */
- ldr ip, =saved_regs
str r8, [ip, #8]
-
/* Restore U-Boot's r8 */
- ldr ip, =saved_regs
ldr r8, [ip, #0]
/* Call into U-Boot */
ldr lr, =return_from_syscall
ldr ip, =syscall_ptr
ldr pc, [ip]
-
return_from_syscall:
- /* Restore loader's r8 */
+ /* Restore loader's r8 and lr */
ldr ip, =saved_regs
ldr r8, [ip, #8]
- /* Restore caller's lr */
- ldr ip, =saved_regs
ldr lr, [ip, #4]
/* Return to caller */
mov pc, lr
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/arm/uboot/version
--- a/head/sys/boot/arm/uboot/version Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/arm/uboot/version Wed Jul 25 16:45:04 2012 +0300
@@ -1,8 +1,9 @@
-$FreeBSD$
+$FreeBSD: head/sys/boot/arm/uboot/version 235537 2012-05-17 10:11:18Z gber $
NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
file is important. Make sure the current version number is on line 6.
+1.2: Extended with NAND FS support.
1.1: Flattened Device Tree blob support.
1.0: Added storage support. Booting from HDD, USB, etc. is now possible.
0.5: Initial U-Boot/arm version (netbooting only).
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/common/boot.c
--- a/head/sys/boot/common/boot.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/common/boot.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/boot/common/boot.c 235330 2012-05-12 09:07:41Z avg $");
/*
* Loading modules, booting the system
@@ -311,12 +311,12 @@
if (getenv("vfs.root.mountfrom") != NULL)
return(0);
+ error = 1;
sprintf(lbuf, "%s/etc/fstab", rootdev);
if ((fd = open(lbuf, O_RDONLY)) < 0)
- return(1);
+ goto notfound;
/* loop reading lines from /etc/fstab What was that about sscanf again? */
- error = 1;
while (fgetstr(lbuf, sizeof(lbuf), fd) >= 0) {
if ((lbuf[0] == 0) || (lbuf[0] == '#'))
continue;
@@ -377,6 +377,20 @@
break;
}
close(fd);
+
+notfound:
+ if (error) {
+ const char *currdev;
+
+ currdev = getenv("currdev");
+ if (currdev != NULL && strncmp("zfs:", currdev, 4) == 0) {
+ cp = strdup(currdev);
+ cp[strlen(cp) - 1] = '\0';
+ setenv("vfs.root.mountfrom", cp, 0);
+ error = 0;
+ }
+ }
+
return(error);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/common/bootstrap.h
--- a/head/sys/boot/common/bootstrap.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/common/bootstrap.h Wed Jul 25 16:45:04 2012 +0300
@@ -23,9 +23,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/boot/common/bootstrap.h 220311 2011-04-03 22:31:51Z marcel $
+ * $FreeBSD: head/sys/boot/common/bootstrap.h 235329 2012-05-12 09:03:30Z avg $
*/
+#ifndef _BOOTSTRAP_H_
+#define _BOOTSTRAP_H_
+
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/linker_set.h>
@@ -314,6 +317,9 @@
#else
void (*arch_loadseg)(void *eh, void *ph, uint64_t delta);
#endif
+
+ /* Probe ZFS pool(s), if needed. */
+ void (*arch_zfs_probe)(void);
};
extern struct arch_switch archsw;
@@ -323,3 +329,11 @@
void dev_cleanup(void);
time_t time(time_t *tloc);
+
+#ifndef CTASSERT /* Allow lint to override */
+#define CTASSERT(x) _CTASSERT(x, __LINE__)
+#define _CTASSERT(x, y) __CTASSERT(x, y)
+#define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1]
+#endif
+
+#endif /* !_BOOTSTRAP_H_ */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/common/load_elf.c
--- a/head/sys/boot/common/load_elf.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/common/load_elf.c Wed Jul 25 16:45:04 2012 +0300
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/boot/common/load_elf.c 223695 2011-06-30 16:08:56Z dfr $");
+__FBSDID("$FreeBSD: head/sys/boot/common/load_elf.c 237338 2012-06-20 21:06:51Z jhb $");
#include <sys/param.h>
#include <sys/exec.h>
@@ -612,7 +612,7 @@
Elf_Addr v, p, p_stop;
if (__elfN(lookup_symbol)(fp, ef, "__start_set_modmetadata_set", &sym) != 0)
- return ENOENT;
+ return 0;
p = sym.st_value + ef->off;
if (__elfN(lookup_symbol)(fp, ef, "__stop_set_modmetadata_set", &sym) != 0)
return ENOENT;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/common/load_elf_obj.c
--- a/head/sys/boot/common/load_elf_obj.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/common/load_elf_obj.c Wed Jul 25 16:45:04 2012 +0300
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/boot/common/load_elf_obj.c 223295 2011-06-19 13:35:41Z kan $");
+__FBSDID("$FreeBSD: head/sys/boot/common/load_elf_obj.c 237338 2012-06-20 21:06:51Z jhb $");
#include <sys/param.h>
#include <sys/exec.h>
@@ -369,7 +369,7 @@
if (__elfN(obj_lookup_set)(fp, ef, "modmetadata_set", &p, &p_stop,
&modcnt) != 0)
- return ENOENT;
+ return 0;
modcnt = 0;
while (p < p_stop) {
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/common/loader.8
--- a/head/sys/boot/common/loader.8 Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/common/loader.8 Wed Jul 25 16:45:04 2012 +0300
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD: head/sys/boot/common/loader.8 233648 2012-03-29 05:02:12Z eadler $
+.\" $FreeBSD: head/sys/boot/common/loader.8 235873 2012-05-24 02:24:03Z wblock $
.\"
.Dd January 7, 2012
.Dt LOADER 8
@@ -423,7 +423,7 @@
Defines the base i/o port used to access console UART
(i386 and amd64 only).
If the variable is not set, its assumed value is 0x3F8, which
-corresponds to PC port COM1, unless overriden by
+corresponds to PC port COM1, unless overridden by
.Va BOOT_COMCONSOLE_PORT
variable during the compilation of
.Nm .
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/common/ufsread.c
--- a/head/sys/boot/common/ufsread.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/common/ufsread.c Wed Jul 25 16:45:04 2012 +0300
@@ -44,7 +44,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/boot/common/ufsread.c 233105 2012-03-18 02:19:30Z marius $");
+__FBSDID("$FreeBSD: head/sys/boot/common/ufsread.c 235988 2012-05-25 09:36:39Z gleb $");
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
@@ -58,6 +58,8 @@
#define cgbase(fs, c) ((ufs2_daddr_t)((fs)->fs_fpg * (c)))
#endif
+typedef uint32_t ufs_ino_t;
+
/*
* We use 4k `virtual' blocks for filesystem data, whatever the actual
* filesystem block size. FFS blocks are always a multiple of 4k.
@@ -85,14 +87,14 @@
};
static struct dmadat *dmadat;
-static ino_t lookup(const char *);
-static ssize_t fsread(ino_t, void *, size_t);
+static ufs_ino_t lookup(const char *);
+static ssize_t fsread(ufs_ino_t, void *, size_t);
static uint8_t ls, dsk_meta;
static uint32_t fs_off;
static __inline uint8_t
-fsfind(const char *name, ino_t * ino)
+fsfind(const char *name, ufs_ino_t * ino)
{
static char buf[DEV_BSIZE];
struct direct *d;
@@ -116,12 +118,12 @@
return 0;
}
-static ino_t
+static ufs_ino_t
lookup(const char *path)
{
static char name[MAXNAMLEN + 1];
const char *s;
- ino_t ino;
+ ufs_ino_t ino;
ssize_t n;
uint8_t dt;
@@ -163,7 +165,7 @@
#endif
static ssize_t
-fsread(ino_t inode, void *buf, size_t nbyte)
+fsread(ufs_ino_t inode, void *buf, size_t nbyte)
{
#ifndef UFS2_ONLY
static struct ufs1_dinode dp1;
@@ -173,7 +175,7 @@
static struct ufs2_dinode dp2;
#endif
static struct fs fs;
- static ino_t inomap;
+ static ufs_ino_t inomap;
char *blkbuf;
void *indbuf;
char *s;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/fdt/dts/bindings-localbus.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/boot/fdt/dts/bindings-localbus.txt Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,83 @@
+$FreeBSD: head/sys/boot/fdt/dts/bindings-localbus.txt 235609 2012-05-18 14:41:14Z gber $
+
+Marvell Device bus (localbus) configuration.
+============================================
+
+1. Properties for localbus nodes
+
+1.1 ranges
+
+Property: ranges
+
+Value type: <prop-encoded-array> encoded as arbitrary number of localbus
+ nodes specifiers.
+
+Description: ranges property defines values used for mapping devices
+ connected to localbus, in Marvell devices it is used also for
+ setting decoding windows.
+
+ a) child node address-cells:
+ - first cell: number of bank (chip select)
+ - second cell: (Marvell devices) Target ID for decoding
+ windows setup
+
+ b) parent node address cells:
+ - address offset: used with parent's node base address to
+ specify base address of mapped device
+
+ c) child node size-cells:
+ - size: defines amount of memory that should be reserved for
+ device
+
+1.2 bank-count
+
+Property: bank-count
+
+Value type: <u32>
+
+Description: The bank_count property defines maximum number of banks on
+ localbus node. Bank is most often interpreted as device chip
+ select, but may also describe another device (e.g. SPI flash).
+
+1.3 Example
+
+ localbus at 0 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "mrvl,lbc";
+ bank-count = <5>;
+
+ /* This reflects CPU decode windows setup. */
+ ranges = <0x0 0x2f 0xb2200000 0x00100000
+ 0x1 0x3e 0xb2100000 0x00100000
+ 0x2 0x3d 0xb0000000 0x02000000
+ 0x3 0x3b 0xb2000000 0x00100000>;
+ };
+
+2. Properties for localbus consumer nodes:
+
+2.1 reg
+
+Property: reg
+
+Value type: <prop-encoded-array>
+
+Description: A standard property required for localbus child nodes. Defines
+ the device memory region.
+
+ a) first cell: number of bank (chip select)
+
+ b) address offset: used with address offset from parent's ranges
+ for corresponding bank to specify base address of
+ the device
+
+ c) size: defines size of the device memory region
+
+2.2 Example
+
+ nor at 0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x00100000>;
+ };
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/fdt/dts/db78100.dts
--- a/head/sys/boot/fdt/dts/db78100.dts Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/fdt/dts/db78100.dts Wed Jul 25 16:45:04 2012 +0300
@@ -28,7 +28,7 @@
*
* Marvell DB-78100 Device Tree Source.
*
- * $FreeBSD: head/sys/boot/fdt/dts/db78100.dts 232518 2012-03-04 19:22:52Z raj $
+ * $FreeBSD: head/sys/boot/fdt/dts/db78100.dts 235609 2012-05-18 14:41:14Z gber $
*/
/dts-v1/;
@@ -69,25 +69,23 @@
reg = <0x0 0x20000000>; // 512M at 0x0
};
- localbus at f1000000 {
+ localbus at 0 {
#address-cells = <2>;
#size-cells = <1>;
compatible = "mrvl,lbc";
- win-count = <14>;
+ bank-count = <5>;
/* This reflects CPU decode windows setup. */
- ranges = <0x0 0x0f 0xf9300000 0x00100000
- 0x1 0x1e 0xfa000000 0x00100000
- 0x2 0x1d 0xfa100000 0x02000000
- 0x3 0x1b 0xfc100000 0x00000400>;
+ ranges = <0x0 0x2f 0xf9300000 0x00100000
+ 0x1 0x3e 0xf9400000 0x00100000
+ 0x2 0x3d 0xf9500000 0x02000000
+ 0x3 0x3b 0xfb500000 0x00100000>;
nor at 0,0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "cfi-flash";
reg = <0x0 0x0 0x00100000>;
- bank-width = <2>;
- device-width = <1>;
};
led at 1,0 {
@@ -102,16 +100,13 @@
#size-cells = <1>;
compatible = "cfi-flash";
reg = <0x2 0x0 0x02000000>;
- bank-width = <2>;
- device-width = <1>;
};
nand at 3,0 {
#address-cells = <1>;
#size-cells = <1>;
+ compatible = "mrvl,nfc";
reg = <0x3 0x0 0x00100000>;
- bank-width = <2>;
- device-width = <1>;
};
};
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/fdt/dts/db88f6281.dts
--- a/head/sys/boot/fdt/dts/db88f6281.dts Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/fdt/dts/db88f6281.dts Wed Jul 25 16:45:04 2012 +0300
@@ -28,7 +28,7 @@
*
* Marvell DB-88F6281 Device Tree Source.
*
- * $FreeBSD: head/sys/boot/fdt/dts/db88f6281.dts 227730 2011-11-19 16:30:06Z raj $
+ * $FreeBSD: head/sys/boot/fdt/dts/db88f6281.dts 235779 2012-05-22 09:27:57Z gber $
*/
/dts-v1/;
@@ -72,48 +72,33 @@
reg = <0x0 0x20000000>; // 512M at 0x0
};
- localbus at f1000000 {
+ localbus at 0 {
#address-cells = <2>;
#size-cells = <1>;
compatible = "mrvl,lbc";
+ bank-count = <3>;
/* This reflects CPU decode windows setup. */
- ranges = <0x0 0x0f 0xf9300000 0x00100000
- 0x1 0x1e 0xfa000000 0x00100000
- 0x2 0x1d 0xfa100000 0x02000000
- 0x3 0x1b 0xfc100000 0x00000400>;
+ ranges = <0x0 0x2f 0xf9300000 0x00100000>;
- nor at 0,0 {
+ nand at 0,0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "cfi-flash";
+ compatible = "mrvl,nfc";
reg = <0x0 0x0 0x00100000>;
bank-width = <2>;
device-width = <1>;
- };
- led at 1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "led";
- reg = <0x1 0x0 0x00100000>;
- };
+ slice at 0 {
+ reg = <0x0 0x200000>;
+ label = "u-boot";
+ read-only;
+ };
- nor at 2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x2 0x0 0x02000000>;
- bank-width = <2>;
- device-width = <1>;
- };
-
- nand at 3,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- reg = <0x3 0x0 0x00100000>;
- bank-width = <2>;
- device-width = <1>;
+ slice at 200000 {
+ reg = <0x200000 0x7e00000>;
+ label = "root";
+ };
};
};
@@ -305,4 +290,9 @@
0x0 0x00100000>;
};
};
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ };
};
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/fdt/dts/p2041rdb.dts
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/boot/fdt/dts/p2041rdb.dts Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,490 @@
+/*
+ * P2041RDB Device Tree Source
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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: head/sys/boot/fdt/dts/p2041rdb.dts 236024 2012-05-25 20:43:38Z raj $ */
+
+/include/ "p2041si.dtsi"
+
+/ {
+ model = "fsl,P2041RDB";
+ compatible = "fsl,P2041RDB";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ phy_rgmii_0 = &phy_rgmii_0;
+ phy_rgmii_1 = &phy_rgmii_1;
+ phy_sgmii_2 = &phy_sgmii_2;
+ phy_sgmii_3 = &phy_sgmii_3;
+ phy_sgmii_4 = &phy_sgmii_4;
+ phy_sgmii_1c = &phy_sgmii_1c;
+ phy_sgmii_1d = &phy_sgmii_1d;
+ phy_sgmii_1e = &phy_sgmii_1e;
+ phy_sgmii_1f = &phy_sgmii_1f;
+ phy_xgmii_2 = &phy_xgmii_2;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x00000000 0x00000000 0x80000000>;
+ };
+
+ dcsr: dcsr at f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+ };
+
+ bman-portals at ff4000000 {
+ bman-portal at 0 {
+ cpu-handle = <&cpu0>;
+ };
+ bman-portal at 4000 {
+ cpu-handle = <&cpu1>;
+ };
+ bman-portal at 8000 {
+ cpu-handle = <&cpu2>;
+ };
+ bman-portal at c000 {
+ cpu-handle = <&cpu3>;
+ };
+ bman-portal at 10000 {
+ };
+ bman-portal at 14000 {
+ };
+ bman-portal at 18000 {
+ };
+ bman-portal at 1c000 {
+ };
+ bman-portal at 20000 {
+ };
+ bman-portal at 24000 {
+ };
+
+ buffer-pool at 0 {
+ compatible = "fsl,p2041-bpool", "fsl,bpool";
+ fsl,bpid = <0>;
+ fsl,bpool-cfg = <0 0x100 0 1 0 0x100>;
+ };
+ };
+
+ qman-portals at ff4200000 {
+ qportal0: qman-portal at 0 {
+ cpu-handle = <&cpu0>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal1: qman-portal at 4000 {
+ cpu-handle = <&cpu1>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal2: qman-portal at 8000 {
+ cpu-handle = <&cpu2>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal3: qman-portal at c000 {
+ cpu-handle = <&cpu3>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal4: qman-portal at 10000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal5: qman-portal at 14000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal6: qman-portal at 18000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal7: qman-portal at 1c000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal8: qman-portal at 20000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal9: qman-portal at 24000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+ };
+
+ soc: soc at ffe000000 {
+ spi at 110000 {
+ flash at 0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+ partition at u-boot {
+ label = "u-boot";
+ reg = <0x00000000 0x00100000>;
+ read-only;
+ };
+ partition at kernel {
+ label = "kernel";
+ reg = <0x00100000 0x00500000>;
+ read-only;
+ };
+ partition at dtb {
+ label = "dtb";
+ reg = <0x00600000 0x00100000>;
+ read-only;
+ };
+ partition at fs {
+ label = "file system";
+ reg = <0x00700000 0x00900000>;
+ };
+ };
+ };
+
+ i2c at 118000 {
+ lm75b at 48 {
+ compatible = "nxp,lm75a";
+ reg = <0x48>;
+ };
+ eeprom at 50 {
+ compatible = "at24,24c256";
+ reg = <0x50>;
+ };
+ rtc at 68 {
+ compatible = "pericom,pt7c4338";
+ reg = <0x68>;
+ };
+ };
+
+ i2c at 118100 {
+ eeprom at 50 {
+ compatible = "at24,24c256";
+ reg = <0x50>;
+ };
+ };
+
+ usb1: usb at 211000 {
+ dr_mode = "host";
+ };
+
+ pme: pme at 316000 {
+ /* Commented out, use default allocation */
+ /* fsl,pme-pdsr = <0x0 0x23000000 0x0 0x01000000>; */
+ /* fsl,pme-sre = <0x0 0x24000000 0x0 0x00a00000>; */
+ };
+
+ qman: qman at 318000 {
+ /* Commented out, use default allocation */
+ /* fsl,qman-fqd = <0x0 0x20000000 0x0 0x01000000>; */
+ /* fsl,qman-pfdr = <0x0 0x21000000 0x0 0x01000000>; */
+ };
+
+ bman: bman at 31a000 {
+ /* Same as fsl,qman-*, use default allocation */
+ /* fsl,bman-fbpr = <0x0 0x22000000 0x0 0x01000000>; */
+ };
+
+ fman0: fman at 400000 {
+ enet0: ethernet at e0000 {
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy_sgmii_2>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio0: mdio at e1120 {
+ tbi0: tbi-phy at 8 {
+ reg = <0x8>;
+ device_type = "tbi-phy";
+ };
+
+ phy_rgmii_0: ethernet-phy at 0 {
+ reg = <0x0>;
+ };
+ phy_rgmii_1: ethernet-phy at 1 {
+ reg = <0x1>;
+ };
+ phy_sgmii_2: ethernet-phy at 2 {
+ reg = <0x2>;
+ };
+ phy_sgmii_3: ethernet-phy at 3 {
+ reg = <0x3>;
+ };
+ phy_sgmii_4: ethernet-phy at 4 {
+ reg = <0x4>;
+ };
+ phy_sgmii_1c: ethernet-phy at 1c {
+ reg = <0x1c>;
+ };
+ phy_sgmii_1d: ethernet-phy at 1d {
+ reg = <0x1d>;
+ };
+ phy_sgmii_1e: ethernet-phy at 1e {
+ reg = <0x1e>;
+ };
+ phy_sgmii_1f: ethernet-phy at 1f {
+ reg = <0x1f>;
+ };
+ };
+
+ enet1: ethernet at e2000 {
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy_sgmii_3>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio at e3120 {
+ tbi1: tbi-phy at 8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet2: ethernet at e4000 {
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy_sgmii_4>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio at e5120 {
+ tbi2: tbi-phy at 8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet3: ethernet at e6000 {
+ tbi-handle = <&tbi3>;
+ phy-handle = <&phy_rgmii_1>;
+ phy-connection-type = "rgmii";
+ };
+
+ mdio at e7120 {
+ tbi3: tbi-phy at 8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet4: ethernet at e8000 {
+ tbi-handle = <&tbi4>;
+ phy-handle = <&phy_rgmii_0>;
+ phy-connection-type = "rgmii";
+ };
+
+ mdio at e9120 {
+ tbi4: tbi-phy at 8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet5: ethernet at f0000 {
+ /*
+ * phy-handle will be updated by U-Boot to
+ * reflect the actual slot the XAUI card is in.
+ */
+ phy-handle = <&phy_xgmii_2>;
+ phy-connection-type = "xgmii";
+ };
+
+ mdio at f1000 {
+ /* XAUI card in slot 2 */
+ phy_xgmii_2: ethernet-phy at 0 {
+ reg = <0x0>;
+ };
+ };
+ };
+ };
+
+ rapidio at ffe0c0000 {
+ reg = <0xf 0xfe0c0000 0 0x11000>;
+
+ port1 {
+ ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+ };
+ port2 {
+ ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+ };
+ };
+
+ localbus at ffe124000 {
+ reg = <0xf 0xfe124000 0 0x1000>;
+ ranges = <0 0 0xf 0xb8000000 0x04000000>;
+
+ flash at 0,0 {
+ compatible = "cfi-flash";
+ /*
+ * Map 64Mb of 128MB NOR flash memory. Since highest
+ * line of address of NOR flash memory are set by
+ * FPGA, memory are divided into two pages equal to
+ * 64MB. One of the pages can be accessed at once.
+ */
+ reg = <0 0 0x04000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ };
+ };
+
+ pci0: pcie at ffe200000 {
+ reg = <0xf 0xfe200000 0 0x1000>;
+ ranges = <0x02000000 0 0x80000000 0x0 0x80000000 0x0 0x10000000
+ 0x01000000 0 0x00000000 0x0 0xff000000 0x0 0x00010000>;
+ pcie at 0 {
+ ranges = <0x02000000 0 0x80000000
+ 0x02000000 0 0x80000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0xff000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie at ffe201000 {
+ reg = <0xf 0xfe201000 0 0x1000>;
+ ranges = <0x02000000 0x0 0x90000000 0x0 0x90000000 0x0 0x10000000
+ 0x01000000 0x0 0x00000000 0x0 0xff010000 0x0 0x00010000>;
+ pcie at 0 {
+ ranges = <0x02000000 0 0x90000000
+ 0x02000000 0 0x90000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0xff010000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie at ffe202000 {
+ reg = <0xf 0xfe202000 0 0x1000>;
+ ranges = <0x02000000 0 0xa0000000 0x0 0xa0000000 0 0x10000000
+ 0x01000000 0 0x00000000 0x0 0xff020000 0 0x00010000>;
+ pcie at 0 {
+ ranges = <0x02000000 0 0xa0000000
+ 0x02000000 0 0xa0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0xff020000
+ 0 0x00010000>;
+ };
+ };
+
+ fsl,dpaa {
+ compatible = "fsl,p2041-dpaa", "fsl,dpaa";
+
+ ethernet at 0 {
+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet0>;
+ status = "okay";
+ };
+ ethernet at 1 {
+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet1>;
+ status = "okay";
+ };
+ ethernet at 2 {
+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet2>;
+ status = "okay";
+ };
+ ethernet at 3 {
+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet3>;
+ status = "okay";
+ };
+ ethernet at 4 {
+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet4>;
+ status = "okay";
+ };
+ ethernet at 5 {
+ compatible = "fsl,p2041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet5>;
+ status = "okay";
+ };
+ };
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+};
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/fdt/dts/p2041si.dtsi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/boot/fdt/dts/p2041si.dtsi Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,1296 @@
+/*
+ * P2041 Silicon Device Tree Source
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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: head/sys/boot/fdt/dts/p2041si.dtsi 236024 2012-05-25 20:43:38Z raj $ */
+
+/dts-v1/;
+
+/ {
+ compatible = "fsl,P2041";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ ccsr = &soc;
+ dcsr = &dcsr;
+
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
+ ethernet5 = &enet5;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ serial2 = &serial2;
+ serial3 = &serial3;
+ pci0 = &pci0;
+ pci1 = &pci1;
+ pci2 = &pci2;
+ usb0 = &usb0;
+ usb1 = &usb1;
+ dma0 = &dma0;
+ dma1 = &dma1;
+ bman = &bman;
+ qman = &qman;
+ pme = &pme;
+ rman = &rman;
+ sdhc = &sdhc;
+ msi0 = &msi0;
+ msi1 = &msi1;
+ msi2 = &msi2;
+
+ crypto = &crypto;
+ sec_jr0 = &sec_jr0;
+ sec_jr1 = &sec_jr1;
+ sec_jr2 = &sec_jr2;
+ sec_jr3 = &sec_jr3;
+ rtic_a = &rtic_a;
+ rtic_b = &rtic_b;
+ rtic_c = &rtic_c;
+ rtic_d = &rtic_d;
+ sec_mon = &sec_mon;
+
+ fman0 = &fman0;
+ fman0_oh0 = &fman0_oh0;
+ fman0_oh1 = &fman0_oh1;
+ fman0_oh2 = &fman0_oh2;
+ fman0_oh3 = &fman0_oh3;
+ fman0_oh4 = &fman0_oh4;
+ fman0_oh5 = &fman0_oh5;
+ fman0_oh6 = &fman0_oh6;
+ fman0_rx0 = &fman0_rx0;
+ fman0_rx1 = &fman0_rx1;
+ fman0_rx2 = &fman0_rx2;
+ fman0_rx3 = &fman0_rx3;
+ fman0_rx4 = &fman0_rx4;
+ fman0_rx5 = &fman0_rx5;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: PowerPC,e500mc at 0 {
+ device_type = "cpu";
+ reg = <0>;
+ bus-frequency = <749999996>;
+ next-level-cache = <&L2_0>;
+ L2_0: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ cpu1: PowerPC,e500mc at 1 {
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2_1>;
+ L2_1: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ cpu2: PowerPC,e500mc at 2 {
+ device_type = "cpu";
+ reg = <2>;
+ next-level-cache = <&L2_2>;
+ L2_2: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ cpu3: PowerPC,e500mc at 3 {
+ device_type = "cpu";
+ reg = <3>;
+ next-level-cache = <&L2_3>;
+ L2_3: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ };
+
+ dcsr: dcsr at f00000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,dcsr", "simple-bus";
+
+ dcsr-epu at 0 {
+ compatible = "fsl,dcsr-epu";
+ interrupts = <52 2 0 0
+ 84 2 0 0
+ 85 2 0 0>;
+ interrupt-parent = <&mpic>;
+ reg = <0x0 0x1000>;
+ };
+ dcsr-npc {
+ compatible = "fsl,dcsr-npc";
+ reg = <0x1000 0x1000 0x1000000 0x8000>;
+ };
+ dcsr-nxc at 2000 {
+ compatible = "fsl,dcsr-nxc";
+ reg = <0x2000 0x1000>;
+ };
+ dcsr-corenet {
+ compatible = "fsl,dcsr-corenet";
+ reg = <0x8000 0x1000 0xB0000 0x1000>;
+ };
+ dcsr-dpaa at 9000 {
+ compatible = "fsl,p2041-dcsr-dpaa", "fsl,dcsr-dpaa";
+ reg = <0x9000 0x1000>;
+ };
+ dcsr-ocn at 11000 {
+ compatible = "fsl,p2041-dcsr-ocn", "fsl,dcsr-ocn";
+ reg = <0x11000 0x1000>;
+ };
+ dcsr-ddr at 12000 {
+ compatible = "fsl,dcsr-ddr";
+ dev-handle = <&ddr>;
+ reg = <0x12000 0x1000>;
+ };
+ dcsr-nal at 18000 {
+ compatible = "fsl,p2041-dcsr-nal", "fsl,dcsr-nal";
+ reg = <0x18000 0x1000>;
+ };
+ dcsr-rcpm at 22000 {
+ compatible = "fsl,p2041-dcsr-rcpm", "fsl,dcsr-rcpm";
+ reg = <0x22000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy at 40000 {
+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu0>;
+ reg = <0x40000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy at 41000 {
+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu1>;
+ reg = <0x41000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy at 42000 {
+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu2>;
+ reg = <0x42000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy at 43000 {
+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu3>;
+ reg = <0x43000 0x1000>;
+ };
+ };
+
+ bman-portals at ff4000000 {
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ compatible = "bman-portals";
+ ranges = <0x0 0xf 0xfde00000 0x200000>;
+ bman-portal at 0 {
+ cell-index = <0x0>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0x0 0x4000 0x100000 0x1000>;
+ interrupts = <105 2 0 0>;
+ };
+ bman-portal at 4000 {
+ cell-index = <0x1>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0x4000 0x4000 0x101000 0x1000>;
+ interrupts = <107 2 0 0>;
+ };
+ bman-portal at 8000 {
+ cell-index = <2>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0x8000 0x4000 0x102000 0x1000>;
+ interrupts = <109 2 0 0>;
+ };
+ bman-portal at c000 {
+ cell-index = <0x3>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0xc000 0x4000 0x103000 0x1000>;
+ interrupts = <111 2 0 0>;
+ };
+ bman-portal at 10000 {
+ cell-index = <0x4>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0x10000 0x4000 0x104000 0x1000>;
+ interrupts = <113 2 0 0>;
+ };
+ bman-portal at 14000 {
+ cell-index = <0x5>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0x14000 0x4000 0x105000 0x1000>;
+ interrupts = <115 2 0 0>;
+ };
+ bman-portal at 18000 {
+ cell-index = <0x6>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0x18000 0x4000 0x106000 0x1000>;
+ interrupts = <117 2 0 0>;
+ };
+ bman-portal at 1c000 {
+ cell-index = <0x7>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0x1c000 0x4000 0x107000 0x1000>;
+ interrupts = <119 2 0 0>;
+ };
+ bman-portal at 20000 {
+ cell-index = <0x8>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0x20000 0x4000 0x108000 0x1000>;
+ interrupts = <121 2 0 0>;
+ };
+ bman-portal at 24000 {
+ cell-index = <0x9>;
+ compatible = "fsl,p2041-bman-portal", "fsl,bman-portal";
+ reg = <0x24000 0x4000 0x109000 0x1000>;
+ interrupts = <123 2 0 0>;
+ };
+
+ buffer-pool at 0 {
+ compatible = "fsl,p2041-bpool", "fsl,bpool";
+ fsl,bpid = <0>;
+ fsl,bpool-cfg = <0 0x100 0 1 0 0x100>;
+ };
+ };
+
+ qman-portals at ff4200000 {
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ compatible = "qman-portals";
+ ranges = <0x0 0xf 0xfdc00000 0x200000>;
+ qportal0: qman-portal at 0 {
+ cell-index = <0x0>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0x0 0x4000 0x100000 0x1000>;
+ interrupts = <104 0x2 0 0>;
+ fsl,qman-channel-id = <0x0>;
+ };
+
+ qportal1: qman-portal at 4000 {
+ cell-index = <0x1>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0x4000 0x4000 0x101000 0x1000>;
+ interrupts = <106 0x2 0 0>;
+ fsl,qman-channel-id = <0x1>;
+ };
+
+ qportal2: qman-portal at 8000 {
+ cell-index = <0x2>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0x8000 0x4000 0x102000 0x1000>;
+ interrupts = <108 0x2 0 0>;
+ fsl,qman-channel-id = <0x2>;
+ };
+
+ qportal3: qman-portal at c000 {
+ cell-index = <0x3>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0xc000 0x4000 0x103000 0x1000>;
+ interrupts = <110 0x2 0 0>;
+ fsl,qman-channel-id = <0x3>;
+ };
+
+ qportal4: qman-portal at 10000 {
+ cell-index = <0x4>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0x10000 0x4000 0x104000 0x1000>;
+ interrupts = <112 0x2 0 0>;
+ fsl,qman-channel-id = <0x4>;
+ };
+
+ qportal5: qman-portal at 14000 {
+ cell-index = <0x5>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0x14000 0x4000 0x105000 0x1000>;
+ interrupts = <114 0x2 0 0>;
+ fsl,qman-channel-id = <0x5>;
+ };
+
+ qportal6: qman-portal at 18000 {
+ cell-index = <0x6>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0x18000 0x4000 0x106000 0x1000>;
+ interrupts = <116 0x2 0 0>;
+ fsl,qman-channel-id = <0x6>;
+ };
+
+ qportal7: qman-portal at 1c000 {
+ cell-index = <0x7>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0x1c000 0x4000 0x107000 0x1000>;
+ interrupts = <118 0x2 0 0>;
+ fsl,qman-channel-id = <0x7>;
+ };
+
+ qportal8: qman-portal at 20000 {
+ cell-index = <0x8>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0x20000 0x4000 0x108000 0x1000>;
+ interrupts = <120 0x2 0 0>;
+ fsl,qman-channel-id = <0x8>;
+ };
+
+ qportal9: qman-portal at 24000 {
+ cell-index = <0x9>;
+ compatible = "fsl,p2041-qman-portal", "fsl,qman-portal";
+ reg = <0x24000 0x4000 0x109000 0x1000>;
+ interrupts = <122 0x2 0 0>;
+ fsl,qman-channel-id = <0x9>;
+ };
+
+ qpool1: qman-pool at 1 {
+ cell-index = <1>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x21>;
+ };
+
+ qpool2: qman-pool at 2 {
+ cell-index = <2>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x22>;
+ };
+
+ qpool3: qman-pool at 3 {
+ cell-index = <3>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x23>;
+ };
+
+ qpool4: qman-pool at 4 {
+ cell-index = <4>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x24>;
+ };
+
+ qpool5: qman-pool at 5 {
+ cell-index = <5>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x25>;
+ };
+
+ qpool6: qman-pool at 6 {
+ cell-index = <6>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x26>;
+ };
+
+ qpool7: qman-pool at 7 {
+ cell-index = <7>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x27>;
+ };
+
+ qpool8: qman-pool at 8 {
+ cell-index = <8>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x28>;
+ };
+
+ qpool9: qman-pool at 9 {
+ cell-index = <9>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x29>;
+ };
+
+ qpool10: qman-pool at 10 {
+ cell-index = <10>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2a>;
+ };
+
+ qpool11: qman-pool at 11 {
+ cell-index = <11>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2b>;
+ };
+
+ qpool12: qman-pool at 12 {
+ cell-index = <12>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2c>;
+ };
+
+ qpool13: qman-pool at 13 {
+ cell-index = <13>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2d>;
+ };
+
+ qpool14: qman-pool at 14 {
+ cell-index = <14>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2e>;
+ };
+
+ qpool15: qman-pool at 15 {
+ cell-index = <15>;
+ compatible = "fsl,p2041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2f>;
+ };
+ };
+
+ soc: soc at ffe000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "simple-bus";
+
+ bus-frequency = <0>; // Filled out by kernel.
+
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+
+ soc-sram-error {
+ compatible = "fsl,soc-sram-error";
+ interrupts = <16 2 1 29>;
+ };
+
+ corenet-law at 0 {
+ compatible = "fsl,corenet-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <32>;
+ };
+
+ ddr: memory-controller at 8000 {
+ compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
+ reg = <0x8000 0x1000>;
+ interrupts = <16 2 1 23>;
+ };
+
+ cpc: l3-cache-controller at 10000 {
+ compatible = "fsl,p2041-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache";
+ reg = <0x10000 0x1000>;
+ interrupts = <16 2 1 27>;
+ };
+
+ corenet-cf at 18000 {
+ compatible = "fsl,corenet-cf";
+ reg = <0x18000 0x1000>;
+ interrupts = <16 2 1 31>;
+ fsl,ccf-num-csdids = <32>;
+ fsl,ccf-num-snoopids = <32>;
+ };
+
+ iommu at 20000 {
+ compatible = "fsl,pamu-v1.0", "fsl,pamu";
+ reg = <0x20000 0x4000>;
+ interrupts = <
+ 24 2 0 0
+ 16 2 1 30>;
+ };
+
+ mpic: pic at 40000 {
+ clock-frequency = <0>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <4>;
+ reg = <0x40000 0x40000>;
+ compatible = "fsl,mpic", "chrp,open-pic";
+ device_type = "open-pic";
+ };
+
+ msi0: msi at 41600 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41600 0x200>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe0 0 0 0
+ 0xe1 0 0 0
+ 0xe2 0 0 0
+ 0xe3 0 0 0
+ 0xe4 0 0 0
+ 0xe5 0 0 0
+ 0xe6 0 0 0
+ 0xe7 0 0 0>;
+ };
+
+ msi1: msi at 41800 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41800 0x200>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe8 0 0 0
+ 0xe9 0 0 0
+ 0xea 0 0 0
+ 0xeb 0 0 0
+ 0xec 0 0 0
+ 0xed 0 0 0
+ 0xee 0 0 0
+ 0xef 0 0 0>;
+ };
+
+ msi2: msi at 41a00 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41a00 0x200>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xf0 0 0 0
+ 0xf1 0 0 0
+ 0xf2 0 0 0
+ 0xf3 0 0 0
+ 0xf4 0 0 0
+ 0xf5 0 0 0
+ 0xf6 0 0 0
+ 0xf7 0 0 0>;
+ };
+
+ guts: global-utilities at e0000 {
+ compatible = "fsl,qoriq-device-config-1.0";
+ reg = <0xe0000 0xe00>;
+ fsl,has-rstcr;
+ #sleep-cells = <1>;
+ fsl,liodn-bits = <12>;
+ };
+
+ pins: global-utilities at e0e00 {
+ compatible = "fsl,qoriq-pin-control-1.0";
+ reg = <0xe0e00 0x200>;
+ #sleep-cells = <2>;
+ };
+
+ clockgen: global-utilities at e1000 {
+ compatible = "fsl,p2041-clockgen", "fsl,qoriq-clockgen-1.0";
+ reg = <0xe1000 0x1000>;
+ clock-frequency = <0>;
+ };
+
+ rcpm: global-utilities at e2000 {
+ compatible = "fsl,qoriq-rcpm-1.0";
+ reg = <0xe2000 0x1000>;
+ #sleep-cells = <1>;
+ };
+
+ sfp: sfp at e8000 {
+ compatible = "fsl,p2041-sfp", "fsl,qoriq-sfp-1.0";
+ reg = <0xe8000 0x1000>;
+ };
+
+ serdes: serdes at ea000 {
+ compatible = "fsl,p2041-serdes";
+ reg = <0xea000 0x1000>;
+ };
+
+ dma0: dma at 100300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p2041-dma", "fsl,eloplus-dma";
+ reg = <0x100300 0x4>;
+ ranges = <0x0 0x100100 0x200>;
+ cell-index = <0>;
+ dma-channel at 0 {
+ compatible = "fsl,p2041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupts = <28 2 0 0>;
+ };
+ dma-channel at 80 {
+ compatible = "fsl,p2041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupts = <29 2 0 0>;
+ };
+ dma-channel at 100 {
+ compatible = "fsl,p2041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupts = <30 2 0 0>;
+ };
+ dma-channel at 180 {
+ compatible = "fsl,p2041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupts = <31 2 0 0>;
+ };
+ };
+
+ dma1: dma at 101300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p2041-dma", "fsl,eloplus-dma";
+ reg = <0x101300 0x4>;
+ ranges = <0x0 0x101100 0x200>;
+ cell-index = <1>;
+ dma-channel at 0 {
+ compatible = "fsl,p2041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupts = <32 2 0 0>;
+ };
+ dma-channel at 80 {
+ compatible = "fsl,p2041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupts = <33 2 0 0>;
+ };
+ dma-channel at 100 {
+ compatible = "fsl,p2041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupts = <34 2 0 0>;
+ };
+ dma-channel at 180 {
+ compatible = "fsl,p2041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupts = <35 2 0 0>;
+ };
+ };
+
+ spi at 110000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,p2041-espi", "fsl,mpc8536-espi";
+ reg = <0x110000 0x1000>;
+ interrupts = <53 0x2 0 0>;
+ fsl,espi-num-chipselects = <4>;
+ };
+
+ sdhc: sdhc at 114000 {
+ compatible = "fsl,p2041-esdhc", "fsl,esdhc";
+ reg = <0x114000 0x1000>;
+ interrupts = <48 2 0 0>;
+ sdhci,auto-cmd12;
+ clock-frequency = <0>;
+ };
+
+ i2c at 118000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x118000 0x100>;
+ interrupts = <38 2 0 0>;
+ dfsrr;
+ };
+
+ i2c at 118100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ compatible = "fsl-i2c";
+ reg = <0x118100 0x100>;
+ interrupts = <38 2 0 0>;
+ dfsrr;
+ };
+
+ i2c at 119000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <2>;
+ compatible = "fsl-i2c";
+ reg = <0x119000 0x100>;
+ interrupts = <39 2 0 0>;
+ dfsrr;
+ };
+
+ i2c at 119100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <3>;
+ compatible = "fsl-i2c";
+ reg = <0x119100 0x100>;
+ interrupts = <39 2 0 0>;
+ dfsrr;
+ };
+
+ serial0: serial at 11c500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11c500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <36 2 0 0>;
+ };
+
+ serial1: serial at 11c600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11c600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <36 2 0 0>;
+ };
+
+ serial2: serial at 11d500 {
+ cell-index = <2>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11d500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <37 2 0 0>;
+ };
+
+ serial3: serial at 11d600 {
+ cell-index = <3>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11d600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <37 2 0 0>;
+ };
+
+ gpio0: gpio at 130000 {
+ compatible = "fsl,p2041-gpio", "fsl,qoriq-gpio";
+ reg = <0x130000 0x1000>;
+ interrupts = <55 2 0 0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ };
+
+ rman: rman at 1e0000 {
+ compatible = "fsl,rman";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x1e0000 0x20000>;
+ reg = <0x1e0000 0x20000>;
+ interrupts = <16 2 1 11>; /* err_irq */
+ fsl,qman-channels-id = <0x62 0x63>;
+
+ inbound-block at 0 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x0 0x800>;
+ };
+ global-cfg at b00 {
+ compatible = "fsl,rman-global-cfg";
+ reg = <0xb00 0x500>;
+ };
+ inbound-block at 1000 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x1000 0x800>;
+ };
+ inbound-block at 2000 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x2000 0x800>;
+ };
+ inbound-block at 3000 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x3000 0x800>;
+ };
+ };
+
+ usb0: usb at 210000 {
+ compatible = "fsl,p2041-usb2-mph",
+ "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph";
+ reg = <0x210000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <44 0x2 0 0>;
+ phy_type = "utmi";
+ port0;
+ };
+
+ usb1: usb at 211000 {
+ compatible = "fsl,p2041-usb2-dr",
+ "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr";
+ reg = <0x211000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <45 0x2 0 0>;
+ phy_type = "utmi";
+ };
+
+ sata at 220000 {
+ compatible = "fsl,p2041-sata", "fsl,pq-sata-v2";
+ reg = <0x220000 0x1000>;
+ interrupts = <68 0x2 0 0>;
+ };
+
+ sata at 221000 {
+ compatible = "fsl,p2041-sata", "fsl,pq-sata-v2";
+ reg = <0x221000 0x1000>;
+ interrupts = <69 0x2 0 0>;
+ };
+
+ crypto: crypto at 300000 {
+ compatible = "fsl,sec-v4.2", "fsl,sec-v4.0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x300000 0x10000>;
+ ranges = <0 0x300000 0x10000>;
+ interrupts = <92 2 0 0>;
+
+ sec_jr0: jr at 1000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x1000 0x1000>;
+ interrupts = <88 2 0 0>;
+ };
+
+ sec_jr1: jr at 2000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x2000 0x1000>;
+ interrupts = <89 2 0 0>;
+ };
+
+ sec_jr2: jr at 3000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x3000 0x1000>;
+ interrupts = <90 2 0 0>;
+ };
+
+ sec_jr3: jr at 4000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x4000 0x1000>;
+ interrupts = <91 2 0 0>;
+ };
+
+ rtic at 6000 {
+ compatible = "fsl,sec-v4.2-rtic",
+ "fsl,sec-v4.0-rtic";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x6000 0x100>;
+ ranges = <0x0 0x6100 0xe00>;
+
+ rtic_a: rtic-a at 0 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x00 0x20 0x100 0x80>;
+ };
+
+ rtic_b: rtic-b at 20 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x20 0x20 0x200 0x80>;
+ };
+
+ rtic_c: rtic-c at 40 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x40 0x20 0x300 0x80>;
+ };
+
+ rtic_d: rtic-d at 60 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x60 0x20 0x500 0x80>;
+ };
+ };
+ };
+
+ sec_mon: sec_mon at 314000 {
+ compatible = "fsl,sec-v4.2-mon", "fsl,sec-v4.0-mon";
+ reg = <0x314000 0x1000>;
+ interrupts = <93 2 0 0>;
+ };
+
+ pme: pme at 316000 {
+ compatible = "fsl,pme";
+ reg = <0x316000 0x10000>;
+ /* fsl,pme-pdsr = <0x0 0x23000000 0x0 0x01000000>; */
+ /* fsl,pme-sre = <0x0 0x24000000 0x0 0x00a00000>; */
+ interrupts = <16 2 1 5>;
+ };
+
+ qman: qman at 318000 {
+ compatible = "fsl,p2041-qman", "fsl,qman";
+ reg = <0x318000 0x1000>;
+ interrupts = <16 2 1 3>;
+ /* Commented out, use default allocation */
+ /* fsl,qman-fqd = <0x0 0x20000000 0x0 0x01000000>; */
+ /* fsl,qman-pfdr = <0x0 0x21000000 0x0 0x01000000>; */
+ };
+
+ bman: bman at 31a000 {
+ compatible = "fsl,p2041-bman", "fsl,bman";
+ reg = <0x31a000 0x1000>;
+ interrupts = <16 2 1 2>;
+ /* Same as fsl,qman-*, use default allocation */
+ /* fsl,bman-fbpr = <0x0 0x22000000 0x0 0x01000000>; */
+ };
+
+ fman0: fman at 400000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ compatible = "fsl,p2041-fman", "fsl,fman", "simple-bus";
+ ranges = <0 0x400000 0x100000>;
+ reg = <0x400000 0x100000>;
+ clock-frequency = <0>;
+ interrupts = <
+ 96 2 0 0
+ 16 2 1 1>;
+
+ cc at 0 {
+ compatible = "fsl,p2041-fman-cc", "fsl,fman-cc";
+ };
+
+ parser at c7000 {
+ compatible = "fsl,p2041-fman-parser", "fsl,fman-parser";
+ reg = <0xc7000 0x1000>;
+ };
+
+ keygen at c1000 {
+ compatible = "fsl,p2041-fman-keygen", "fsl,fman-keygen";
+ reg = <0xc1000 0x1000>;
+ };
+
+ policer at c0000 {
+ compatible = "fsl,p2041-fman-policer", "fsl,fman-policer";
+ reg = <0xc0000 0x1000>;
+ };
+
+ muram at 0 {
+ compatible = "fsl,p2041-fman-muram", "fsl,fman-muram";
+ reg = <0x0 0x28000>;
+ };
+
+ bmi at 80000 {
+ compatible = "fsl,p2041-fman-bmi", "fsl,fman-bmi";
+ reg = <0x80000 0x400>;
+ };
+
+ qmi at 80400 {
+ compatible = "fsl,p2041-fman-qmi", "fsl,fman-qmi";
+ reg = <0x80400 0x400>;
+ };
+
+ fman0_rx0: port at 88000 {
+ cell-index = <0>;
+ compatible = "fsl,p2041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x88000 0x1000>;
+ };
+ fman0_rx1: port at 89000 {
+ cell-index = <1>;
+ compatible = "fsl,p2041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x89000 0x1000>;
+ };
+ fman0_rx2: port at 8a000 {
+ cell-index = <2>;
+ compatible = "fsl,p2041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x8a000 0x1000>;
+ };
+ fman0_rx3: port at 8b000 {
+ cell-index = <3>;
+ compatible = "fsl,p2041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x8b000 0x1000>;
+ };
+ fman0_rx4: port at 8c000 {
+ cell-index = <4>;
+ compatible = "fsl,p2041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x8c000 0x1000>;
+ };
+ fman0_rx5: port at 90000 {
+ cell-index = <0>;
+ compatible = "fsl,p2041-fman-port-10g-rx", "fsl,fman-port-10g-rx";
+ reg = <0x90000 0x1000>;
+ };
+
+ fman0_tx5: port at b0000 {
+ cell-index = <0>;
+ compatible = "fsl,p2041-fman-port-10g-tx", "fsl,fman-port-10g-tx";
+ reg = <0xb0000 0x1000>;
+ fsl,qman-channel-id = <0x40>;
+ };
+ fman0_tx0: port at a8000 {
+ cell-index = <0>;
+ compatible = "fsl,p2041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xa8000 0x1000>;
+ fsl,qman-channel-id = <0x41>;
+ };
+ fman0_tx1: port at a9000 {
+ cell-index = <1>;
+ compatible = "fsl,p2041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xa9000 0x1000>;
+ fsl,qman-channel-id = <0x42>;
+ };
+ fman0_tx2: port at aa000 {
+ cell-index = <2>;
+ compatible = "fsl,p2041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xaa000 0x1000>;
+ fsl,qman-channel-id = <0x43>;
+ };
+ fman0_tx3: port at ab000 {
+ cell-index = <3>;
+ compatible = "fsl,p2041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xab000 0x1000>;
+ fsl,qman-channel-id = <0x44>;
+ };
+ fman0_tx4: port at ac000 {
+ cell-index = <4>;
+ compatible = "fsl,p2041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xac000 0x1000>;
+ fsl,qman-channel-id = <0x45>;
+ };
+
+ fman0_oh0: port at 81000 {
+ cell-index = <0>;
+ compatible = "fsl,p2041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x81000 0x1000>;
+ fsl,qman-channel-id = <0x46>;
+ };
+ fman0_oh1: port at 82000 {
+ cell-index = <1>;
+ compatible = "fsl,p2041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x82000 0x1000>;
+ fsl,qman-channel-id = <0x47>;
+ };
+ fman0_oh2: port at 83000 {
+ cell-index = <2>;
+ compatible = "fsl,p2041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x83000 0x1000>;
+ fsl,qman-channel-id = <0x48>;
+ };
+ fman0_oh3: port at 84000 {
+ cell-index = <3>;
+ compatible = "fsl,p2041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x84000 0x1000>;
+ fsl,qman-channel-id = <0x49>;
+ };
+ fman0_oh4: port at 85000 {
+ cell-index = <4>;
+ compatible = "fsl,p2041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x85000 0x1000>;
+ fsl,qman-channel-id = <0x4a>;
+ };
+ fman0_oh5: port at 86000 {
+ cell-index = <5>;
+ compatible = "fsl,p2041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x86000 0x1000>;
+ fsl,qman-channel-id = <0x4b>;
+ };
+ fman0_oh6: port at 87000 {
+ cell-index = <6>;
+ compatible = "fsl,p2041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x87000 0x1000>;
+ };
+
+ enet0: ethernet at e0000 {
+ cell-index = <0>;
+ compatible = "fsl,p2041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe0000 0x1000>;
+ fsl,port-handles = <&fman0_rx0 &fman0_tx0>;
+ };
+
+ mdio0: mdio at e1120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-mdio";
+ reg = <0xe1120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet1: ethernet at e2000 {
+ cell-index = <1>;
+ compatible = "fsl,p2041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe2000 0x1000>;
+ fsl,port-handles = <&fman0_rx1 &fman0_tx1>;
+ };
+
+ mdio at e3120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe3120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet2: ethernet at e4000 {
+ cell-index = <2>;
+ compatible = "fsl,p2041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe4000 0x1000>;
+ fsl,port-handles = <&fman0_rx2 &fman0_tx2>;
+ };
+
+ mdio at e5120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe5120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet3: ethernet at e6000 {
+ cell-index = <3>;
+ compatible = "fsl,p2041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe6000 0x1000>;
+ fsl,port-handles = <&fman0_rx3 &fman0_tx3>;
+ };
+
+ mdio at e7120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe7120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet4: ethernet at e8000 {
+ cell-index = <4>;
+ compatible = "fsl,p2041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe8000 0x1000>;
+ fsl,port-handles = <&fman0_rx4 &fman0_tx4>;
+ };
+
+ mdio at e9120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe9120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet5: ethernet at f0000 {
+ cell-index = <0>;
+ compatible = "fsl,p2041-fman-10g-mac", "fsl,fman-10g-mac";
+ reg = <0xf0000 0x1000>;
+ fsl,port-handles = <&fman0_rx5 &fman0_tx5>;
+ };
+
+ mdio at f1000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-xmdio";
+ reg = <0xf1000 0x1000>;
+ interrupts = <100 1 0 0>;
+ };
+ };
+ };
+
+ rapidio at ffe0c0000 {
+ compatible = "fsl,srio";
+ interrupts = <16 2 1 11>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ port1 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ cell-index = <1>;
+ };
+
+ port2 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ cell-index = <2>;
+ };
+ };
+
+ localbus at ffe124000 {
+ compatible = "fsl,p2041-elbc", "fsl,elbc", "simple-bus";
+ interrupts = <25 2 0 0>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ };
+
+ pci0: pcie at ffe200000 {
+ compatible = "fsl,p2041-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "disabled";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <33333333>;
+ fsl,msi = <&msi0>;
+ interrupts = <16 2 1 15>;
+ pcie at 0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 15>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 40 1 0 0
+ 0000 0 0 2 &mpic 1 1 0 0
+ 0000 0 0 3 &mpic 2 1 0 0
+ 0000 0 0 4 &mpic 3 1 0 0
+ >;
+ };
+ };
+
+ pci1: pcie at ffe201000 {
+ compatible = "fsl,p2041-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "okay";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0 0xff>;
+ clock-frequency = <33333333>;
+ fsl,msi = <&msi1>;
+ interrupts = <16 2 1 14>;
+ pcie at 0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 14>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 41 1 0 0
+ 0000 0 0 2 &mpic 5 1 0 0
+ 0000 0 0 3 &mpic 6 1 0 0
+ 0000 0 0 4 &mpic 7 1 0 0
+ >;
+ };
+ };
+
+ pci2: pcie at ffe202000 {
+ compatible = "fsl,p2041-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "disabled";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <33333333>;
+ fsl,msi = <&msi2>;
+ interrupts = <16 2 1 13>;
+ pcie at 0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 13>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 42 1 0 0
+ 0000 0 0 2 &mpic 9 1 0 0
+ 0000 0 0 3 &mpic 10 1 0 0
+ 0000 0 0 4 &mpic 11 1 0 0
+ >;
+ };
+ };
+};
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/fdt/dts/p3041ds.dts
--- a/head/sys/boot/fdt/dts/p3041ds.dts Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/fdt/dts/p3041ds.dts Wed Jul 25 16:45:04 2012 +0300
@@ -31,9 +31,9 @@
* (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: head/sys/boot/fdt/dts/p3041ds.dts 227506 2011-11-14 18:51:39Z marcel $ */
+/* $FreeBSD: head/sys/boot/fdt/dts/p3041ds.dts 236024 2012-05-25 20:43:38Z raj $ */
-/dts-v1/;
+/include/ "p3041si.dtsi"
/ {
model = "fsl,P3041DS";
@@ -43,305 +43,155 @@
interrupt-parent = <&mpic>;
aliases {
- ccsr = &soc;
-
- serial0 = &serial0;
- serial1 = &serial1;
- serial2 = &serial2;
- serial3 = &serial3;
- pci0 = &pci0;
- pci1 = &pci1;
- pci2 = &pci2;
- pci3 = &pci3;
- usb0 = &usb0;
- usb1 = &usb1;
- dma0 = &dma0;
- dma1 = &dma1;
- sdhc = &sdhc;
- msi0 = &msi0;
- msi1 = &msi1;
- msi2 = &msi2;
-
- crypto = &crypto;
- sec_jr0 = &sec_jr0;
- sec_jr1 = &sec_jr1;
- sec_jr2 = &sec_jr2;
- sec_jr3 = &sec_jr3;
- rtic_a = &rtic_a;
- rtic_b = &rtic_b;
- rtic_c = &rtic_c;
- rtic_d = &rtic_d;
- sec_mon = &sec_mon;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu0: PowerPC,e500mc at 0 {
- device_type = "cpu";
- reg = <0>;
- next-level-cache = <&L2_0>;
- L2_0: l2-cache {
- next-level-cache = <&cpc>;
- };
- };
- cpu1: PowerPC,e500mc at 1 {
- device_type = "cpu";
- reg = <1>;
- next-level-cache = <&L2_1>;
- L2_1: l2-cache {
- next-level-cache = <&cpc>;
- };
- };
- cpu2: PowerPC,e500mc at 2 {
- device_type = "cpu";
- reg = <2>;
- next-level-cache = <&L2_2>;
- L2_2: l2-cache {
- next-level-cache = <&cpc>;
- };
- };
- cpu3: PowerPC,e500mc at 3 {
- device_type = "cpu";
- reg = <3>;
- next-level-cache = <&L2_3>;
- L2_3: l2-cache {
- next-level-cache = <&cpc>;
- };
- };
+ phy_rgmii_0 = &phy_rgmii_0;
+ phy_rgmii_1 = &phy_rgmii_1;
+ phy_sgmii_1c = &phy_sgmii_1c;
+ phy_sgmii_1d = &phy_sgmii_1d;
+ phy_sgmii_1e = &phy_sgmii_1e;
+ phy_sgmii_1f = &phy_sgmii_1f;
+ phy_xgmii_1 = &phy_xgmii_1;
+ phy_xgmii_2 = &phy_xgmii_2;
+ emi1_rgmii = &hydra_mdio_rgmii;
+ emi1_sgmii = &hydra_mdio_sgmii;
+ emi2_xgmii = &hydra_mdio_xgmii;
};
memory {
device_type = "memory";
+ reg = <0x00000000 0x00000000 0x00000000 0x80000000>;
+ };
+
+ dcsr: dcsr at f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+ };
+
+ bman-portals at ff4000000 {
+ bman-portal at 0 {
+ cpu-handle = <&cpu0>;
+ };
+ bman-portal at 4000 {
+ cpu-handle = <&cpu1>;
+ };
+ bman-portal at 8000 {
+ cpu-handle = <&cpu2>;
+ };
+ bman-portal at c000 {
+ cpu-handle = <&cpu3>;
+ };
+ bman-portal at 10000 {
+ };
+ bman-portal at 14000 {
+ };
+ bman-portal at 18000 {
+ };
+ bman-portal at 1c000 {
+ };
+ bman-portal at 20000 {
+ };
+ bman-portal at 24000 {
+ };
+
+ buffer-pool at 0 {
+ compatible = "fsl,p3041-bpool", "fsl,bpool";
+ fsl,bpid = <0>;
+ fsl,bpool-cfg = <0 0x100 0 1 0 0x100>;
+ };
+ };
+
+ qman-portals at ff4200000 {
+ qportal0: qman-portal at 0 {
+ cpu-handle = <&cpu0>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal1: qman-portal at 4000 {
+ cpu-handle = <&cpu1>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal2: qman-portal at 8000 {
+ cpu-handle = <&cpu2>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal3: qman-portal at c000 {
+ cpu-handle = <&cpu3>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal4: qman-portal at 10000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal5: qman-portal at 14000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal6: qman-portal at 18000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal7: qman-portal at 1c000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal8: qman-portal at 20000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal9: qman-portal at 24000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
};
soc: soc at ffe000000 {
- #address-cells = <1>;
- #size-cells = <1>;
- device_type = "soc";
- compatible = "simple-bus";
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
-
- soc-sram-error {
- compatible = "fsl,soc-sram-error";
- interrupts = <16 2 1 29>;
- };
-
- corenet-law at 0 {
- compatible = "fsl,corenet-law";
- reg = <0x0 0x1000>;
- fsl,num-laws = <32>;
- };
-
- memory-controller at 8000 {
- compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
- reg = <0x8000 0x1000>;
- interrupts = <16 2 1 23>;
- };
-
- cpc: l3-cache-controller at 10000 {
- compatible = "fsl,p3041-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache";
- reg = <0x10000 0x1000>;
- interrupts = <16 2 1 27>;
- };
-
- corenet-cf at 18000 {
- compatible = "fsl,corenet-cf";
- reg = <0x18000 0x1000>;
- interrupts = <16 2 1 31>;
- fsl,ccf-num-csdids = <32>;
- fsl,ccf-num-snoopids = <32>;
- };
-
- iommu at 20000 {
- compatible = "fsl,pamu-v1.0", "fsl,pamu";
- reg = <0x20000 0x4000>;
- interrupts = <
- 24 2 0 0
- 16 2 1 30>;
- };
-
- mpic: pic at 40000 {
- clock-frequency = <0>;
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <4>;
- reg = <0x40000 0x40000>;
- compatible = "fsl,mpic", "chrp,open-pic";
- device_type = "open-pic";
- };
-
- msi0: msi at 41600 {
- compatible = "fsl,mpic-msi";
- reg = <0x41600 0x200>;
- msi-available-ranges = <0 0x100>;
- interrupts = <
- 0xe0 0 0 0
- 0xe1 0 0 0
- 0xe2 0 0 0
- 0xe3 0 0 0
- 0xe4 0 0 0
- 0xe5 0 0 0
- 0xe6 0 0 0
- 0xe7 0 0 0>;
- };
-
- msi1: msi at 41800 {
- compatible = "fsl,mpic-msi";
- reg = <0x41800 0x200>;
- msi-available-ranges = <0 0x100>;
- interrupts = <
- 0xe8 0 0 0
- 0xe9 0 0 0
- 0xea 0 0 0
- 0xeb 0 0 0
- 0xec 0 0 0
- 0xed 0 0 0
- 0xee 0 0 0
- 0xef 0 0 0>;
- };
-
- msi2: msi at 41a00 {
- compatible = "fsl,mpic-msi";
- reg = <0x41a00 0x200>;
- msi-available-ranges = <0 0x100>;
- interrupts = <
- 0xf0 0 0 0
- 0xf1 0 0 0
- 0xf2 0 0 0
- 0xf3 0 0 0
- 0xf4 0 0 0
- 0xf5 0 0 0
- 0xf6 0 0 0
- 0xf7 0 0 0>;
- };
-
- guts: global-utilities at e0000 {
- compatible = "fsl,qoriq-device-config-1.0";
- reg = <0xe0000 0xe00>;
- fsl,has-rstcr;
- #sleep-cells = <1>;
- fsl,liodn-bits = <12>;
- };
-
- pins: global-utilities at e0e00 {
- compatible = "fsl,qoriq-pin-control-1.0";
- reg = <0xe0e00 0x200>;
- #sleep-cells = <2>;
- };
-
- clockgen: global-utilities at e1000 {
- compatible = "fsl,p3041-clockgen", "fsl,qoriq-clockgen-1.0";
- reg = <0xe1000 0x1000>;
- clock-frequency = <0>;
- };
-
- rcpm: global-utilities at e2000 {
- compatible = "fsl,qoriq-rcpm-1.0";
- reg = <0xe2000 0x1000>;
- #sleep-cells = <1>;
- };
-
- sfp: sfp at e8000 {
- compatible = "fsl,p3041-sfp", "fsl,qoriq-sfp-1.0";
- reg = <0xe8000 0x1000>;
- };
-
- serdes: serdes at ea000 {
- compatible = "fsl,p3041-serdes";
- reg = <0xea000 0x1000>;
- };
-
- dma0: dma at 100300 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,p3041-dma", "fsl,eloplus-dma";
- reg = <0x100300 0x4>;
- ranges = <0x0 0x100100 0x200>;
- cell-index = <0>;
- dma-channel at 0 {
- compatible = "fsl,p3041-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x0 0x80>;
- cell-index = <0>;
- interrupts = <28 2 0 0>;
- };
- dma-channel at 80 {
- compatible = "fsl,p3041-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x80 0x80>;
- cell-index = <1>;
- interrupts = <29 2 0 0>;
- };
- dma-channel at 100 {
- compatible = "fsl,p3041-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x100 0x80>;
- cell-index = <2>;
- interrupts = <30 2 0 0>;
- };
- dma-channel at 180 {
- compatible = "fsl,p3041-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x180 0x80>;
- cell-index = <3>;
- interrupts = <31 2 0 0>;
- };
- };
-
- dma1: dma at 101300 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,p3041-dma", "fsl,eloplus-dma";
- reg = <0x101300 0x4>;
- ranges = <0x0 0x101100 0x200>;
- cell-index = <1>;
- dma-channel at 0 {
- compatible = "fsl,p3041-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x0 0x80>;
- cell-index = <0>;
- interrupts = <32 2 0 0>;
- };
- dma-channel at 80 {
- compatible = "fsl,p3041-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x80 0x80>;
- cell-index = <1>;
- interrupts = <33 2 0 0>;
- };
- dma-channel at 100 {
- compatible = "fsl,p3041-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x100 0x80>;
- cell-index = <2>;
- interrupts = <34 2 0 0>;
- };
- dma-channel at 180 {
- compatible = "fsl,p3041-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x180 0x80>;
- cell-index = <3>;
- interrupts = <35 2 0 0>;
- };
- };
-
spi at 110000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,p3041-espi", "fsl,mpc8536-espi";
- reg = <0x110000 0x1000>;
- interrupts = <53 0x2 0 0>;
- fsl,espi-num-chipselects = <4>;
-
flash at 0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "spansion,s25sl12801";
reg = <0>;
- spi-max-frequency = <40000000>; /* input clock */
+ spi-max-frequency = <35000000>; /* input clock */
partition at u-boot {
label = "u-boot";
reg = <0x00000000 0x00100000>;
@@ -364,32 +214,7 @@
};
};
- sdhc: sdhc at 114000 {
- compatible = "fsl,p3041-esdhc", "fsl,esdhc";
- reg = <0x114000 0x1000>;
- interrupts = <48 2 0 0>;
- sdhci,auto-cmd12;
- clock-frequency = <0>;
- };
-
- i2c at 118000 {
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- compatible = "fsl-i2c";
- reg = <0x118000 0x100>;
- interrupts = <38 2 0 0>;
- dfsrr;
- };
-
i2c at 118100 {
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <1>;
- compatible = "fsl-i2c";
- reg = <0x118100 0x100>;
- interrupts = <38 2 0 0>;
- dfsrr;
eeprom at 51 {
compatible = "at24,24c256";
reg = <0x51>;
@@ -400,24 +225,7 @@
};
};
- i2c at 119000 {
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <2>;
- compatible = "fsl-i2c";
- reg = <0x119000 0x100>;
- interrupts = <39 2 0 0>;
- dfsrr;
- };
-
i2c at 119100 {
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <3>;
- compatible = "fsl-i2c";
- reg = <0x119100 0x100>;
- interrupts = <39 2 0 0>;
- dfsrr;
rtc at 68 {
compatible = "dallas,ds3232";
reg = <0x68>;
@@ -425,329 +233,355 @@
};
};
- serial0: serial at 11c500 {
- cell-index = <0>;
- device_type = "serial";
- compatible = "ns16550";
- reg = <0x11c500 0x100>;
- clock-frequency = <0>;
- interrupts = <36 2 0 0>;
+ pme: pme at 316000 {
+ /* Commented out, use default allocation */
+ /* fsl,pme-pdsr = <0x0 0x23000000 0x0 0x01000000>; */
+ /* fsl,pme-sre = <0x0 0x24000000 0x0 0x00a00000>; */
};
- serial1: serial at 11c600 {
- cell-index = <1>;
- device_type = "serial";
- compatible = "ns16550";
- reg = <0x11c600 0x100>;
- clock-frequency = <0>;
- interrupts = <36 2 0 0>;
+ qman: qman at 318000 {
+ /* Commented out, use default allocation */
+ /* fsl,qman-fqd = <0x0 0x20000000 0x0 0x01000000>; */
+ /* fsl,qman-pfdr = <0x0 0x21000000 0x0 0x01000000>; */
};
- serial2: serial at 11d500 {
- cell-index = <2>;
- device_type = "serial";
- compatible = "ns16550";
- reg = <0x11d500 0x100>;
- clock-frequency = <0>;
- interrupts = <37 2 0 0>;
+ bman: bman at 31a000 {
+ /* Same as fsl,qman-*, use default allocation */
+ /* fsl,bman-fbpr = <0x0 0x22000000 0x0 0x01000000>; */
};
- serial3: serial at 11d600 {
- cell-index = <3>;
- device_type = "serial";
- compatible = "ns16550";
- reg = <0x11d600 0x100>;
- clock-frequency = <0>;
- interrupts = <37 2 0 0>;
- };
-
- gpio0: gpio at 130000 {
- compatible = "fsl,p3041-gpio", "fsl,qoriq-gpio";
- reg = <0x130000 0x1000>;
- interrupts = <55 2 0 0>;
- #gpio-cells = <2>;
- gpio-controller;
- };
-
- usb0: usb at 210000 {
- compatible = "fsl,p3041-usb2-mph",
- "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph";
- reg = <0x210000 0x1000>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <44 0x2 0 0>;
- phy_type = "utmi";
- port0;
- };
-
- usb1: usb at 211000 {
- compatible = "fsl,p3041-usb2-dr",
- "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr";
- reg = <0x211000 0x1000>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <45 0x2 0 0>;
- dr_mode = "host";
- phy_type = "utmi";
- };
-
- sata at 220000 {
- compatible = "fsl,p3041-sata", "fsl,pq-sata-v2";
- reg = <0x220000 0x1000>;
- interrupts = <68 0x2 0 0>;
- };
-
- sata at 221000 {
- compatible = "fsl,p3041-sata", "fsl,pq-sata-v2";
- reg = <0x221000 0x1000>;
- interrupts = <69 0x2 0 0>;
- };
-
- crypto: crypto at 300000 {
- compatible = "fsl,sec-v4.2", "fsl,sec-v4.0";
- #address-cells = <1>;
- #size-cells = <1>;
- reg = <0x300000 0x10000>;
- ranges = <0 0x300000 0x10000>;
- interrupts = <92 2 0 0>;
-
- sec_jr0: jr at 1000 {
- compatible = "fsl,sec-v4.2-job-ring",
- "fsl,sec-v4.0-job-ring";
- reg = <0x1000 0x1000>;
- interrupts = <88 2 0 0>;
+ fman0: fman at 400000 {
+ enet0: ethernet at e0000 {
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy_rgmii_0>;
+ phy-connection-type = "rgmii";
};
- sec_jr1: jr at 2000 {
- compatible = "fsl,sec-v4.2-job-ring",
- "fsl,sec-v4.0-job-ring";
- reg = <0x2000 0x1000>;
- interrupts = <89 2 0 0>;
+ mdio0: mdio at e1120 {
+ tbi0: tbi-phy at 8 {
+ reg = <0x8>;
+ device_type = "tbi-phy";
+ };
+
+ /*
+ * Virtual MDIO for the two on-board RGMII
+ * ports. The fsl,hydra-mdio-muxval property
+ * is already correct.
+ */
+ hydra_mdio_rgmii: hydra-mdio-rgmii {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,hydra-mdio";
+ fsl,mdio-handle = <&mdio0>;
+ fsl,hydra-mdio-muxval = <0x00>;
+ status = "disabled";
+
+ phy_rgmii_0: ethernet-phy at 0 {
+ reg = <0x0>;
+ };
+ phy_rgmii_1: ethernet-phy at 1 {
+ reg = <0x1>;
+ };
+ };
+
+ /*
+ * Virtual MDIO for the four-port SGMII card.
+ * The fsl,hydra-mdio-muxval property will be
+ * fixed-up by U-Boot based on the slot that
+ * the SGMII card is in.
+ *
+ * Note: we do not support DTSEC5 connected to
+ * SGMII, so this is the only SGMII node.
+ */
+ hydra_mdio_sgmii: hydra-mdio-sgmii {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,hydra-mdio";
+ fsl,mdio-handle = <&mdio0>;
+ fsl,hydra-mdio-muxval = <0x00>;
+ status = "disabled";
+
+ phy_sgmii_1c: ethernet-phy at 1c {
+ reg = <0x1c>;
+ };
+ phy_sgmii_1d: ethernet-phy at 1d {
+ reg = <0x1d>;
+ };
+ phy_sgmii_1e: ethernet-phy at 1e {
+ reg = <0x1e>;
+ };
+ phy_sgmii_1f: ethernet-phy at 1f {
+ reg = <0x1f>;
+ };
+ };
};
- sec_jr2: jr at 3000 {
- compatible = "fsl,sec-v4.2-job-ring",
- "fsl,sec-v4.0-job-ring";
- reg = <0x3000 0x1000>;
- interrupts = <90 2 0 0>;
+ enet1: ethernet at e2000 {
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy_sgmii_1d>;
+ phy-connection-type = "sgmii";
};
- sec_jr3: jr at 4000 {
- compatible = "fsl,sec-v4.2-job-ring",
- "fsl,sec-v4.0-job-ring";
- reg = <0x4000 0x1000>;
- interrupts = <91 2 0 0>;
+ mdio at e3120 {
+ tbi1: tbi-phy at 8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
};
- rtic at 6000 {
- compatible = "fsl,sec-v4.2-rtic",
- "fsl,sec-v4.0-rtic";
+ enet2: ethernet at e4000 {
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy_sgmii_1e>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio at e5120 {
+ tbi2: tbi-phy at 8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet3: ethernet at e6000 {
+ tbi-handle = <&tbi3>;
+ phy-handle = <&phy_sgmii_1f>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio at e7120 {
#address-cells = <1>;
- #size-cells = <1>;
- reg = <0x6000 0x100>;
- ranges = <0x0 0x6100 0xe00>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe7120 0xee0>;
+ interrupts = <100 1 0 0>;
- rtic_a: rtic-a at 0 {
- compatible = "fsl,sec-v4.2-rtic-memory",
- "fsl,sec-v4.0-rtic-memory";
- reg = <0x00 0x20 0x100 0x80>;
+ tbi3: tbi-phy at 8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet4: ethernet at e8000 {
+ tbi-handle = <&tbi4>;
+ phy-handle = <&phy_rgmii_1>;
+ phy-connection-type = "rgmii";
+ };
+
+ mdio at e9120 {
+ tbi4: tbi-phy at 8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet5: ethernet at f0000 {
+ /*
+ * phy-handle will be updated by U-Boot to
+ * reflect the actual slot the XAUI card is in.
+ */
+ phy-handle = <&phy_xgmii_1>;
+ phy-connection-type = "xgmii";
+ };
+
+ /*
+ * We only support one XAUI card, so the MDIO muxing
+ * is set by U-Boot, and Linux never touches it.
+ * Therefore, we don't need a virtual MDIO node.
+ * However, the phy address depends on the slot, so
+ * only one of the ethernet-phy nodes below will be
+ * used.
+ */
+ hydra_mdio_xgmii: mdio at f1000 {
+ status = "disabled";
+
+ /* XAUI card in slot 1 */
+ phy_xgmii_1: ethernet-phy at 4 {
+ reg = <0x4>;
};
- rtic_b: rtic-b at 20 {
- compatible = "fsl,sec-v4.2-rtic-memory",
- "fsl,sec-v4.0-rtic-memory";
- reg = <0x20 0x20 0x200 0x80>;
- };
-
- rtic_c: rtic-c at 40 {
- compatible = "fsl,sec-v4.2-rtic-memory",
- "fsl,sec-v4.0-rtic-memory";
- reg = <0x40 0x20 0x300 0x80>;
- };
-
- rtic_d: rtic-d at 60 {
- compatible = "fsl,sec-v4.2-rtic-memory",
- "fsl,sec-v4.0-rtic-memory";
- reg = <0x60 0x20 0x500 0x80>;
+ /* XAUI card in slot 2 */
+ phy_xgmii_2: ethernet-phy at 0 {
+ reg = <0x0>;
};
};
};
+ };
- sec_mon: sec_mon at 314000 {
- compatible = "fsl,sec-v4.2-mon", "fsl,sec-v4.0-mon";
- reg = <0x314000 0x1000>;
- interrupts = <93 2 0 0>;
+ rapidio at ffe0c0000 {
+ reg = <0xf 0xfe0c0000 0 0x11000>;
+
+ port1 {
+ ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+ };
+ port2 {
+ ranges = <0 0 0xc 0x30000000 0 0x10000000>;
};
};
localbus at ffe124000 {
- compatible = "fsl,p3041-elbc", "fsl,elbc", "simple-bus";
reg = <0xf 0xfe124000 0 0x1000>;
- interrupts = <25 2 0 0>;
- #address-cells = <2>;
- #size-cells = <1>;
-
- ranges = <0 0 0xf 0xe8000000 0x08000000
- 3 0 0xf 0xffdf0000 0x00008000>;
+ ranges = <0 0 0xf 0xb8000000 0x04000000>;
flash at 0,0 {
compatible = "cfi-flash";
- reg = <0 0 0x08000000>;
+ /*
+ * Map 64Mb of 128MB NOR flash memory. Since highest
+ * line of address of NOR flash memory are set by
+ * FPGA, memory are divided into two pages equal to
+ * 64MB. One of the pages can be accessed at once.
+ */
+ reg = <0 0 0x04000000>;
bank-width = <2>;
device-width = <2>;
};
+ nand at 2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,elbc-fcm-nand";
+ reg = <0x2 0x0 0x40000>;
+
+ partition at 0 {
+ label = "NAND U-Boot Image";
+ reg = <0x0 0x02000000>;
+ read-only;
+ };
+
+ partition at 2000000 {
+ label = "NAND Root File System";
+ reg = <0x02000000 0x10000000>;
+ };
+
+ partition at 12000000 {
+ label = "NAND Compressed RFS Image";
+ reg = <0x12000000 0x08000000>;
+ };
+
+ partition at 1a000000 {
+ label = "NAND Linux Kernel Image";
+ reg = <0x1a000000 0x04000000>;
+ };
+
+ partition at 1e000000 {
+ label = "NAND DTB Image";
+ reg = <0x1e000000 0x01000000>;
+ };
+
+ partition at 1f000000 {
+ label = "NAND Writable User area";
+ reg = <0x1f000000 0x21000000>;
+ };
+ };
+
board-control at 3,0 {
- compatible = "fsl,p3041ds-pixis";
- reg = <3 0 0x20>;
+ compatible = "fsl,p3041ds-fpga", "fsl,fpga-ngpixis";
+ reg = <3 0 0x30>;
};
};
pci0: pcie at ffe200000 {
- compatible = "fsl,p3041-pcie", "fsl,qoriq-pcie-v2.2";
- device_type = "pci";
- #size-cells = <2>;
- #address-cells = <3>;
reg = <0xf 0xfe200000 0 0x1000>;
- bus-range = <0x0 0xff>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
- clock-frequency = <0x1fca055>;
- fsl,msi = <&msi0>;
- interrupts = <16 2 1 15>;
+ ranges = <0x02000000 0 0x80000000 0x0 0x80000000 0x0 0x10000000
+ 0x01000000 0 0x00000000 0x0 0xff000000 0x0 0x00010000>;
pcie at 0 {
- reg = <0 0 0 0 0>;
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- device_type = "pci";
- interrupts = <16 2 1 15>;
- interrupt-map-mask = <0xf800 0 0 7>;
- interrupt-map = <
- /* IDSEL 0x0 */
- 0000 0 0 1 &mpic 40 1 0 0
- 0000 0 0 2 &mpic 1 1 0 0
- 0000 0 0 3 &mpic 2 1 0 0
- 0000 0 0 4 &mpic 3 1 0 0
- >;
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
+ ranges = <0x02000000 0 0x80000000
+ 0x02000000 0 0x80000000
+ 0 0x10000000
0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
+ 0x01000000 0 0xff000000
0 0x00010000>;
};
};
pci1: pcie at ffe201000 {
- compatible = "fsl,p3041-pcie", "fsl,qoriq-pcie-v2.2";
- device_type = "pci";
- #size-cells = <2>;
- #address-cells = <3>;
reg = <0xf 0xfe201000 0 0x1000>;
- bus-range = <0 0xff>;
- ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
- 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
- clock-frequency = <0x1fca055>;
- fsl,msi = <&msi1>;
- interrupts = <16 2 1 14>;
+ ranges = <0x02000000 0x0 0x90000000 0x0 0x90000000 0x0 0x10000000
+ 0x01000000 0x0 0x00000000 0x0 0xff010000 0x0 0x00010000>;
pcie at 0 {
- reg = <0 0 0 0 0>;
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- device_type = "pci";
- interrupts = <16 2 1 14>;
- interrupt-map-mask = <0xf800 0 0 7>;
- interrupt-map = <
- /* IDSEL 0x0 */
- 0000 0 0 1 &mpic 41 1 0 0
- 0000 0 0 2 &mpic 5 1 0 0
- 0000 0 0 3 &mpic 6 1 0 0
- 0000 0 0 4 &mpic 7 1 0 0
- >;
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
+ ranges = <0x02000000 0 0x90000000
+ 0x02000000 0 0x90000000
+ 0 0x10000000
0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
+ 0x01000000 0 0xff010000
0 0x00010000>;
};
};
pci2: pcie at ffe202000 {
- compatible = "fsl,p3041-pcie", "fsl,qoriq-pcie-v2.2";
- device_type = "pci";
- #size-cells = <2>;
- #address-cells = <3>;
reg = <0xf 0xfe202000 0 0x1000>;
- bus-range = <0x0 0xff>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
- clock-frequency = <0x1fca055>;
- fsl,msi = <&msi2>;
- interrupts = <16 2 1 13>;
+ ranges = <0x02000000 0 0xa0000000 0x0 0xa0000000 0 0x10000000
+ 0x01000000 0 0x00000000 0x0 0xff020000 0 0x00010000>;
pcie at 0 {
- reg = <0 0 0 0 0>;
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- device_type = "pci";
- interrupts = <16 2 1 13>;
- interrupt-map-mask = <0xf800 0 0 7>;
- interrupt-map = <
- /* IDSEL 0x0 */
- 0000 0 0 1 &mpic 42 1 0 0
- 0000 0 0 2 &mpic 9 1 0 0
- 0000 0 0 3 &mpic 10 1 0 0
- 0000 0 0 4 &mpic 11 1 0 0
- >;
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
+ ranges = <0x02000000 0 0xa0000000
+ 0x02000000 0 0xa0000000
+ 0 0x10000000
0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
+ 0x01000000 0 0xff020000
0 0x00010000>;
};
};
pci3: pcie at ffe203000 {
- compatible = "fsl,p3041-pcie", "fsl,qoriq-pcie-v2.2";
- device_type = "pci";
- #size-cells = <2>;
- #address-cells = <3>;
reg = <0xf 0xfe203000 0 0x1000>;
- bus-range = <0x0 0xff>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
- clock-frequency = <0x1fca055>;
- fsl,msi = <&msi2>;
- interrupts = <16 2 1 12>;
+ ranges = <0x02000000 0 0xb0000000 0x0 0xb0000000 0 0x08000000
+ 0x01000000 0 0x00000000 0x0 0xff030000 0 0x00010000>;
pcie at 0 {
- reg = <0 0 0 0 0>;
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- device_type = "pci";
- interrupts = <16 2 1 12>;
- interrupt-map-mask = <0xf800 0 0 7>;
- interrupt-map = <
- /* IDSEL 0x0 */
- 0000 0 0 1 &mpic 43 1 0 0
- 0000 0 0 2 &mpic 0 1 0 0
- 0000 0 0 3 &mpic 4 1 0 0
- 0000 0 0 4 &mpic 8 1 0 0
- >;
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
+ ranges = <0x02000000 0 0xb0000000
+ 0x02000000 0 0xb0000000
+ 0 0x08000000
0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
+ 0x01000000 0 0xff030000
0 0x00010000>;
};
};
+
+ fsl,dpaa {
+ compatible = "fsl,p3041-dpaa", "fsl,dpaa";
+
+ ethernet at 0 {
+ compatible = "fsl,p3041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet0>;
+ status="okay";
+ };
+ ethernet at 1 {
+ compatible = "fsl,p3041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet1>;
+ status = "disabled";
+ };
+ ethernet at 2 {
+ compatible = "fsl,p3041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet2>;
+ status = "disabled";
+ };
+ ethernet at 3 {
+ compatible = "fsl,p3041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet3>;
+ status = "disabled";
+ };
+ ethernet at 4 {
+ compatible = "fsl,p3041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet4>;
+ status = "okay";
+ };
+ ethernet at 5 {
+ compatible = "fsl,p3041-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet5>;
+ status = "disabled";
+ };
+ };
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ };
};
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/fdt/dts/p3041si.dtsi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/boot/fdt/dts/p3041si.dtsi Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,1339 @@
+/*
+ * P3041 Silicon Device Tree Source
+ *
+ * Copyright 2010-2011 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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: head/sys/boot/fdt/dts/p3041si.dtsi 236024 2012-05-25 20:43:38Z raj $ */
+
+/dts-v1/;
+
+/ {
+ compatible = "fsl,P3041";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ ccsr = &soc;
+ dcsr = &dcsr;
+
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
+ ethernet5 = &enet5;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ serial2 = &serial2;
+ serial3 = &serial3;
+ pci0 = &pci0;
+ pci1 = &pci1;
+ pci2 = &pci2;
+ pci3 = &pci3;
+ usb0 = &usb0;
+ usb1 = &usb1;
+ dma0 = &dma0;
+ dma1 = &dma1;
+ bman = &bman;
+ qman = &qman;
+ pme = &pme;
+ rman = &rman;
+ sdhc = &sdhc;
+ msi0 = &msi0;
+ msi1 = &msi1;
+ msi2 = &msi2;
+
+ crypto = &crypto;
+ sec_jr0 = &sec_jr0;
+ sec_jr1 = &sec_jr1;
+ sec_jr2 = &sec_jr2;
+ sec_jr3 = &sec_jr3;
+ rtic_a = &rtic_a;
+ rtic_b = &rtic_b;
+ rtic_c = &rtic_c;
+ rtic_d = &rtic_d;
+ sec_mon = &sec_mon;
+
+ fman0 = &fman0;
+ fman0_oh0 = &fman0_oh0;
+ fman0_oh1 = &fman0_oh1;
+ fman0_oh2 = &fman0_oh2;
+ fman0_oh3 = &fman0_oh3;
+ fman0_oh4 = &fman0_oh4;
+ fman0_oh5 = &fman0_oh5;
+ fman0_oh6 = &fman0_oh6;
+ fman0_rx0 = &fman0_rx0;
+ fman0_rx1 = &fman0_rx1;
+ fman0_rx2 = &fman0_rx2;
+ fman0_rx3 = &fman0_rx3;
+ fman0_rx4 = &fman0_rx4;
+ fman0_rx5 = &fman0_rx5;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: PowerPC,e500mc at 0 {
+ device_type = "cpu";
+ reg = <0>;
+ bus-frequency = <749999996>;
+ next-level-cache = <&L2_0>;
+ L2_0: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ cpu1: PowerPC,e500mc at 1 {
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2_1>;
+ L2_1: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ cpu2: PowerPC,e500mc at 2 {
+ device_type = "cpu";
+ reg = <2>;
+ next-level-cache = <&L2_2>;
+ L2_2: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ cpu3: PowerPC,e500mc at 3 {
+ device_type = "cpu";
+ reg = <3>;
+ next-level-cache = <&L2_3>;
+ L2_3: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ };
+
+ dcsr: dcsr at f00000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,dcsr", "simple-bus";
+
+ dcsr-epu at 0 {
+ compatible = "fsl,dcsr-epu";
+ interrupts = <52 2 0 0
+ 84 2 0 0
+ 85 2 0 0>;
+ interrupt-parent = <&mpic>;
+ reg = <0x0 0x1000>;
+ };
+ dcsr-npc {
+ compatible = "fsl,dcsr-npc";
+ reg = <0x1000 0x1000 0x1000000 0x8000>;
+ };
+ dcsr-nxc at 2000 {
+ compatible = "fsl,dcsr-nxc";
+ reg = <0x2000 0x1000>;
+ };
+ dcsr-corenet {
+ compatible = "fsl,dcsr-corenet";
+ reg = <0x8000 0x1000 0xB0000 0x1000>;
+ };
+ dcsr-dpaa at 9000 {
+ compatible = "fsl,p43041-dcsr-dpaa", "fsl,dcsr-dpaa";
+ reg = <0x9000 0x1000>;
+ };
+ dcsr-ocn at 11000 {
+ compatible = "fsl,p43041-dcsr-ocn", "fsl,dcsr-ocn";
+ reg = <0x11000 0x1000>;
+ };
+ dcsr-ddr at 12000 {
+ compatible = "fsl,dcsr-ddr";
+ dev-handle = <&ddr>;
+ reg = <0x12000 0x1000>;
+ };
+ dcsr-nal at 18000 {
+ compatible = "fsl,p43041-dcsr-nal", "fsl,dcsr-nal";
+ reg = <0x18000 0x1000>;
+ };
+ dcsr-rcpm at 22000 {
+ compatible = "fsl,p43041-dcsr-rcpm", "fsl,dcsr-rcpm";
+ reg = <0x22000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy at 40000 {
+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu0>;
+ reg = <0x40000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy at 41000 {
+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu1>;
+ reg = <0x41000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy at 42000 {
+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu2>;
+ reg = <0x42000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy at 43000 {
+ compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu3>;
+ reg = <0x43000 0x1000>;
+ };
+ };
+
+ bman-portals at ff4000000 {
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ compatible = "bman-portals";
+ ranges = <0x0 0xf 0xfde00000 0x200000>;
+ bman-portal at 0 {
+ cell-index = <0x0>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0x0 0x4000 0x100000 0x1000>;
+ interrupts = <105 2 0 0>;
+ };
+ bman-portal at 4000 {
+ cell-index = <0x1>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0x4000 0x4000 0x101000 0x1000>;
+ interrupts = <107 2 0 0>;
+ };
+ bman-portal at 8000 {
+ cell-index = <2>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0x8000 0x4000 0x102000 0x1000>;
+ interrupts = <109 2 0 0>;
+ };
+ bman-portal at c000 {
+ cell-index = <0x3>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0xc000 0x4000 0x103000 0x1000>;
+ interrupts = <111 2 0 0>;
+ };
+ bman-portal at 10000 {
+ cell-index = <0x4>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0x10000 0x4000 0x104000 0x1000>;
+ interrupts = <113 2 0 0>;
+ };
+ bman-portal at 14000 {
+ cell-index = <0x5>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0x14000 0x4000 0x105000 0x1000>;
+ interrupts = <115 2 0 0>;
+ };
+ bman-portal at 18000 {
+ cell-index = <0x6>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0x18000 0x4000 0x106000 0x1000>;
+ interrupts = <117 2 0 0>;
+ };
+ bman-portal at 1c000 {
+ cell-index = <0x7>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0x1c000 0x4000 0x107000 0x1000>;
+ interrupts = <119 2 0 0>;
+ };
+ bman-portal at 20000 {
+ cell-index = <0x8>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0x20000 0x4000 0x108000 0x1000>;
+ interrupts = <121 2 0 0>;
+ };
+ bman-portal at 24000 {
+ cell-index = <0x9>;
+ compatible = "fsl,p3041-bman-portal", "fsl,bman-portal";
+ reg = <0x24000 0x4000 0x109000 0x1000>;
+ interrupts = <123 2 0 0>;
+ };
+
+ buffer-pool at 0 {
+ compatible = "fsl,p3041-bpool", "fsl,bpool";
+ fsl,bpid = <0>;
+ fsl,bpool-cfg = <0 0x100 0 1 0 0x100>;
+ };
+ };
+
+ qman-portals at ff4200000 {
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ compatible = "qman-portals";
+ ranges = <0x0 0xf 0xfdc00000 0x200000>;
+ qportal0: qman-portal at 0 {
+ cell-index = <0x0>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0x0 0x4000 0x100000 0x1000>;
+ interrupts = <104 0x2 0 0>;
+ fsl,qman-channel-id = <0x0>;
+ };
+
+ qportal1: qman-portal at 4000 {
+ cell-index = <0x1>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0x4000 0x4000 0x101000 0x1000>;
+ interrupts = <106 0x2 0 0>;
+ fsl,qman-channel-id = <0x1>;
+ };
+
+ qportal2: qman-portal at 8000 {
+ cell-index = <0x2>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0x8000 0x4000 0x102000 0x1000>;
+ interrupts = <108 0x2 0 0>;
+ fsl,qman-channel-id = <0x2>;
+ };
+
+ qportal3: qman-portal at c000 {
+ cell-index = <0x3>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0xc000 0x4000 0x103000 0x1000>;
+ interrupts = <110 0x2 0 0>;
+ fsl,qman-channel-id = <0x3>;
+ };
+
+ qportal4: qman-portal at 10000 {
+ cell-index = <0x4>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0x10000 0x4000 0x104000 0x1000>;
+ interrupts = <112 0x2 0 0>;
+ fsl,qman-channel-id = <0x4>;
+ };
+
+ qportal5: qman-portal at 14000 {
+ cell-index = <0x5>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0x14000 0x4000 0x105000 0x1000>;
+ interrupts = <114 0x2 0 0>;
+ fsl,qman-channel-id = <0x5>;
+ };
+
+ qportal6: qman-portal at 18000 {
+ cell-index = <0x6>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0x18000 0x4000 0x106000 0x1000>;
+ interrupts = <116 0x2 0 0>;
+ fsl,qman-channel-id = <0x6>;
+ };
+
+ qportal7: qman-portal at 1c000 {
+ cell-index = <0x7>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0x1c000 0x4000 0x107000 0x1000>;
+ interrupts = <118 0x2 0 0>;
+ fsl,qman-channel-id = <0x7>;
+ };
+
+ qportal8: qman-portal at 20000 {
+ cell-index = <0x8>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0x20000 0x4000 0x108000 0x1000>;
+ interrupts = <120 0x2 0 0>;
+ fsl,qman-channel-id = <0x8>;
+ };
+
+ qportal9: qman-portal at 24000 {
+ cell-index = <0x9>;
+ compatible = "fsl,p3041-qman-portal", "fsl,qman-portal";
+ reg = <0x24000 0x4000 0x109000 0x1000>;
+ interrupts = <122 0x2 0 0>;
+ fsl,qman-channel-id = <0x9>;
+ };
+
+ qpool1: qman-pool at 1 {
+ cell-index = <1>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x21>;
+ };
+
+ qpool2: qman-pool at 2 {
+ cell-index = <2>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x22>;
+ };
+
+ qpool3: qman-pool at 3 {
+ cell-index = <3>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x23>;
+ };
+
+ qpool4: qman-pool at 4 {
+ cell-index = <4>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x24>;
+ };
+
+ qpool5: qman-pool at 5 {
+ cell-index = <5>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x25>;
+ };
+
+ qpool6: qman-pool at 6 {
+ cell-index = <6>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x26>;
+ };
+
+ qpool7: qman-pool at 7 {
+ cell-index = <7>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x27>;
+ };
+
+ qpool8: qman-pool at 8 {
+ cell-index = <8>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x28>;
+ };
+
+ qpool9: qman-pool at 9 {
+ cell-index = <9>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x29>;
+ };
+
+ qpool10: qman-pool at 10 {
+ cell-index = <10>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2a>;
+ };
+
+ qpool11: qman-pool at 11 {
+ cell-index = <11>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2b>;
+ };
+
+ qpool12: qman-pool at 12 {
+ cell-index = <12>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2c>;
+ };
+
+ qpool13: qman-pool at 13 {
+ cell-index = <13>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2d>;
+ };
+
+ qpool14: qman-pool at 14 {
+ cell-index = <14>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2e>;
+ };
+
+ qpool15: qman-pool at 15 {
+ cell-index = <15>;
+ compatible = "fsl,p3041-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2f>;
+ };
+ };
+
+ soc: soc at ffe000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "simple-bus";
+
+ bus-frequency = <0>; // Filled out by kernel.
+
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+
+ soc-sram-error {
+ compatible = "fsl,soc-sram-error";
+ interrupts = <16 2 1 29>;
+ };
+
+ corenet-law at 0 {
+ compatible = "fsl,corenet-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <32>;
+ };
+
+ ddr: memory-controller at 8000 {
+ compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
+ reg = <0x8000 0x1000>;
+ interrupts = <16 2 1 23>;
+ };
+
+ cpc: l3-cache-controller at 10000 {
+ compatible = "fsl,p3041-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache";
+ reg = <0x10000 0x1000>;
+ interrupts = <16 2 1 27>;
+ };
+
+ corenet-cf at 18000 {
+ compatible = "fsl,corenet-cf";
+ reg = <0x18000 0x1000>;
+ interrupts = <16 2 1 31>;
+ fsl,ccf-num-csdids = <32>;
+ fsl,ccf-num-snoopids = <32>;
+ };
+
+ iommu at 20000 {
+ compatible = "fsl,pamu-v1.0", "fsl,pamu";
+ reg = <0x20000 0x4000>;
+ interrupts = <
+ 24 2 0 0
+ 16 2 1 30>;
+ };
+
+ mpic: pic at 40000 {
+ clock-frequency = <0>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <4>;
+ reg = <0x40000 0x40000>;
+ compatible = "fsl,mpic", "chrp,open-pic";
+ device_type = "open-pic";
+ };
+
+ msi0: msi at 41600 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41600 0x200>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe0 0 0 0
+ 0xe1 0 0 0
+ 0xe2 0 0 0
+ 0xe3 0 0 0
+ 0xe4 0 0 0
+ 0xe5 0 0 0
+ 0xe6 0 0 0
+ 0xe7 0 0 0>;
+ };
+
+ msi1: msi at 41800 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41800 0x200>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe8 0 0 0
+ 0xe9 0 0 0
+ 0xea 0 0 0
+ 0xeb 0 0 0
+ 0xec 0 0 0
+ 0xed 0 0 0
+ 0xee 0 0 0
+ 0xef 0 0 0>;
+ };
+
+ msi2: msi at 41a00 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41a00 0x200>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xf0 0 0 0
+ 0xf1 0 0 0
+ 0xf2 0 0 0
+ 0xf3 0 0 0
+ 0xf4 0 0 0
+ 0xf5 0 0 0
+ 0xf6 0 0 0
+ 0xf7 0 0 0>;
+ };
+
+ guts: global-utilities at e0000 {
+ compatible = "fsl,qoriq-device-config-1.0";
+ reg = <0xe0000 0xe00>;
+ fsl,has-rstcr;
+ #sleep-cells = <1>;
+ fsl,liodn-bits = <12>;
+ };
+
+ pins: global-utilities at e0e00 {
+ compatible = "fsl,qoriq-pin-control-1.0";
+ reg = <0xe0e00 0x200>;
+ #sleep-cells = <2>;
+ };
+
+ clockgen: global-utilities at e1000 {
+ compatible = "fsl,p3041-clockgen", "fsl,qoriq-clockgen-1.0";
+ reg = <0xe1000 0x1000>;
+ clock-frequency = <0>;
+ };
+
+ rcpm: global-utilities at e2000 {
+ compatible = "fsl,qoriq-rcpm-1.0";
+ reg = <0xe2000 0x1000>;
+ #sleep-cells = <1>;
+ };
+
+ sfp: sfp at e8000 {
+ compatible = "fsl,p3041-sfp", "fsl,qoriq-sfp-1.0";
+ reg = <0xe8000 0x1000>;
+ };
+
+ serdes: serdes at ea000 {
+ compatible = "fsl,p3041-serdes";
+ reg = <0xea000 0x1000>;
+ };
+
+ dma0: dma at 100300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p3041-dma", "fsl,eloplus-dma";
+ reg = <0x100300 0x4>;
+ ranges = <0x0 0x100100 0x200>;
+ cell-index = <0>;
+ dma-channel at 0 {
+ compatible = "fsl,p3041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupts = <28 2 0 0>;
+ };
+ dma-channel at 80 {
+ compatible = "fsl,p3041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupts = <29 2 0 0>;
+ };
+ dma-channel at 100 {
+ compatible = "fsl,p3041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupts = <30 2 0 0>;
+ };
+ dma-channel at 180 {
+ compatible = "fsl,p3041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupts = <31 2 0 0>;
+ };
+ };
+
+ dma1: dma at 101300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p3041-dma", "fsl,eloplus-dma";
+ reg = <0x101300 0x4>;
+ ranges = <0x0 0x101100 0x200>;
+ cell-index = <1>;
+ dma-channel at 0 {
+ compatible = "fsl,p3041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupts = <32 2 0 0>;
+ };
+ dma-channel at 80 {
+ compatible = "fsl,p3041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupts = <33 2 0 0>;
+ };
+ dma-channel at 100 {
+ compatible = "fsl,p3041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupts = <34 2 0 0>;
+ };
+ dma-channel at 180 {
+ compatible = "fsl,p3041-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupts = <35 2 0 0>;
+ };
+ };
+
+ spi at 110000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,p3041-espi", "fsl,mpc8536-espi";
+ reg = <0x110000 0x1000>;
+ interrupts = <53 0x2 0 0>;
+ fsl,espi-num-chipselects = <4>;
+ };
+
+ sdhc: sdhc at 114000 {
+ compatible = "fsl,p3041-esdhc", "fsl,esdhc";
+ reg = <0x114000 0x1000>;
+ interrupts = <48 2 0 0>;
+ sdhci,auto-cmd12;
+ clock-frequency = <0>;
+ };
+
+ i2c at 118000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x118000 0x100>;
+ interrupts = <38 2 0 0>;
+ dfsrr;
+ };
+
+ i2c at 118100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ compatible = "fsl-i2c";
+ reg = <0x118100 0x100>;
+ interrupts = <38 2 0 0>;
+ dfsrr;
+ };
+
+ i2c at 119000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <2>;
+ compatible = "fsl-i2c";
+ reg = <0x119000 0x100>;
+ interrupts = <39 2 0 0>;
+ dfsrr;
+ };
+
+ i2c at 119100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <3>;
+ compatible = "fsl-i2c";
+ reg = <0x119100 0x100>;
+ interrupts = <39 2 0 0>;
+ dfsrr;
+ };
+
+ serial0: serial at 11c500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11c500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <36 2 0 0>;
+ };
+
+ serial1: serial at 11c600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11c600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <36 2 0 0>;
+ };
+
+ serial2: serial at 11d500 {
+ cell-index = <2>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11d500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <37 2 0 0>;
+ };
+
+ serial3: serial at 11d600 {
+ cell-index = <3>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11d600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <37 2 0 0>;
+ };
+
+ gpio0: gpio at 130000 {
+ compatible = "fsl,p3041-gpio", "fsl,qoriq-gpio";
+ reg = <0x130000 0x1000>;
+ interrupts = <55 2 0 0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ };
+
+ rman: rman at 1e0000 {
+ compatible = "fsl,rman";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x1e0000 0x20000>;
+ reg = <0x1e0000 0x20000>;
+ interrupts = <16 2 1 11>; /* err_irq */
+ fsl,qman-channels-id = <0x62 0x63>;
+
+ inbound-block at 0 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x0 0x800>;
+ };
+ global-cfg at b00 {
+ compatible = "fsl,rman-global-cfg";
+ reg = <0xb00 0x500>;
+ };
+ inbound-block at 1000 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x1000 0x800>;
+ };
+ inbound-block at 2000 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x2000 0x800>;
+ };
+ inbound-block at 3000 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x3000 0x800>;
+ };
+ };
+
+ usb0: usb at 210000 {
+ compatible = "fsl,p3041-usb2-mph",
+ "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph";
+ reg = <0x210000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <44 0x2 0 0>;
+ phy_type = "utmi";
+ port0;
+ };
+
+ usb1: usb at 211000 {
+ compatible = "fsl,p3041-usb2-dr",
+ "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr";
+ reg = <0x211000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <45 0x2 0 0>;
+ dr_mode = "host";
+ phy_type = "utmi";
+ };
+
+ sata at 220000 {
+ compatible = "fsl,p3041-sata", "fsl,pq-sata-v2";
+ reg = <0x220000 0x1000>;
+ interrupts = <68 0x2 0 0>;
+ };
+
+ sata at 221000 {
+ compatible = "fsl,p3041-sata", "fsl,pq-sata-v2";
+ reg = <0x221000 0x1000>;
+ interrupts = <69 0x2 0 0>;
+ };
+
+ crypto: crypto at 300000 {
+ compatible = "fsl,sec-v4.2", "fsl,sec-v4.0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x300000 0x10000>;
+ ranges = <0 0x300000 0x10000>;
+ interrupts = <92 2 0 0>;
+
+ sec_jr0: jr at 1000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x1000 0x1000>;
+ interrupts = <88 2 0 0>;
+ };
+
+ sec_jr1: jr at 2000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x2000 0x1000>;
+ interrupts = <89 2 0 0>;
+ };
+
+ sec_jr2: jr at 3000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x3000 0x1000>;
+ interrupts = <90 2 0 0>;
+ };
+
+ sec_jr3: jr at 4000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x4000 0x1000>;
+ interrupts = <91 2 0 0>;
+ };
+
+ rtic at 6000 {
+ compatible = "fsl,sec-v4.2-rtic",
+ "fsl,sec-v4.0-rtic";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x6000 0x100>;
+ ranges = <0x0 0x6100 0xe00>;
+
+ rtic_a: rtic-a at 0 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x00 0x20 0x100 0x80>;
+ };
+
+ rtic_b: rtic-b at 20 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x20 0x20 0x200 0x80>;
+ };
+
+ rtic_c: rtic-c at 40 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x40 0x20 0x300 0x80>;
+ };
+
+ rtic_d: rtic-d at 60 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x60 0x20 0x500 0x80>;
+ };
+ };
+ };
+
+ sec_mon: sec_mon at 314000 {
+ compatible = "fsl,sec-v4.2-mon", "fsl,sec-v4.0-mon";
+ reg = <0x314000 0x1000>;
+ interrupts = <93 2 0 0>;
+ };
+
+ pme: pme at 316000 {
+ compatible = "fsl,pme";
+ reg = <0x316000 0x10000>;
+ /* fsl,pme-pdsr = <0x0 0x23000000 0x0 0x01000000>; */
+ /* fsl,pme-sre = <0x0 0x24000000 0x0 0x00a00000>; */
+ interrupts = <16 2 1 5>;
+ };
+
+ qman: qman at 318000 {
+ compatible = "fsl,p3041-qman", "fsl,qman";
+ reg = <0x318000 0x1000>;
+ interrupts = <16 2 1 3>;
+ /* Commented out, use default allocation */
+ /* fsl,qman-fqd = <0x0 0x20000000 0x0 0x01000000>; */
+ /* fsl,qman-pfdr = <0x0 0x21000000 0x0 0x01000000>; */
+ };
+
+ bman: bman at 31a000 {
+ compatible = "fsl,p3041-bman", "fsl,bman";
+ reg = <0x31a000 0x1000>;
+ interrupts = <16 2 1 2>;
+ /* Same as fsl,qman-*, use default allocation */
+ /* fsl,bman-fbpr = <0x0 0x22000000 0x0 0x01000000>; */
+ };
+
+ fman0: fman at 400000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ compatible = "fsl,p3041-fman", "fsl,fman", "simple-bus";
+ ranges = <0 0x400000 0x100000>;
+ reg = <0x400000 0x100000>;
+ clock-frequency = <0>;
+ interrupts = <
+ 96 2 0 0
+ 16 2 1 1>;
+
+ cc at 0 {
+ compatible = "fsl,p3041-fman-cc", "fsl,fman-cc";
+ };
+
+ parser at c7000 {
+ compatible = "fsl,p3041-fman-parser", "fsl,fman-parser";
+ reg = <0xc7000 0x1000>;
+ };
+
+ keygen at c1000 {
+ compatible = "fsl,p3041-fman-keygen", "fsl,fman-keygen";
+ reg = <0xc1000 0x1000>;
+ };
+
+ policer at c0000 {
+ compatible = "fsl,p3041-fman-policer", "fsl,fman-policer";
+ reg = <0xc0000 0x1000>;
+ };
+
+ muram at 0 {
+ compatible = "fsl,p3041-fman-muram", "fsl,fman-muram";
+ reg = <0x0 0x28000>;
+ };
+
+ bmi at 80000 {
+ compatible = "fsl,p3041-fman-bmi", "fsl,fman-bmi";
+ reg = <0x80000 0x400>;
+ };
+
+ qmi at 80400 {
+ compatible = "fsl,p3041-fman-qmi", "fsl,fman-qmi";
+ reg = <0x80400 0x400>;
+ };
+
+ fman0_rx0: port at 88000 {
+ cell-index = <0>;
+ compatible = "fsl,p3041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x88000 0x1000>;
+ };
+ fman0_rx1: port at 89000 {
+ cell-index = <1>;
+ compatible = "fsl,p3041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x89000 0x1000>;
+ };
+ fman0_rx2: port at 8a000 {
+ cell-index = <2>;
+ compatible = "fsl,p3041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x8a000 0x1000>;
+ };
+ fman0_rx3: port at 8b000 {
+ cell-index = <3>;
+ compatible = "fsl,p3041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x8b000 0x1000>;
+ };
+ fman0_rx4: port at 8c000 {
+ cell-index = <4>;
+ compatible = "fsl,p3041-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x8c000 0x1000>;
+ };
+ fman0_rx5: port at 90000 {
+ cell-index = <0>;
+ compatible = "fsl,p3041-fman-port-10g-rx", "fsl,fman-port-10g-rx";
+ reg = <0x90000 0x1000>;
+ };
+
+ fman0_tx5: port at b0000 {
+ cell-index = <0>;
+ compatible = "fsl,p3041-fman-port-10g-tx", "fsl,fman-port-10g-tx";
+ reg = <0xb0000 0x1000>;
+ fsl,qman-channel-id = <0x40>;
+ };
+ fman0_tx0: port at a8000 {
+ cell-index = <0>;
+ compatible = "fsl,p3041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xa8000 0x1000>;
+ fsl,qman-channel-id = <0x41>;
+ };
+ fman0_tx1: port at a9000 {
+ cell-index = <1>;
+ compatible = "fsl,p3041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xa9000 0x1000>;
+ fsl,qman-channel-id = <0x42>;
+ };
+ fman0_tx2: port at aa000 {
+ cell-index = <2>;
+ compatible = "fsl,p3041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xaa000 0x1000>;
+ fsl,qman-channel-id = <0x43>;
+ };
+ fman0_tx3: port at ab000 {
+ cell-index = <3>;
+ compatible = "fsl,p3041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xab000 0x1000>;
+ fsl,qman-channel-id = <0x44>;
+ };
+ fman0_tx4: port at ac000 {
+ cell-index = <4>;
+ compatible = "fsl,p3041-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xac000 0x1000>;
+ fsl,qman-channel-id = <0x45>;
+ };
+
+ fman0_oh0: port at 81000 {
+ cell-index = <0>;
+ compatible = "fsl,p3041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x81000 0x1000>;
+ fsl,qman-channel-id = <0x46>;
+ };
+ fman0_oh1: port at 82000 {
+ cell-index = <1>;
+ compatible = "fsl,p3041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x82000 0x1000>;
+ fsl,qman-channel-id = <0x47>;
+ };
+ fman0_oh2: port at 83000 {
+ cell-index = <2>;
+ compatible = "fsl,p3041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x83000 0x1000>;
+ fsl,qman-channel-id = <0x48>;
+ };
+ fman0_oh3: port at 84000 {
+ cell-index = <3>;
+ compatible = "fsl,p3041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x84000 0x1000>;
+ fsl,qman-channel-id = <0x49>;
+ };
+ fman0_oh4: port at 85000 {
+ cell-index = <4>;
+ compatible = "fsl,p3041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x85000 0x1000>;
+ fsl,qman-channel-id = <0x4a>;
+ };
+ fman0_oh5: port at 86000 {
+ cell-index = <5>;
+ compatible = "fsl,p3041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x86000 0x1000>;
+ fsl,qman-channel-id = <0x4b>;
+ };
+ fman0_oh6: port at 87000 {
+ cell-index = <6>;
+ compatible = "fsl,p3041-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x87000 0x1000>;
+ };
+
+ enet0: ethernet at e0000 {
+ cell-index = <0>;
+ compatible = "fsl,p3041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe0000 0x1000>;
+ fsl,port-handles = <&fman0_rx0 &fman0_tx0>;
+ ptimer-handle = <&ptp_timer0>;
+ };
+
+ mdio0: mdio at e1120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-mdio";
+ reg = <0xe1120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet1: ethernet at e2000 {
+ cell-index = <1>;
+ compatible = "fsl,p3041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe2000 0x1000>;
+ fsl,port-handles = <&fman0_rx1 &fman0_tx1>;
+ ptimer-handle = <&ptp_timer0>;
+ };
+
+ mdio at e3120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe3120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet2: ethernet at e4000 {
+ cell-index = <2>;
+ compatible = "fsl,p3041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe4000 0x1000>;
+ fsl,port-handles = <&fman0_rx2 &fman0_tx2>;
+ ptimer-handle = <&ptp_timer0>;
+ };
+
+ mdio at e5120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe5120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet3: ethernet at e6000 {
+ cell-index = <3>;
+ compatible = "fsl,p3041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe6000 0x1000>;
+ fsl,port-handles = <&fman0_rx3 &fman0_tx3>;
+ };
+
+ mdio at e7120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe7120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet4: ethernet at e8000 {
+ cell-index = <4>;
+ compatible = "fsl,p3041-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe8000 0x1000>;
+ fsl,port-handles = <&fman0_rx4 &fman0_tx4>;
+ ptimer-handle = <&ptp_timer0>;
+ };
+
+ mdio at e9120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe9120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet5: ethernet at f0000 {
+ cell-index = <0>;
+ compatible = "fsl,p3041-fman-10g-mac", "fsl,fman-10g-mac";
+ reg = <0xf0000 0x1000>;
+ fsl,port-handles = <&fman0_rx5 &fman0_tx5>;
+ };
+
+ mdio at f1000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-xmdio";
+ reg = <0xf1000 0x1000>;
+ interrupts = <100 1 0 0>;
+ };
+
+ ptp_timer0: rtc at fe000 {
+ compatible = "fsl,fman-rtc";
+ reg = <0xfe000 0x1000>;
+ };
+ };
+ };
+
+ rapidio at ffe0c0000 {
+ compatible = "fsl,srio";
+ interrupts = <16 2 1 11>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ port1 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ cell-index = <1>;
+ };
+
+ port2 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ cell-index = <2>;
+ };
+ };
+
+ localbus at ffe124000 {
+ compatible = "fsl,p3041-rev1.0-elbc", "simple-bus", "fsl,elbc";
+ interrupts = <
+ 25 2 0 0
+ 16 2 1 19
+ >;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ };
+
+ pci0: pcie at ffe200000 {
+ compatible = "fsl,p3041-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "okay";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <0x1fca055>;
+ fsl,msi = <&msi0>;
+ interrupts = <16 2 1 15>;
+
+ pcie at 0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 15>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 40 1 0 0
+ 0000 0 0 2 &mpic 1 1 0 0
+ 0000 0 0 3 &mpic 2 1 0 0
+ 0000 0 0 4 &mpic 3 1 0 0
+ >;
+ };
+ };
+
+ pci1: pcie at ffe201000 {
+ compatible = "fsl,p3041-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "disabled";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0 0xff>;
+ clock-frequency = <0x1fca055>;
+ fsl,msi = <&msi1>;
+ interrupts = <16 2 1 14>;
+ pcie at 0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 14>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 41 1 0 0
+ 0000 0 0 2 &mpic 5 1 0 0
+ 0000 0 0 3 &mpic 6 1 0 0
+ 0000 0 0 4 &mpic 7 1 0 0
+ >;
+ };
+ };
+
+ pci2: pcie at ffe202000 {
+ compatible = "fsl,p3041-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "okay";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <0x1fca055>;
+ fsl,msi = <&msi2>;
+ interrupts = <16 2 1 13>;
+ pcie at 0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 13>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 42 1 0 0
+ 0000 0 0 2 &mpic 9 1 0 0
+ 0000 0 0 3 &mpic 10 1 0 0
+ 0000 0 0 4 &mpic 11 1 0 0
+ >;
+ };
+ };
+
+ pci3: pcie at ffe203000 {
+ compatible = "fsl,p3041-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "disabled";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <0x1fca055>;
+ fsl,msi = <&msi2>;
+ interrupts = <16 2 1 12>;
+ pcie at 0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 12>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 43 1 0 0
+ 0000 0 0 2 &mpic 0 1 0 0
+ 0000 0 0 3 &mpic 4 1 0 0
+ 0000 0 0 4 &mpic 8 1 0 0
+ >;
+ };
+ };
+};
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/fdt/dts/p5020ds.dts
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/boot/fdt/dts/p5020ds.dts Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,583 @@
+/*
+ * P5020DS Device Tree Source
+ *
+ * Copyright 2010-2011 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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: head/sys/boot/fdt/dts/p5020ds.dts 236024 2012-05-25 20:43:38Z raj $ */
+
+/include/ "p5020si.dtsi"
+
+/ {
+ model = "fsl,P5020DS";
+ compatible = "fsl,P5020DS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ phy_rgmii_0 = &phy_rgmii_0;
+ phy_rgmii_1 = &phy_rgmii_1;
+ phy_sgmii_1c = &phy_sgmii_1c;
+ phy_sgmii_1d = &phy_sgmii_1d;
+ phy_sgmii_1e = &phy_sgmii_1e;
+ phy_sgmii_1f = &phy_sgmii_1f;
+ phy_xgmii_1 = &phy_xgmii_1;
+ phy_xgmii_2 = &phy_xgmii_2;
+ emi1_rgmii = &hydra_mdio_rgmii;
+ emi1_sgmii = &hydra_mdio_sgmii;
+ emi2_xgmii = &hydra_mdio_xgmii;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x00000000 0x00000000 0x80000000>;
+ };
+
+ dcsr: dcsr at f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+ };
+
+ bman-portals at ff4000000 {
+ bman-portal at 0 {
+ cpu-handle = <&cpu0>;
+ };
+ bman-portal at 4000 {
+ cpu-handle = <&cpu1>;
+ };
+ bman-portal at 8000 {
+ };
+ bman-portal at c000 {
+ };
+ bman-portal at 10000 {
+ };
+ bman-portal at 14000 {
+ };
+ bman-portal at 18000 {
+ };
+ bman-portal at 1c000 {
+ };
+ bman-portal at 20000 {
+ };
+ bman-portal at 24000 {
+ };
+
+ buffer-pool at 0 {
+ compatible = "fsl,p5020-bpool", "fsl,bpool";
+ fsl,bpid = <0>;
+ fsl,bpool-cfg = <0 0x100 0 1 0 0x100>;
+ };
+ };
+
+ qman-portals at ff4200000 {
+ qportal0: qman-portal at 0 {
+ cpu-handle = <&cpu0>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal1: qman-portal at 4000 {
+ cpu-handle = <&cpu1>;
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal2: qman-portal at 8000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal3: qman-portal at c000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal4: qman-portal at 10000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal5: qman-portal at 14000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal6: qman-portal at 18000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal7: qman-portal at 1c000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal8: qman-portal at 20000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+
+ qportal9: qman-portal at 24000 {
+ fsl,qman-pool-channels = <&qpool1 &qpool2 &qpool3
+ &qpool4 &qpool5 &qpool6
+ &qpool7 &qpool8 &qpool9
+ &qpool10 &qpool11 &qpool12
+ &qpool13 &qpool14 &qpool15>;
+ };
+ };
+
+ soc: soc at ffe000000 {
+ spi at 110000 {
+ flash at 0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+ partition at u-boot {
+ label = "u-boot";
+ reg = <0x00000000 0x00100000>;
+ read-only;
+ };
+ partition at kernel {
+ label = "kernel";
+ reg = <0x00100000 0x00500000>;
+ read-only;
+ };
+ partition at dtb {
+ label = "dtb";
+ reg = <0x00600000 0x00100000>;
+ read-only;
+ };
+ partition at fs {
+ label = "file system";
+ reg = <0x00700000 0x00900000>;
+ };
+ };
+ };
+
+ i2c at 118100 {
+ eeprom at 51 {
+ compatible = "at24,24c256";
+ reg = <0x51>;
+ };
+ eeprom at 52 {
+ compatible = "at24,24c256";
+ reg = <0x52>;
+ };
+ };
+
+ i2c at 119100 {
+ rtc at 68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ interrupts = <0x1 0x1 0 0>;
+ };
+ };
+
+ pme: pme at 316000 {
+ /* Commented out, use default allocation */
+ /* fsl,pme-pdsr = <0x0 0x23000000 0x0 0x01000000>; */
+ /* fsl,pme-sre = <0x0 0x24000000 0x0 0x00a00000>; */
+ };
+
+ qman: qman at 318000 {
+ /* Commented out, use default allocation */
+ /* fsl,qman-fqd = <0x0 0x20000000 0x0 0x01000000>; */
+ /* fsl,qman-pfdr = <0x0 0x21000000 0x0 0x01000000>; */
+ };
+
+ bman: bman at 31a000 {
+ /* Same as fsl,qman-*, use default allocation */
+ /* fsl,bman-fbpr = <0x0 0x22000000 0x0 0x01000000>; */
+ };
+
+ fman0: fman at 400000 {
+ enet0: ethernet at e0000 {
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy_rgmii_0>;
+ phy-connection-type = "rgmii";
+ };
+
+ mdio0: mdio at e1120 {
+ tbi0: tbi-phy at 8 {
+ reg = <0x8>;
+ device_type = "tbi-phy";
+ };
+
+ /*
+ * Virtual MDIO for the two on-board RGMII
+ * ports. The fsl,hydra-mdio-muxval property
+ * is already correct.
+ */
+ hydra_mdio_rgmii: hydra-mdio-rgmii {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,hydra-mdio";
+ fsl,mdio-handle = <&mdio0>;
+ fsl,hydra-mdio-muxval = <0x00>;
+ status = "disabled";
+
+ phy_rgmii_0: ethernet-phy at 0 {
+ reg = <0x0>;
+ };
+ phy_rgmii_1: ethernet-phy at 1 {
+ reg = <0x1>;
+ };
+ };
+
+ /*
+ * Virtual MDIO for the four-port SGMII card.
+ * The fsl,hydra-mdio-muxval property will be
+ * fixed-up by U-Boot based on the slot that
+ * the SGMII card is in.
+ *
+ * Note: we do not support DTSEC5 connected to
+ * SGMII, so this is the only SGMII node.
+ */
+ hydra_mdio_sgmii: hydra-mdio-sgmii {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,hydra-mdio";
+ fsl,mdio-handle = <&mdio0>;
+ fsl,hydra-mdio-muxval = <0x00>;
+ status = "disabled";
+
+ phy_sgmii_1c: ethernet-phy at 1c {
+ reg = <0x1c>;
+ };
+ phy_sgmii_1d: ethernet-phy at 1d {
+ reg = <0x1d>;
+ };
+ phy_sgmii_1e: ethernet-phy at 1e {
+ reg = <0x1e>;
+ };
+ phy_sgmii_1f: ethernet-phy at 1f {
+ reg = <0x1f>;
+ };
+ };
+ };
+
+ enet1: ethernet at e2000 {
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy_sgmii_1d>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio at e3120 {
+ tbi1: tbi-phy at 8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet2: ethernet at e4000 {
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy_sgmii_1e>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio at e5120 {
+ tbi2: tbi-phy at 8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet3: ethernet at e6000 {
+ tbi-handle = <&tbi3>;
+ phy-handle = <&phy_sgmii_1f>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio at e7120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe7120 0xee0>;
+ interrupts = <100 1 0 0>;
+
+ tbi3: tbi-phy at 8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet4: ethernet at e8000 {
+ tbi-handle = <&tbi4>;
+ phy-handle = <&phy_rgmii_1>;
+ phy-connection-type = "rgmii";
+ };
+
+ mdio at e9120 {
+ tbi4: tbi-phy at 8 {
+ reg = <8>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet5: ethernet at f0000 {
+ /*
+ * phy-handle will be updated by U-Boot to
+ * reflect the actual slot the XAUI card is in.
+ */
+ phy-handle = <&phy_xgmii_1>;
+ phy-connection-type = "xgmii";
+ };
+
+ /*
+ * We only support one XAUI card, so the MDIO muxing
+ * is set by U-Boot, and Linux never touches it.
+ * Therefore, we don't need a virtual MDIO node.
+ * However, the phy address depends on the slot, so
+ * only one of the ethernet-phy nodes below will be
+ * used.
+ */
+ hydra_mdio_xgmii: mdio at f1000 {
+ status = "disabled";
+
+ /* XAUI card in slot 1 */
+ phy_xgmii_1: ethernet-phy at 4 {
+ reg = <0x4>;
+ };
+
+ /* XAUI card in slot 2 */
+ phy_xgmii_2: ethernet-phy at 0 {
+ reg = <0x0>;
+ };
+ };
+ };
+ };
+
+ rapidio at ffe0c0000 {
+ reg = <0xf 0xfe0c0000 0 0x11000>;
+
+ port1 {
+ ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+ };
+ port2 {
+ ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+ };
+ };
+
+ localbus at ffe124000 {
+ reg = <0xf 0xfe124000 0 0x1000>;
+ ranges = <0 0 0xf 0xb8000000 0x04000000>;
+
+ flash at 0,0 {
+ compatible = "cfi-flash";
+ /*
+ * Map 64Mb of 128MB NOR flash memory. Since highest
+ * line of address of NOR flash memory are set by
+ * FPGA, memory are divided into two pages equal to
+ * 64MB. One of the pages can be accessed at once.
+ */
+ reg = <0 0 0x04000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ };
+
+ nand at 2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,elbc-fcm-nand";
+ reg = <0x2 0x0 0x40000>;
+
+ partition at 0 {
+ label = "NAND U-Boot Image";
+ reg = <0x0 0x02000000>;
+ read-only;
+ };
+
+ partition at 2000000 {
+ label = "NAND Root File System";
+ reg = <0x02000000 0x10000000>;
+ };
+
+ partition at 12000000 {
+ label = "NAND Compressed RFS Image";
+ reg = <0x12000000 0x08000000>;
+ };
+
+ partition at 1a000000 {
+ label = "NAND Linux Kernel Image";
+ reg = <0x1a000000 0x04000000>;
+ };
+
+ partition at 1e000000 {
+ label = "NAND DTB Image";
+ reg = <0x1e000000 0x01000000>;
+ };
+
+ partition at 1f000000 {
+ label = "NAND Writable User area";
+ reg = <0x1f000000 0x21000000>;
+ };
+ };
+
+ board-control at 3,0 {
+ compatible = "fsl,p5020ds-fpga", "fsl,fpga-ngpixis";
+ reg = <3 0 0x30>;
+ };
+ };
+
+ pci0: pcie at ffe200000 {
+ reg = <0xf 0xfe200000 0 0x1000>;
+ ranges = <0x02000000 0 0x80000000 0x0 0x80000000 0x0 0x10000000
+ 0x01000000 0 0x00000000 0x0 0xff000000 0x0 0x00010000>;
+ pcie at 0 {
+ ranges = <0x02000000 0 0x80000000
+ 0x02000000 0 0x80000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0xff000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie at ffe201000 {
+ reg = <0xf 0xfe201000 0 0x1000>;
+ ranges = <0x02000000 0x0 0x90000000 0x0 0x90000000 0x0 0x10000000
+ 0x01000000 0x0 0x00000000 0x0 0xff010000 0x0 0x00010000>;
+ pcie at 0 {
+ ranges = <0x02000000 0 0x90000000
+ 0x02000000 0 0x90000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0xff010000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie at ffe202000 {
+ reg = <0xf 0xfe202000 0 0x1000>;
+ ranges = <0x02000000 0 0xa0000000 0x0 0xa0000000 0 0x10000000
+ 0x01000000 0 0x00000000 0x0 0xff020000 0 0x00010000>;
+ pcie at 0 {
+ ranges = <0x02000000 0 0xa0000000
+ 0x02000000 0 0xa0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0xff020000
+ 0 0x00010000>;
+ };
+ };
+
+ pci3: pcie at ffe203000 {
+ reg = <0xf 0xfe203000 0 0x1000>;
+ ranges = <0x02000000 0 0xb0000000 0x0 0xb0000000 0 0x08000000
+ 0x01000000 0 0x00000000 0x0 0xff030000 0 0x00010000>;
+ pcie at 0 {
+ ranges = <0x02000000 0 0xb0000000
+ 0x02000000 0 0xb0000000
+ 0 0x08000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0xff030000
+ 0 0x00010000>;
+ };
+ };
+
+ fsl,dpaa {
+ compatible = "fsl,p5020-dpaa", "fsl,dpaa";
+
+ ethernet at 0 {
+ compatible = "fsl,p5020-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet0>;
+ status = "okay";
+ };
+ ethernet at 1 {
+ compatible = "fsl,p5020-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet1>;
+ status = "disabled";
+ };
+ ethernet at 2 {
+ compatible = "fsl,p5020-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet2>;
+ status = "disabled";
+ };
+ ethernet at 3 {
+ compatible = "fsl,p5020-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet3>;
+ status = "disabled";
+ };
+ ethernet at 4 {
+ compatible = "fsl,p5020-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet4>;
+ status = "okay";
+ };
+ ethernet at 5 {
+ compatible = "fsl,p5020-dpa-ethernet", "fsl,dpa-ethernet";
+ fsl,qman-channel = <&qpool1>;
+ fsl,fman-mac = <&enet5>;
+ status = "disabled";
+ };
+ };
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ };
+};
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/fdt/dts/p5020si.dtsi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/boot/fdt/dts/p5020si.dtsi Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,1389 @@
+/*
+ * P5020 Silicon Device Tree Source
+ *
+ * Copyright 2010-2011 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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: head/sys/boot/fdt/dts/p5020si.dtsi 236024 2012-05-25 20:43:38Z raj $ */
+
+/dts-v1/;
+
+/ {
+ compatible = "fsl,P5020";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ ccsr = &soc;
+ dcsr = &dcsr;
+
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
+ ethernet5 = &enet5;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ serial2 = &serial2;
+ serial3 = &serial3;
+ pci0 = &pci0;
+ pci1 = &pci1;
+ pci2 = &pci2;
+ pci3 = &pci3;
+ usb0 = &usb0;
+ usb1 = &usb1;
+ dma0 = &dma0;
+ dma1 = &dma1;
+ bman = &bman;
+ qman = &qman;
+ pme = &pme;
+ rman = &rman;
+ sdhc = &sdhc;
+ msi0 = &msi0;
+ msi1 = &msi1;
+ msi2 = &msi2;
+
+ crypto = &crypto;
+ sec_jr0 = &sec_jr0;
+ sec_jr1 = &sec_jr1;
+ sec_jr2 = &sec_jr2;
+ sec_jr3 = &sec_jr3;
+ rtic_a = &rtic_a;
+ rtic_b = &rtic_b;
+ rtic_c = &rtic_c;
+ rtic_d = &rtic_d;
+ sec_mon = &sec_mon;
+
+ raideng = &raideng;
+ raideng_jr0 = &raideng_jr0;
+ raideng_jr1 = &raideng_jr1;
+ raideng_jr2 = &raideng_jr2;
+ raideng_jr3 = &raideng_jr3;
+
+ fman0 = &fman0;
+ fman0_oh0 = &fman0_oh0;
+ fman0_oh1 = &fman0_oh1;
+ fman0_oh2 = &fman0_oh2;
+ fman0_oh3 = &fman0_oh3;
+ fman0_oh4 = &fman0_oh4;
+ fman0_oh5 = &fman0_oh5;
+ fman0_oh6 = &fman0_oh6;
+ fman0_rx0 = &fman0_rx0;
+ fman0_rx1 = &fman0_rx1;
+ fman0_rx2 = &fman0_rx2;
+ fman0_rx3 = &fman0_rx3;
+ fman0_rx4 = &fman0_rx4;
+ fman0_rx5 = &fman0_rx5;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: PowerPC,e5500 at 0 {
+ device_type = "cpu";
+ reg = <0>;
+ bus-frequency = <799999998>;
+ next-level-cache = <&L2_0>;
+ L2_0: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ cpu1: PowerPC,e5500 at 1 {
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2_1>;
+ L2_1: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ };
+
+ dcsr: dcsr at f00000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,dcsr", "simple-bus";
+
+ dcsr-epu at 0 {
+ compatible = "fsl,dcsr-epu";
+ interrupts = <52 2 0 0
+ 84 2 0 0
+ 85 2 0 0>;
+ interrupt-parent = <&mpic>;
+ reg = <0x0 0x1000>;
+ };
+ dcsr-npc {
+ compatible = "fsl,dcsr-npc";
+ reg = <0x1000 0x1000 0x1000000 0x8000>;
+ };
+ dcsr-nxc at 2000 {
+ compatible = "fsl,dcsr-nxc";
+ reg = <0x2000 0x1000>;
+ };
+ dcsr-corenet {
+ compatible = "fsl,dcsr-corenet";
+ reg = <0x8000 0x1000 0xB0000 0x1000>;
+ };
+ dcsr-dpaa at 9000 {
+ compatible = "fsl,p5020-dcsr-dpaa", "fsl,dcsr-dpaa";
+ reg = <0x9000 0x1000>;
+ };
+ dcsr-ocn at 11000 {
+ compatible = "fsl,p5020-dcsr-ocn", "fsl,dcsr-ocn";
+ reg = <0x11000 0x1000>;
+ };
+ dcsr-ddr at 12000 {
+ compatible = "fsl,dcsr-ddr";
+ dev-handle = <&ddr1>;
+ reg = <0x12000 0x1000>;
+ };
+ dcsr-ddr at 13000 {
+ compatible = "fsl,dcsr-ddr";
+ dev-handle = <&ddr2>;
+ reg = <0x13000 0x1000>;
+ };
+ dcsr-nal at 18000 {
+ compatible = "fsl,p5020-dcsr-nal", "fsl,dcsr-nal";
+ reg = <0x18000 0x1000>;
+ };
+ dcsr-rcpm at 22000 {
+ compatible = "fsl,p5020-dcsr-rcpm", "fsl,dcsr-rcpm";
+ reg = <0x22000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy at 40000 {
+ compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu0>;
+ reg = <0x40000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy at 41000 {
+ compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu1>;
+ reg = <0x41000 0x1000>;
+ };
+ };
+
+ bman-portals at ff4000000 {
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ compatible = "bman-portals";
+ ranges = <0x0 0xf 0xfde00000 0x200000>;
+ bman-portal at 0 {
+ cell-index = <0x0>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0x0 0x4000 0x100000 0x1000>;
+ interrupts = <105 2 0 0>;
+ };
+ bman-portal at 4000 {
+ cell-index = <0x1>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0x4000 0x4000 0x101000 0x1000>;
+ interrupts = <107 2 0 0>;
+ };
+ bman-portal at 8000 {
+ cell-index = <2>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0x8000 0x4000 0x102000 0x1000>;
+ interrupts = <109 2 0 0>;
+ };
+ bman-portal at c000 {
+ cell-index = <0x3>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0xc000 0x4000 0x103000 0x1000>;
+ interrupts = <111 2 0 0>;
+ };
+ bman-portal at 10000 {
+ cell-index = <0x4>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0x10000 0x4000 0x104000 0x1000>;
+ interrupts = <113 2 0 0>;
+ };
+ bman-portal at 14000 {
+ cell-index = <0x5>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0x14000 0x4000 0x105000 0x1000>;
+ interrupts = <115 2 0 0>;
+ };
+ bman-portal at 18000 {
+ cell-index = <0x6>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0x18000 0x4000 0x106000 0x1000>;
+ interrupts = <117 2 0 0>;
+ };
+ bman-portal at 1c000 {
+ cell-index = <0x7>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0x1c000 0x4000 0x107000 0x1000>;
+ interrupts = <119 2 0 0>;
+ };
+ bman-portal at 20000 {
+ cell-index = <0x8>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0x20000 0x4000 0x108000 0x1000>;
+ interrupts = <121 2 0 0>;
+ };
+ bman-portal at 24000 {
+ cell-index = <0x9>;
+ compatible = "fsl,p5020-bman-portal", "fsl,bman-portal";
+ reg = <0x24000 0x4000 0x109000 0x1000>;
+ interrupts = <123 2 0 0>;
+ };
+
+ buffer-pool at 0 {
+ compatible = "fsl,p5020-bpool", "fsl,bpool";
+ fsl,bpid = <0>;
+ fsl,bpool-cfg = <0 0x100 0 1 0 0x100>;
+ };
+ };
+
+ qman-portals at ff4200000 {
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ compatible = "qman-portals";
+ ranges = <0x0 0xf 0xfdc00000 0x200000>;
+ qportal0: qman-portal at 0 {
+ cell-index = <0x0>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0x0 0x4000 0x100000 0x1000>;
+ interrupts = <104 0x2 0 0>;
+ fsl,qman-channel-id = <0x0>;
+ };
+
+ qportal1: qman-portal at 4000 {
+ cell-index = <0x1>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0x4000 0x4000 0x101000 0x1000>;
+ interrupts = <106 0x2 0 0>;
+ fsl,qman-channel-id = <0x1>;
+ };
+
+ qportal2: qman-portal at 8000 {
+ cell-index = <0x2>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0x8000 0x4000 0x102000 0x1000>;
+ interrupts = <108 0x2 0 0>;
+ fsl,qman-channel-id = <0x2>;
+ };
+
+ qportal3: qman-portal at c000 {
+ cell-index = <0x3>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0xc000 0x4000 0x103000 0x1000>;
+ interrupts = <110 0x2 0 0>;
+ fsl,qman-channel-id = <0x3>;
+ };
+
+ qportal4: qman-portal at 10000 {
+ cell-index = <0x4>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0x10000 0x4000 0x104000 0x1000>;
+ interrupts = <112 0x2 0 0>;
+ fsl,qman-channel-id = <0x4>;
+ };
+
+ qportal5: qman-portal at 14000 {
+ cell-index = <0x5>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0x14000 0x4000 0x105000 0x1000>;
+ interrupts = <114 0x2 0 0>;
+ fsl,qman-channel-id = <0x5>;
+ };
+
+ qportal6: qman-portal at 18000 {
+ cell-index = <0x6>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0x18000 0x4000 0x106000 0x1000>;
+ interrupts = <116 0x2 0 0>;
+ fsl,qman-channel-id = <0x6>;
+ };
+
+ qportal7: qman-portal at 1c000 {
+ cell-index = <0x7>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0x1c000 0x4000 0x107000 0x1000>;
+ interrupts = <118 0x2 0 0>;
+ fsl,qman-channel-id = <0x7>;
+ };
+
+ qportal8: qman-portal at 20000 {
+ cell-index = <0x8>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0x20000 0x4000 0x108000 0x1000>;
+ interrupts = <120 0x2 0 0>;
+ fsl,qman-channel-id = <0x8>;
+ };
+
+ qportal9: qman-portal at 24000 {
+ cell-index = <0x9>;
+ compatible = "fsl,p5020-qman-portal", "fsl,qman-portal";
+ reg = <0x24000 0x4000 0x109000 0x1000>;
+ interrupts = <122 0x2 0 0>;
+ fsl,qman-channel-id = <0x9>;
+ };
+
+ qpool1: qman-pool at 1 {
+ cell-index = <1>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x21>;
+ };
+
+ qpool2: qman-pool at 2 {
+ cell-index = <2>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x22>;
+ };
+
+ qpool3: qman-pool at 3 {
+ cell-index = <3>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x23>;
+ };
+
+ qpool4: qman-pool at 4 {
+ cell-index = <4>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x24>;
+ };
+
+ qpool5: qman-pool at 5 {
+ cell-index = <5>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x25>;
+ };
+
+ qpool6: qman-pool at 6 {
+ cell-index = <6>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x26>;
+ };
+
+ qpool7: qman-pool at 7 {
+ cell-index = <7>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x27>;
+ };
+
+ qpool8: qman-pool at 8 {
+ cell-index = <8>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x28>;
+ };
+
+ qpool9: qman-pool at 9 {
+ cell-index = <9>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x29>;
+ };
+
+ qpool10: qman-pool at 10 {
+ cell-index = <10>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2a>;
+ };
+
+ qpool11: qman-pool at 11 {
+ cell-index = <11>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2b>;
+ };
+
+ qpool12: qman-pool at 12 {
+ cell-index = <12>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2c>;
+ };
+
+ qpool13: qman-pool at 13 {
+ cell-index = <13>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2d>;
+ };
+
+ qpool14: qman-pool at 14 {
+ cell-index = <14>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2e>;
+ };
+
+ qpool15: qman-pool at 15 {
+ cell-index = <15>;
+ compatible = "fsl,p5020-qman-pool-channel", "fsl,qman-pool-channel";
+ fsl,qman-channel-id = <0x2f>;
+ };
+ };
+
+ soc: soc at ffe000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "simple-bus";
+
+ bus-frequency = <0>; // Filled out by kernel.
+
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+
+ soc-sram-error {
+ compatible = "fsl,soc-sram-error";
+ interrupts = <16 2 1 29>;
+ };
+
+ corenet-law at 0 {
+ compatible = "fsl,corenet-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <32>;
+ };
+
+ ddr1: memory-controller at 8000 {
+ compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
+ reg = <0x8000 0x1000>;
+ interrupts = <16 2 1 23>;
+ };
+
+ ddr2: memory-controller at 9000 {
+ compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
+ reg = <0x9000 0x1000>;
+ interrupts = <16 2 1 22>;
+ };
+
+ cpc: l3-cache-controller at 10000 {
+ compatible = "fsl,p5020-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache";
+ reg = <0x10000 0x1000
+ 0x11000 0x1000>;
+ interrupts = <16 2 1 27
+ 16 2 1 26>;
+ };
+
+ corenet-cf at 18000 {
+ compatible = "fsl,corenet-cf";
+ reg = <0x18000 0x1000>;
+ interrupts = <16 2 1 31>;
+ fsl,ccf-num-csdids = <32>;
+ fsl,ccf-num-snoopids = <32>;
+ };
+
+ iommu at 20000 {
+ compatible = "fsl,pamu-v1.0", "fsl,pamu";
+ reg = <0x20000 0x4000>;
+ interrupts = <
+ 24 2 0 0
+ 16 2 1 30>;
+ };
+
+ mpic: pic at 40000 {
+ clock-frequency = <0>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <4>;
+ reg = <0x40000 0x40000>;
+ compatible = "fsl,mpic", "chrp,open-pic";
+ device_type = "open-pic";
+ };
+
+ msi0: msi at 41600 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41600 0x200>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe0 0 0 0
+ 0xe1 0 0 0
+ 0xe2 0 0 0
+ 0xe3 0 0 0
+ 0xe4 0 0 0
+ 0xe5 0 0 0
+ 0xe6 0 0 0
+ 0xe7 0 0 0>;
+ };
+
+ msi1: msi at 41800 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41800 0x200>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe8 0 0 0
+ 0xe9 0 0 0
+ 0xea 0 0 0
+ 0xeb 0 0 0
+ 0xec 0 0 0
+ 0xed 0 0 0
+ 0xee 0 0 0
+ 0xef 0 0 0>;
+ };
+
+ msi2: msi at 41a00 {
+ compatible = "fsl,mpic-msi";
+ reg = <0x41a00 0x200>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xf0 0 0 0
+ 0xf1 0 0 0
+ 0xf2 0 0 0
+ 0xf3 0 0 0
+ 0xf4 0 0 0
+ 0xf5 0 0 0
+ 0xf6 0 0 0
+ 0xf7 0 0 0>;
+ };
+
+ guts: global-utilities at e0000 {
+ compatible = "fsl,qoriq-device-config-1.0";
+ reg = <0xe0000 0xe00>;
+ fsl,has-rstcr;
+ #sleep-cells = <1>;
+ fsl,liodn-bits = <12>;
+ };
+
+ pins: global-utilities at e0e00 {
+ compatible = "fsl,qoriq-pin-control-1.0";
+ reg = <0xe0e00 0x200>;
+ #sleep-cells = <2>;
+ };
+
+ clockgen: global-utilities at e1000 {
+ compatible = "fsl,p5020-clockgen", "fsl,qoriq-clockgen-1.0";
+ reg = <0xe1000 0x1000>;
+ clock-frequency = <0>;
+ };
+
+ rcpm: global-utilities at e2000 {
+ compatible = "fsl,qoriq-rcpm-1.0";
+ reg = <0xe2000 0x1000>;
+ #sleep-cells = <1>;
+ };
+
+ sfp: sfp at e8000 {
+ compatible = "fsl,p5020-sfp", "fsl,qoriq-sfp-1.0";
+ reg = <0xe8000 0x1000>;
+ };
+
+ serdes: serdes at ea000 {
+ compatible = "fsl,p5020-serdes";
+ reg = <0xea000 0x1000>;
+ };
+
+ dma0: dma at 100300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p5020-dma", "fsl,eloplus-dma";
+ reg = <0x100300 0x4>;
+ ranges = <0x0 0x100100 0x200>;
+ cell-index = <0>;
+ dma-channel at 0 {
+ compatible = "fsl,p5020-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupts = <28 2 0 0>;
+ };
+ dma-channel at 80 {
+ compatible = "fsl,p5020-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupts = <29 2 0 0>;
+ };
+ dma-channel at 100 {
+ compatible = "fsl,p5020-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupts = <30 2 0 0>;
+ };
+ dma-channel at 180 {
+ compatible = "fsl,p5020-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupts = <31 2 0 0>;
+ };
+ };
+
+ dma1: dma at 101300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p5020-dma", "fsl,eloplus-dma";
+ reg = <0x101300 0x4>;
+ ranges = <0x0 0x101100 0x200>;
+ cell-index = <1>;
+ dma-channel at 0 {
+ compatible = "fsl,p5020-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupts = <32 2 0 0>;
+ };
+ dma-channel at 80 {
+ compatible = "fsl,p5020-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupts = <33 2 0 0>;
+ };
+ dma-channel at 100 {
+ compatible = "fsl,p5020-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupts = <34 2 0 0>;
+ };
+ dma-channel at 180 {
+ compatible = "fsl,p5020-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupts = <35 2 0 0>;
+ };
+ };
+
+ spi at 110000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,p5020-espi", "fsl,mpc8536-espi";
+ reg = <0x110000 0x1000>;
+ interrupts = <53 0x2 0 0>;
+ fsl,espi-num-chipselects = <4>;
+ };
+
+ sdhc: sdhc at 114000 {
+ compatible = "fsl,p5020-esdhc", "fsl,esdhc";
+ reg = <0x114000 0x1000>;
+ interrupts = <48 2 0 0>;
+ sdhci,auto-cmd12;
+ clock-frequency = <0>;
+ };
+
+ i2c at 118000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x118000 0x100>;
+ interrupts = <38 2 0 0>;
+ dfsrr;
+ };
+
+ i2c at 118100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ compatible = "fsl-i2c";
+ reg = <0x118100 0x100>;
+ interrupts = <38 2 0 0>;
+ dfsrr;
+ };
+
+ i2c at 119000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <2>;
+ compatible = "fsl-i2c";
+ reg = <0x119000 0x100>;
+ interrupts = <39 2 0 0>;
+ dfsrr;
+ };
+
+ i2c at 119100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <3>;
+ compatible = "fsl-i2c";
+ reg = <0x119100 0x100>;
+ interrupts = <39 2 0 0>;
+ dfsrr;
+ };
+
+ serial0: serial at 11c500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11c500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <36 2 0 0>;
+ };
+
+ serial1: serial at 11c600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11c600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <36 2 0 0>;
+ };
+
+ serial2: serial at 11d500 {
+ cell-index = <2>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11d500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <37 2 0 0>;
+ };
+
+ serial3: serial at 11d600 {
+ cell-index = <3>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x11d600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <37 2 0 0>;
+ };
+
+ gpio0: gpio at 130000 {
+ compatible = "fsl,p5020-gpio", "fsl,qoriq-gpio";
+ reg = <0x130000 0x1000>;
+ interrupts = <55 2 0 0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ };
+
+ rman: rman at 1e0000 {
+ compatible = "fsl,rman";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x1e0000 0x20000>;
+ reg = <0x1e0000 0x20000>;
+ interrupts = <16 2 1 11>; /* err_irq */
+ fsl,qman-channels-id = <0x62 0x63>;
+
+ inbound-block at 0 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x0 0x800>;
+ };
+ global-cfg at b00 {
+ compatible = "fsl,rman-global-cfg";
+ reg = <0xb00 0x500>;
+ };
+ inbound-block at 1000 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x1000 0x800>;
+ };
+ inbound-block at 2000 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x2000 0x800>;
+ };
+ inbound-block at 3000 {
+ compatible = "fsl,rman-inbound-block";
+ reg = <0x3000 0x800>;
+ };
+ };
+
+ usb0: usb at 210000 {
+ compatible = "fsl,p5020-usb2-mph",
+ "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph";
+ reg = <0x210000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <44 0x2 0 0>;
+ phy_type = "utmi";
+ port0;
+ };
+
+ usb1: usb at 211000 {
+ compatible = "fsl,p5020-usb2-dr",
+ "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr";
+ reg = <0x211000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <45 0x2 0 0>;
+ dr_mode = "host";
+ phy_type = "utmi";
+ };
+
+ sata at 220000 {
+ compatible = "fsl,p5020-sata", "fsl,pq-sata-v2";
+ reg = <0x220000 0x1000>;
+ interrupts = <68 0x2 0 0>;
+ };
+
+ sata at 221000 {
+ compatible = "fsl,p5020-sata", "fsl,pq-sata-v2";
+ reg = <0x221000 0x1000>;
+ interrupts = <69 0x2 0 0>;
+ };
+
+ crypto: crypto at 300000 {
+ compatible = "fsl,sec-v4.2", "fsl,sec-v4.0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x300000 0x10000>;
+ ranges = <0 0x300000 0x10000>;
+ interrupts = <92 2 0 0>;
+
+ sec_jr0: jr at 1000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x1000 0x1000>;
+ interrupts = <88 2 0 0>;
+ };
+
+ sec_jr1: jr at 2000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x2000 0x1000>;
+ interrupts = <89 2 0 0>;
+ };
+
+ sec_jr2: jr at 3000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x3000 0x1000>;
+ interrupts = <90 2 0 0>;
+ };
+
+ sec_jr3: jr at 4000 {
+ compatible = "fsl,sec-v4.2-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x4000 0x1000>;
+ interrupts = <91 2 0 0>;
+ };
+
+ rtic at 6000 {
+ compatible = "fsl,sec-v4.2-rtic",
+ "fsl,sec-v4.0-rtic";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x6000 0x100>;
+ ranges = <0x0 0x6100 0xe00>;
+
+ rtic_a: rtic-a at 0 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x00 0x20 0x100 0x80>;
+ };
+
+ rtic_b: rtic-b at 20 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x20 0x20 0x200 0x80>;
+ };
+
+ rtic_c: rtic-c at 40 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x40 0x20 0x300 0x80>;
+ };
+
+ rtic_d: rtic-d at 60 {
+ compatible = "fsl,sec-v4.2-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x60 0x20 0x500 0x80>;
+ };
+ };
+ };
+
+ sec_mon: sec_mon at 314000 {
+ compatible = "fsl,sec-v4.2-mon", "fsl,sec-v4.0-mon";
+ reg = <0x314000 0x1000>;
+ interrupts = <93 2 0 0>;
+ };
+
+ raideng: raideng at 320000 {
+ compatible = "fsl,raideng-v1.0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x320000 0x10000>;
+ ranges = <0 0x320000 0x10000>;
+
+ raideng_jq0 at 1000 {
+ compatible = "fsl,raideng-v1.0-job-queue";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x1000 0x1000>;
+ ranges = <0x0 0x1000 0x1000>;
+
+ raideng_jr0: jr at 0 {
+ compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-hp-ring";
+ reg = <0x0 0x400>;
+ interrupts = <139 2 0 0>;
+ interrupt-parent = <&mpic>;
+ };
+
+ raideng_jr1: jr at 400 {
+ compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-lp-ring";
+ reg = <0x400 0x400>;
+ interrupts = <140 2 0 0>;
+ interrupt-parent = <&mpic>;
+ };
+ };
+
+ raideng_jq1 at 2000 {
+ compatible = "fsl,raideng-v1.0-job-queue";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x2000 0x1000>;
+ ranges = <0x0 0x2000 0x1000>;
+
+ raideng_jr2: jr at 0 {
+ compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-hp-ring";
+ reg = <0x0 0x400>;
+ interrupts = <141 2 0 0>;
+ interrupt-parent = <&mpic>;
+ };
+
+ raideng_jr3: jr at 400 {
+ compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-lp-ring";
+ reg = <0x400 0x400>;
+ interrupts = <142 2 0 0>;
+ interrupt-parent = <&mpic>;
+ };
+ };
+ };
+
+ pme: pme at 316000 {
+ compatible = "fsl,pme";
+ reg = <0x316000 0x10000>;
+ /* fsl,pme-pdsr = <0x0 0x23000000 0x0 0x01000000>; */
+ /* fsl,pme-sre = <0x0 0x24000000 0x0 0x00a00000>; */
+ interrupts = <16 2 1 5>;
+ };
+
+ qman: qman at 318000 {
+ compatible = "fsl,p5020-qman", "fsl,qman";
+ reg = <0x318000 0x1000>;
+ interrupts = <16 2 1 3>;
+ /* Commented out, use default allocation */
+ /* fsl,qman-fqd = <0x0 0x20000000 0x0 0x01000000>; */
+ /* fsl,qman-pfdr = <0x0 0x21000000 0x0 0x01000000>; */
+ };
+
+ bman: bman at 31a000 {
+ compatible = "fsl,p5020-bman", "fsl,bman";
+ reg = <0x31a000 0x1000>;
+ interrupts = <16 2 1 2>;
+ /* Same as fsl,qman-*, use default allocation */
+ /* fsl,bman-fbpr = <0x0 0x22000000 0x0 0x01000000>; */
+ };
+
+ fman0: fman at 400000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ compatible = "fsl,p5020-fman", "fsl,fman", "simple-bus";
+ ranges = <0 0x400000 0x100000>;
+ reg = <0x400000 0x100000>;
+ clock-frequency = <0>;
+ interrupts = <
+ 96 2 0 0
+ 16 2 1 1>;
+
+ cc at 0 {
+ compatible = "fsl,p5020-fman-cc", "fsl,fman-cc";
+ };
+
+ parser at c7000 {
+ compatible = "fsl,p5020-fman-parser", "fsl,fman-parser";
+ reg = <0xc7000 0x1000>;
+ };
+
+ keygen at c1000 {
+ compatible = "fsl,p5020-fman-keygen", "fsl,fman-keygen";
+ reg = <0xc1000 0x1000>;
+ };
+
+ policer at c0000 {
+ compatible = "fsl,p5020-fman-policer", "fsl,fman-policer";
+ reg = <0xc0000 0x1000>;
+ };
+
+ muram at 0 {
+ compatible = "fsl,p5020-fman-muram", "fsl,fman-muram";
+ reg = <0x0 0x28000>;
+ };
+
+ bmi at 80000 {
+ compatible = "fsl,p5020-fman-bmi", "fsl,fman-bmi";
+ reg = <0x80000 0x400>;
+ };
+
+ qmi at 80400 {
+ compatible = "fsl,p5020-fman-qmi", "fsl,fman-qmi";
+ reg = <0x80400 0x400>;
+ };
+
+ fman0_rx0: port at 88000 {
+ cell-index = <0>;
+ compatible = "fsl,p5020-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x88000 0x1000>;
+ };
+ fman0_rx1: port at 89000 {
+ cell-index = <1>;
+ compatible = "fsl,p5020-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x89000 0x1000>;
+ };
+ fman0_rx2: port at 8a000 {
+ cell-index = <2>;
+ compatible = "fsl,p5020-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x8a000 0x1000>;
+ };
+ fman0_rx3: port at 8b000 {
+ cell-index = <3>;
+ compatible = "fsl,p5020-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x8b000 0x1000>;
+ };
+ fman0_rx4: port at 8c000 {
+ cell-index = <4>;
+ compatible = "fsl,p5020-fman-port-1g-rx", "fsl,fman-port-1g-rx";
+ reg = <0x8c000 0x1000>;
+ };
+ fman0_rx5: port at 90000 {
+ cell-index = <0>;
+ compatible = "fsl,p5020-fman-port-10g-rx", "fsl,fman-port-10g-rx";
+ reg = <0x90000 0x1000>;
+ };
+
+ fman0_tx5: port at b0000 {
+ cell-index = <0>;
+ compatible = "fsl,p5020-fman-port-10g-tx", "fsl,fman-port-10g-tx";
+ reg = <0xb0000 0x1000>;
+ fsl,qman-channel-id = <0x40>;
+ };
+ fman0_tx0: port at a8000 {
+ cell-index = <0>;
+ compatible = "fsl,p5020-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xa8000 0x1000>;
+ fsl,qman-channel-id = <0x41>;
+ };
+ fman0_tx1: port at a9000 {
+ cell-index = <1>;
+ compatible = "fsl,p5020-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xa9000 0x1000>;
+ fsl,qman-channel-id = <0x42>;
+ };
+ fman0_tx2: port at aa000 {
+ cell-index = <2>;
+ compatible = "fsl,p5020-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xaa000 0x1000>;
+ fsl,qman-channel-id = <0x43>;
+ };
+ fman0_tx3: port at ab000 {
+ cell-index = <3>;
+ compatible = "fsl,p5020-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xab000 0x1000>;
+ fsl,qman-channel-id = <0x44>;
+ };
+ fman0_tx4: port at ac000 {
+ cell-index = <4>;
+ compatible = "fsl,p5020-fman-port-1g-tx", "fsl,fman-port-1g-tx";
+ reg = <0xac000 0x1000>;
+ fsl,qman-channel-id = <0x45>;
+ };
+
+ fman0_oh0: port at 81000 {
+ cell-index = <0>;
+ compatible = "fsl,p5020-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x81000 0x1000>;
+ fsl,qman-channel-id = <0x46>;
+ };
+ fman0_oh1: port at 82000 {
+ cell-index = <1>;
+ compatible = "fsl,p5020-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x82000 0x1000>;
+ fsl,qman-channel-id = <0x47>;
+ };
+ fman0_oh2: port at 83000 {
+ cell-index = <2>;
+ compatible = "fsl,p5020-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x83000 0x1000>;
+ fsl,qman-channel-id = <0x48>;
+ };
+ fman0_oh3: port at 84000 {
+ cell-index = <3>;
+ compatible = "fsl,p5020-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x84000 0x1000>;
+ fsl,qman-channel-id = <0x49>;
+ };
+ fman0_oh4: port at 85000 {
+ cell-index = <4>;
+ compatible = "fsl,p5020-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x85000 0x1000>;
+ fsl,qman-channel-id = <0x4a>;
+ };
+ fman0_oh5: port at 86000 {
+ cell-index = <5>;
+ compatible = "fsl,p5020-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x86000 0x1000>;
+ fsl,qman-channel-id = <0x4b>;
+ };
+ fman0_oh6: port at 87000 {
+ cell-index = <6>;
+ compatible = "fsl,p5020-fman-port-oh", "fsl,fman-port-oh";
+ reg = <0x87000 0x1000>;
+ };
+
+ enet0: ethernet at e0000 {
+ cell-index = <0>;
+ compatible = "fsl,p5020-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe0000 0x1000>;
+ fsl,port-handles = <&fman0_rx0 &fman0_tx0>;
+ ptimer-handle = <&ptp_timer0>;
+ };
+
+ mdio0: mdio at e1120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-mdio";
+ reg = <0xe1120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet1: ethernet at e2000 {
+ cell-index = <1>;
+ compatible = "fsl,p5020-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe2000 0x1000>;
+ fsl,port-handles = <&fman0_rx1 &fman0_tx1>;
+ ptimer-handle = <&ptp_timer0>;
+ };
+
+ mdio at e3120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe3120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet2: ethernet at e4000 {
+ cell-index = <2>;
+ compatible = "fsl,p5020-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe4000 0x1000>;
+ fsl,port-handles = <&fman0_rx2 &fman0_tx2>;
+ ptimer-handle = <&ptp_timer0>;
+ };
+
+ mdio at e5120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe5120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet3: ethernet at e6000 {
+ cell-index = <3>;
+ compatible = "fsl,p5020-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe6000 0x1000>;
+ fsl,port-handles = <&fman0_rx3 &fman0_tx3>;
+ ptimer-handle = <&ptp_timer0>;
+ };
+
+ mdio at e7120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe7120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet4: ethernet at e8000 {
+ cell-index = <4>;
+ compatible = "fsl,p5020-fman-1g-mac", "fsl,fman-1g-mac";
+ reg = <0xe8000 0x1000>;
+ fsl,port-handles = <&fman0_rx4 &fman0_tx4>;
+ ptimer-handle = <&ptp_timer0>;
+ };
+
+ mdio at e9120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-tbi";
+ reg = <0xe9120 0xee0>;
+ interrupts = <100 1 0 0>;
+ };
+
+ enet5: ethernet at f0000 {
+ cell-index = <0>;
+ compatible = "fsl,p5020-fman-10g-mac", "fsl,fman-10g-mac";
+ reg = <0xf0000 0x1000>;
+ fsl,port-handles = <&fman0_rx5 &fman0_tx5>;
+ };
+
+ mdio at f1000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-xmdio";
+ reg = <0xf1000 0x1000>;
+ interrupts = <100 1 0 0>;
+ };
+
+ ptp_timer0: rtc at fe000 {
+ compatible = "fsl,fman-rtc";
+ reg = <0xfe000 0x1000>;
+ };
+ };
+ };
+
+ rapidio at ffe0c0000 {
+ compatible = "fsl,srio";
+ interrupts = <16 2 1 11>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ port1 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ cell-index = <1>;
+ };
+
+ port2 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ cell-index = <2>;
+ };
+ };
+
+ localbus at ffe124000 {
+ compatible = "fsl,p5020-rev1.0-elbc", "simple-bus", "fsl,elbc";
+ interrupts = <
+ 25 2 0 0
+ 16 2 1 19
+ >;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ };
+
+ pci0: pcie at ffe200000 {
+ compatible = "fsl,p5020-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "okay";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ cell-index = <0>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <0x1fca055>;
+ fsl,msi = <&msi0>;
+ interrupts = <16 2 1 15>;
+
+ pcie at 0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 15>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 40 1 0 0
+ 0000 0 0 2 &mpic 1 1 0 0
+ 0000 0 0 3 &mpic 2 1 0 0
+ 0000 0 0 4 &mpic 3 1 0 0
+ >;
+ };
+ };
+
+ pci1: pcie at ffe201000 {
+ compatible = "fsl,p5020-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "disabled";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ cell-index = <1>;
+ bus-range = <0 0xff>;
+ clock-frequency = <0x1fca055>;
+ fsl,msi = <&msi1>;
+ interrupts = <16 2 1 14>;
+ pcie at 0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 14>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 41 1 0 0
+ 0000 0 0 2 &mpic 5 1 0 0
+ 0000 0 0 3 &mpic 6 1 0 0
+ 0000 0 0 4 &mpic 7 1 0 0
+ >;
+ };
+ };
+
+ pci2: pcie at ffe202000 {
+ compatible = "fsl,p5020-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "okay";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ cell-index = <2>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <0x1fca055>;
+ fsl,msi = <&msi2>;
+ interrupts = <16 2 1 13>;
+ pcie at 0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 13>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 42 1 0 0
+ 0000 0 0 2 &mpic 9 1 0 0
+ 0000 0 0 3 &mpic 10 1 0 0
+ 0000 0 0 4 &mpic 11 1 0 0
+ >;
+ };
+ };
+
+ pci3: pcie at ffe203000 {
+ compatible = "fsl,p5020-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ status = "disabled";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ cell-index = <3>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <0x1fca055>;
+ fsl,msi = <&msi2>;
+ interrupts = <16 2 1 12>;
+ pcie at 0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 12>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 43 1 0 0
+ 0000 0 0 2 &mpic 0 1 0 0
+ 0000 0 0 3 &mpic 4 1 0 0
+ 0000 0 0 4 &mpic 8 1 0 0
+ >;
+ };
+ };
+};
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/fdt/dts/sheevaplug.dts
--- a/head/sys/boot/fdt/dts/sheevaplug.dts Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/fdt/dts/sheevaplug.dts Wed Jul 25 16:45:04 2012 +0300
@@ -28,7 +28,7 @@
*
* Marvell SheevaPlug Device Tree Source.
*
- * $FreeBSD: head/sys/boot/fdt/dts/sheevaplug.dts 227730 2011-11-19 16:30:06Z raj $
+ * $FreeBSD: head/sys/boot/fdt/dts/sheevaplug.dts 235778 2012-05-22 08:33:14Z gber $
*/
/dts-v1/;
@@ -71,48 +71,33 @@
reg = <0x0 0x20000000>; // 512M at 0x0
};
- localbus at f1000000 {
+ localbus at 0 {
#address-cells = <2>;
#size-cells = <1>;
compatible = "mrvl,lbc";
+ bank-count = <3>;
/* This reflects CPU decode windows setup. */
- ranges = <0x0 0x0f 0xf9300000 0x00100000
- 0x1 0x1e 0xfa000000 0x00100000
- 0x2 0x1d 0xfa100000 0x02000000
- 0x3 0x1b 0xfc100000 0x00000400>;
+ ranges = <0x0 0x2f 0xf9300000 0x00100000>;
- nor at 0,0 {
+ nand at 0,0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "cfi-flash";
+ compatible = "mrvl,nfc";
reg = <0x0 0x0 0x00100000>;
bank-width = <2>;
device-width = <1>;
- };
- led at 1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "led";
- reg = <0x1 0x0 0x00100000>;
- };
+ slice at 0 {
+ reg = <0x0 0x200000>;
+ label = "u-boot";
+ read-only;
+ };
- nor at 2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x2 0x0 0x02000000>;
- bank-width = <2>;
- device-width = <1>;
- };
-
- nand at 3,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- reg = <0x3 0x0 0x00100000>;
- bank-width = <2>;
- device-width = <1>;
+ slice at 200000 {
+ reg = <0x200000 0x1fe00000>;
+ label = "root";
+ };
};
};
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/fdt/fdt_loader_cmd.c
--- a/head/sys/boot/fdt/fdt_loader_cmd.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/fdt/fdt_loader_cmd.c Wed Jul 25 16:45:04 2012 +0300
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/boot/fdt/fdt_loader_cmd.c 233323 2012-03-22 20:34:26Z raj $");
+__FBSDID("$FreeBSD: head/sys/boot/fdt/fdt_loader_cmd.c 235529 2012-05-17 04:04:48Z kientzle $");
#include <stand.h>
#include <fdt.h>
@@ -57,11 +57,17 @@
#define STR(number) #number
#define STRINGIFY(number) STR(number)
-#define COPYOUT(s,d,l) archsw.arch_copyout((vm_offset_t)(s), d, l)
+#define COPYOUT(s,d,l) archsw.arch_copyout(s, d, l)
+#define COPYIN(s,d,l) archsw.arch_copyin(s, d, l)
#define FDT_STATIC_DTB_SYMBOL "fdt_static_dtb"
+/* Local copy of FDT */
static struct fdt_header *fdtp = NULL;
+/* Size of FDT blob */
+static size_t fdtp_size = 0;
+/* Location of FDT in kernel or module */
+static vm_offset_t fdtp_va = 0;
static int fdt_cmd_nyi(int argc, char *argv[]);
@@ -98,21 +104,19 @@
static char cwd[FDT_CWD_LEN] = "/";
static vm_offset_t
-fdt_find_static_dtb(void)
+fdt_find_static_dtb()
{
+ Elf_Dyn dyn;
Elf_Sym sym;
- vm_offset_t dyntab, esym;
+ vm_offset_t dyntab, esym, strtab, symtab, fdt_start;
uint64_t offs;
struct preloaded_file *kfp;
struct file_metadata *md;
- Elf_Sym *symtab;
- Elf_Dyn *dyn;
- char *strtab, *strp;
- int i, sym_count;
+ char *strp;
+ int sym_count;
- symtab = NULL;
- dyntab = esym = 0;
- strtab = strp = NULL;
+ symtab = strtab = dyntab = esym = 0;
+ strp = NULL;
offs = __elfN(relocation_offset);
@@ -123,28 +127,29 @@
md = file_findmetadata(kfp, MODINFOMD_ESYM);
if (md == NULL)
return (0);
- COPYOUT(md->md_data, &esym, sizeof(esym));
+ bcopy(md->md_data, &esym, sizeof(esym));
+ // esym is already offset
md = file_findmetadata(kfp, MODINFOMD_DYNAMIC);
if (md == NULL)
return (0);
- COPYOUT(md->md_data, &dyntab, sizeof(dyntab));
-
+ bcopy(md->md_data, &dyntab, sizeof(dyntab));
dyntab += offs;
/* Locate STRTAB and DYNTAB */
- for (dyn = (Elf_Dyn *)dyntab; dyn->d_tag != DT_NULL; dyn++) {
- if (dyn->d_tag == DT_STRTAB) {
- strtab = (char *)(uintptr_t)(dyn->d_un.d_ptr + offs);
- continue;
- } else if (dyn->d_tag == DT_SYMTAB) {
- symtab = (Elf_Sym *)(uintptr_t)
- (dyn->d_un.d_ptr + offs);
- continue;
+ for (;;) {
+ COPYOUT(dyntab, &dyn, sizeof(dyn));
+ if (dyn.d_tag == DT_STRTAB) {
+ strtab = (vm_offset_t)(dyn.d_un.d_ptr) + offs;
+ } else if (dyn.d_tag == DT_SYMTAB) {
+ symtab = (vm_offset_t)(dyn.d_un.d_ptr) + offs;
+ } else if (dyn.d_tag == DT_NULL) {
+ break;
}
+ dyntab += sizeof(dyn);
}
- if (symtab == NULL || strtab == NULL) {
+ if (symtab == 0 || strtab == 0) {
/*
* No symtab? No strtab? That should not happen here,
* and should have been verified during __elfN(loadimage).
@@ -153,7 +158,7 @@
return (0);
}
- sym_count = (int)((Elf_Sym *)esym - symtab) / sizeof(Elf_Sym);
+ sym_count = (int)(esym - symtab) / sizeof(Elf_Sym);
/*
* The most efficent way to find a symbol would be to calculate a
@@ -165,26 +170,27 @@
* we are eliminating symbols type of which is not STT_NOTYPE, or(and)
* those which binding attribute is not STB_GLOBAL.
*/
- for (i = 0; i < sym_count; i++) {
- COPYOUT(symtab + i, &sym, sizeof(sym));
+ fdt_start = 0;
+ while (sym_count > 0 && fdt_start == 0) {
+ COPYOUT(symtab, &sym, sizeof(sym));
+ symtab += sizeof(sym);
+ --sym_count;
if (ELF_ST_BIND(sym.st_info) != STB_GLOBAL ||
ELF_ST_TYPE(sym.st_info) != STT_NOTYPE)
continue;
-
- strp = strdupout((vm_offset_t)(strtab + sym.st_name));
- if (strcmp(strp, FDT_STATIC_DTB_SYMBOL) == 0) {
- /* Found a match ! */
- free(strp);
- return ((vm_offset_t)(sym.st_value + offs));
- }
+ strp = strdupout(strtab + sym.st_name);
+ if (strcmp(strp, FDT_STATIC_DTB_SYMBOL) == 0)
+ fdt_start = (vm_offset_t)sym.st_value + offs;
free(strp);
}
- return (0);
+ printf("fdt_start: 0x%08jX\n", (intmax_t)fdt_start);
+ return (fdt_start);
}
static int
fdt_setup_fdtp()
{
+ struct fdt_header header;
struct preloaded_file *bfp;
int err;
@@ -193,15 +199,26 @@
*/
bfp = file_findfile(NULL, "dtb");
if (bfp == NULL) {
- if ((fdtp = (struct fdt_header *)fdt_find_static_dtb()) == 0) {
+ if ((fdtp_va = fdt_find_static_dtb()) == 0) {
command_errmsg = "no device tree blob found!";
+ printf("%s\n", command_errmsg);
return (CMD_ERROR);
}
} else {
/* Dynamic blob has precedence over static. */
- fdtp = (struct fdt_header *)bfp->f_addr;
+ fdtp_va = bfp->f_addr;
}
+ COPYOUT(fdtp_va, &header, sizeof(header));
+ fdtp_size = fdt_totalsize(&header);
+ fdtp = malloc(fdtp_size);
+ if (fdtp == NULL) {
+ command_errmsg = "can't allocate memory for device tree copy";
+ printf("%s\n", command_errmsg);
+ return (CMD_ERROR);
+ }
+ COPYOUT(fdtp_va, fdtp, fdtp_size);
+
/*
* Validate the blob.
*/
@@ -317,6 +334,8 @@
/* We want to modify every subnode of /cpus */
o = fdt_path_offset(fdtp, "/cpus");
+ if (o < 0)
+ return;
/* maxo should contain offset of node next to /cpus */
depth = 0;
@@ -545,7 +564,7 @@
/*
* Locate the blob, fix it up and return its location.
*/
-void *
+vm_offset_t
fdt_fixup(void)
{
const char *env;
@@ -561,7 +580,7 @@
err = fdt_setup_fdtp();
if (err) {
sprintf(command_errbuf, "No valid device tree blob found!");
- return (NULL);
+ return (0);
}
/* Create /chosen node (if not exists) */
@@ -616,7 +635,9 @@
fdt_setprop(fdtp, chosen, "fixup-applied", NULL, 0);
success:
- return (fdtp);
+ /* Overwrite the FDT with the fixed version. */
+ COPYIN(fdtp, fdtp_va, fdtp_size);
+ return (fdtp_va);
}
int
@@ -634,7 +655,7 @@
/*
* Check if uboot env vars were parsed already. If not, do it now.
*/
- if (fdt_fixup() == NULL)
+ if (fdt_fixup() == 0)
return (CMD_ERROR);
/*
@@ -1151,6 +1172,8 @@
else
sprintf(command_errbuf,
"Could not add/modify property!\n");
+ } else {
+ COPYIN(fdtp, fdtp_va, fdtp_size);
}
return (rv);
}
@@ -1371,6 +1394,8 @@
if (rv) {
sprintf(command_errbuf, "could not delete node");
return (CMD_ERROR);
+ } else {
+ COPYIN(fdtp, fdtp_va, fdtp_size);
}
return (CMD_OK);
}
@@ -1401,6 +1426,8 @@
sprintf(command_errbuf,
"Could not add node!\n");
return (CMD_ERROR);
+ } else {
+ COPYIN(fdtp, fdtp_va, fdtp_size);
}
return (CMD_OK);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/forth/beastie.4th
--- a/head/sys/boot/forth/beastie.4th Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/forth/beastie.4th Wed Jul 25 16:45:04 2012 +0300
@@ -1,6 +1,6 @@
\ Copyright (c) 2003 Scott Long <scottl at freebsd.org>
\ Copyright (c) 2003 Aleksander Fafula <alex at fafula.com>
-\ Copyright (c) 2006-2011 Devin Teske <devinteske at hotmail.com>
+\ Copyright (c) 2006-2011 Devin Teske <dteske at FreeBSD.org>
\ All rights reserved.
\
\ Redistribution and use in source and binary forms, with or without
@@ -24,7 +24,7 @@
\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
\ SUCH DAMAGE.
\
-\ $FreeBSD: head/sys/boot/forth/beastie.4th 222417 2011-05-28 08:50:38Z julian $
+\ $FreeBSD: head/sys/boot/forth/beastie.4th 238431 2012-07-14 01:45:35Z dteske $
marker task-beastie.4th
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/forth/beastie.4th.8
--- a/head/sys/boot/forth/beastie.4th.8 Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/forth/beastie.4th.8 Wed Jul 25 16:45:04 2012 +0300
@@ -22,14 +22,14 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD: head/sys/boot/forth/beastie.4th.8 222417 2011-05-28 08:50:38Z julian $
+.\" $FreeBSD: head/sys/boot/forth/beastie.4th.8 238431 2012-07-14 01:45:35Z dteske $
.\"
.Dd May 16, 2011
.Dt BEASTIE.4TH 8
.Os
.Sh NAME
.Nm beastie.4th
-.Nd FreeBSD ASCII art boot module.
+.Nd FreeBSD ASCII art boot module
.Sh DESCRIPTION
The file that goes by the name of
.Nm
@@ -168,4 +168,4 @@
.An Scott Long Aq scottl at FreeBSD.org ,
.An Aleksander Fafula Aq alex at fafula.com
and
-.An Devin Teske Aq devinteske at hotmail.com .
+.An Devin Teske Aq dteske at FreeBSD.org .
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/forth/brand.4th
--- a/head/sys/boot/forth/brand.4th Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/forth/brand.4th Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-\ Copyright (c) 2006-2011 Devin Teske <devinteske at hotmail.com>
+\ Copyright (c) 2006-2011 Devin Teske <dteske at FreeBSD.org>
\ All rights reserved.
\
\ Redistribution and use in source and binary forms, with or without
@@ -22,7 +22,7 @@
\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
\ SUCH DAMAGE.
\
-\ $FreeBSD: head/sys/boot/forth/brand.4th 222417 2011-05-28 08:50:38Z julian $
+\ $FreeBSD: head/sys/boot/forth/brand.4th 238431 2012-07-14 01:45:35Z dteske $
marker task-brand.4th
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/forth/brand.4th.8
--- a/head/sys/boot/forth/brand.4th.8 Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/forth/brand.4th.8 Wed Jul 25 16:45:04 2012 +0300
@@ -22,14 +22,14 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD: head/sys/boot/forth/brand.4th.8 222417 2011-05-28 08:50:38Z julian $
+.\" $FreeBSD: head/sys/boot/forth/brand.4th.8 238431 2012-07-14 01:45:35Z dteske $
.\"
.Dd May 18, 2011
.Dt BRAND.4TH 8
.Os
.Sh NAME
.Nm brand.4th
-.Nd FreeBSD ASCII art boot module.
+.Nd FreeBSD ASCII art boot module
.Sh DESCRIPTION
The file that goes by the name of
.Nm
@@ -122,4 +122,4 @@
.Nm
set of commands was written by
.An -nosplit
-.An Devin Teske Aq devinteske at hotmail.com .
+.An Devin Teske Aq dteske at FreeBSD.org .
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/forth/check-password.4th
--- a/head/sys/boot/forth/check-password.4th Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/forth/check-password.4th Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-\ Copyright (c) 2006-2011 Devin Teske <devinteske at hotmail.com>
+\ Copyright (c) 2006-2011 Devin Teske <dteske at FreeBSD.org>
\ All rights reserved.
\
\ Redistribution and use in source and binary forms, with or without
@@ -22,7 +22,7 @@
\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
\ SUCH DAMAGE.
\
-\ $FreeBSD: head/sys/boot/forth/check-password.4th 222417 2011-05-28 08:50:38Z julian $
+\ $FreeBSD: head/sys/boot/forth/check-password.4th 238431 2012-07-14 01:45:35Z dteske $
marker task-check-password.4th
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/forth/check-password.4th.8
--- a/head/sys/boot/forth/check-password.4th.8 Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/forth/check-password.4th.8 Wed Jul 25 16:45:04 2012 +0300
@@ -22,14 +22,14 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD: head/sys/boot/forth/check-password.4th.8 222599 2011-06-02 09:56:42Z uqs $
+.\" $FreeBSD: head/sys/boot/forth/check-password.4th.8 238431 2012-07-14 01:45:35Z dteske $
.\"
.Dd May 18, 2011
.Dt CHECK-PASSWORD.4TH 8
.Os
.Sh NAME
.Nm check-password.4th
-.Nd FreeBSD password-checking boot module.
+.Nd FreeBSD password-checking boot module
.Sh DESCRIPTION
The file that goes by the name of
.Nm
@@ -120,4 +120,4 @@
.Nm
set of commands was written by
.An -nosplit
-.An Devin Teske Aq devinteske at hotmail.com .
+.An Devin Teske Aq dteske at FreeBSD.org .
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/forth/color.4th
--- a/head/sys/boot/forth/color.4th Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/forth/color.4th Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-\ Copyright (c) 2011 Devin Teske <devinteske at hotmail.com>
+\ Copyright (c) 2011 Devin Teske <dteske at FreeBSD.org>
\ All rights reserved.
\
\ Redistribution and use in source and binary forms, with or without
@@ -22,7 +22,7 @@
\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
\ SUCH DAMAGE.
\
-\ $FreeBSD: head/sys/boot/forth/color.4th 222417 2011-05-28 08:50:38Z julian $
+\ $FreeBSD: head/sys/boot/forth/color.4th 238431 2012-07-14 01:45:35Z dteske $
marker task-color.4th
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/forth/color.4th.8
--- a/head/sys/boot/forth/color.4th.8 Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/forth/color.4th.8 Wed Jul 25 16:45:04 2012 +0300
@@ -22,14 +22,14 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD: head/sys/boot/forth/color.4th.8 222417 2011-05-28 08:50:38Z julian $
+.\" $FreeBSD: head/sys/boot/forth/color.4th.8 238431 2012-07-14 01:45:35Z dteske $
.\"
.Dd May 18, 2011
.Dt COLOR.4TH 8
.Os
.Sh NAME
.Nm color.4th
-.Nd FreeBSD color-detection boot module.
+.Nd FreeBSD color-detection boot module
.Sh DESCRIPTION
The file that goes by the name of
.Nm
@@ -114,4 +114,4 @@
.Nm
set of commands was written by
.An -nosplit
-.An Devin Teske Aq devinteske at hotmail.com .
+.An Devin Teske Aq dteske at FreeBSD.org .
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/forth/delay.4th
--- a/head/sys/boot/forth/delay.4th Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/forth/delay.4th Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-\ Copyright (c) 2008-2011 Devin Teske <devinteske at hotmail.com>
+\ Copyright (c) 2008-2011 Devin Teske <dteske at FreeBSD.org>
\ All rights reserved.
\
\ Redistribution and use in source and binary forms, with or without
@@ -22,7 +22,7 @@
\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
\ SUCH DAMAGE.
\
-\ $FreeBSD: head/sys/boot/forth/delay.4th 222417 2011-05-28 08:50:38Z julian $
+\ $FreeBSD: head/sys/boot/forth/delay.4th 238431 2012-07-14 01:45:35Z dteske $
marker task-delay.4th
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/forth/delay.4th.8
--- a/head/sys/boot/forth/delay.4th.8 Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/forth/delay.4th.8 Wed Jul 25 16:45:04 2012 +0300
@@ -22,14 +22,14 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD: head/sys/boot/forth/delay.4th.8 222417 2011-05-28 08:50:38Z julian $
+.\" $FreeBSD: head/sys/boot/forth/delay.4th.8 238431 2012-07-14 01:45:35Z dteske $
.\"
.Dd May 18, 2011
.Dt DELAY.4TH 8
.Os
.Sh NAME
.Nm delay.4th
-.Nd FreeBSD debugging boot module.
+.Nd FreeBSD debugging boot module
.Sh DESCRIPTION
The file that goes by the name of
.Nm
@@ -123,4 +123,4 @@
.Nm
set of commands was written by
.An -nosplit
-.An Devin Teske Aq devinteske at hotmail.com .
+.An Devin Teske Aq dteske at FreeBSD.org .
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/forth/menu-commands.4th
--- a/head/sys/boot/forth/menu-commands.4th Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/forth/menu-commands.4th Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-\ Copyright (c) 2006-2011 Devin Teske <devinteske at hotmail.com>
+\ Copyright (c) 2006-2011 Devin Teske <dteske at FreeBSD.org>
\ All rights reserved.
\
\ Redistribution and use in source and binary forms, with or without
@@ -22,7 +22,7 @@
\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
\ SUCH DAMAGE.
\
-\ $FreeBSD: head/sys/boot/forth/menu-commands.4th 233941 2012-04-06 09:36:22Z avg $
+\ $FreeBSD: head/sys/boot/forth/menu-commands.4th 238431 2012-07-14 01:45:35Z dteske $
marker task-menu-commands.4th
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/forth/menu.4th
--- a/head/sys/boot/forth/menu.4th Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/forth/menu.4th Wed Jul 25 16:45:04 2012 +0300
@@ -1,6 +1,6 @@
\ Copyright (c) 2003 Scott Long <scottl at freebsd.org>
\ Copyright (c) 2003 Aleksander Fafula <alex at fafula.com>
-\ Copyright (c) 2006-2011 Devin Teske <devinteske at hotmail.com>
+\ Copyright (c) 2006-2011 Devin Teske <dteske at FreeBSD.org>
\ All rights reserved.
\
\ Redistribution and use in source and binary forms, with or without
@@ -24,7 +24,7 @@
\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
\ SUCH DAMAGE.
\
-\ $FreeBSD: head/sys/boot/forth/menu.4th 228985 2011-12-30 06:24:59Z pluknet $
+\ $FreeBSD: head/sys/boot/forth/menu.4th 238431 2012-07-14 01:45:35Z dteske $
marker task-menu.4th
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/forth/menu.4th.8
--- a/head/sys/boot/forth/menu.4th.8 Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/forth/menu.4th.8 Wed Jul 25 16:45:04 2012 +0300
@@ -22,14 +22,14 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD: head/sys/boot/forth/menu.4th.8 232158 2012-02-25 15:21:43Z gjb $
+.\" $FreeBSD: head/sys/boot/forth/menu.4th.8 238431 2012-07-14 01:45:35Z dteske $
.\"
.Dd February 25, 2012
.Dt MENU.4TH 8
.Os
.Sh NAME
.Nm menu.4th
-.Nd FreeBSD dynamic menu boot module.
+.Nd FreeBSD dynamic menu boot module
.Sh DESCRIPTION
The file that goes by the name of
.Nm
@@ -320,4 +320,4 @@
.Nm
set of commands was written by
.An -nosplit
-.An Devin Teske Aq devinteske at hotmail.com .
+.An Devin Teske Aq dteske at FreeBSD.org .
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/forth/shortcuts.4th
--- a/head/sys/boot/forth/shortcuts.4th Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/forth/shortcuts.4th Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-\ Copyright (c) 2008-2011 Devin Teske <devinteske at hotmail.com>
+\ Copyright (c) 2008-2011 Devin Teske <dteske at FreeBSD.org>
\ All rights reserved.
\
\ Redistribution and use in source and binary forms, with or without
@@ -22,7 +22,7 @@
\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
\ SUCH DAMAGE.
\
-\ $FreeBSD: head/sys/boot/forth/shortcuts.4th 222417 2011-05-28 08:50:38Z julian $
+\ $FreeBSD: head/sys/boot/forth/shortcuts.4th 238431 2012-07-14 01:45:35Z dteske $
\ FICL words intended to be used as shortcuts for carrying out common tasks or
\ producing common results. Generally, words defined here are simply groupings
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/forth/version.4th
--- a/head/sys/boot/forth/version.4th Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/forth/version.4th Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-\ Copyright (c) 2006-2011 Devin Teske <devinteske at hotmail.com>
+\ Copyright (c) 2006-2011 Devin Teske <dteske at FreeBSD.org>
\ All rights reserved.
\
\ Redistribution and use in source and binary forms, with or without
@@ -22,7 +22,7 @@
\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
\ SUCH DAMAGE.
\
-\ $FreeBSD: head/sys/boot/forth/version.4th 222417 2011-05-28 08:50:38Z julian $
+\ $FreeBSD: head/sys/boot/forth/version.4th 238431 2012-07-14 01:45:35Z dteske $
marker task-version.4th
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/forth/version.4th.8
--- a/head/sys/boot/forth/version.4th.8 Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/forth/version.4th.8 Wed Jul 25 16:45:04 2012 +0300
@@ -22,14 +22,14 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD: head/sys/boot/forth/version.4th.8 222417 2011-05-28 08:50:38Z julian $
+.\" $FreeBSD: head/sys/boot/forth/version.4th.8 238431 2012-07-14 01:45:35Z dteske $
.\"
.Dd May 19, 2011
.Dt VERSION.4TH 8
.Os
.Sh NAME
.Nm version.4th
-.Nd FreeBSD version string boot module.
+.Nd FreeBSD version string boot module
.Sh DESCRIPTION
The file that goes by the name of
.Nm
@@ -123,4 +123,4 @@
.Nm
set of commands was written by
.An -nosplit
-.An Devin Teske Aq devinteske at hotmail.com .
+.An Devin Teske Aq dteske at FreeBSD.org .
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/boot2/boot2.c
--- a/head/sys/boot/i386/boot2/boot2.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/boot2/boot2.c Wed Jul 25 16:45:04 2012 +0300
@@ -14,7 +14,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/boot/i386/boot2/boot2.c 232754 2012-03-09 23:30:30Z jkim $");
+__FBSDID("$FreeBSD: head/sys/boot/i386/boot2/boot2.c 236405 2012-06-01 15:48:24Z jhb $");
#include <sys/param.h>
#include <sys/disklabel.h>
@@ -129,8 +129,8 @@
int init;
} dsk;
static char cmd[512], cmddup[512], knamebuf[1024];
-static const char *kname = NULL;
-static uint32_t opts = 0;
+static const char *kname;
+static uint32_t opts;
static int comspeed = SIOSPD;
static struct bootinfo bootinfo;
static uint8_t ioctrl = IO_KEYBOARD;
@@ -138,7 +138,6 @@
void exit(int);
static void load(void);
static int parse(void);
-static int xfsread(ino_t, void *, size_t);
static int dskread(void *, unsigned, unsigned);
static void printf(const char *,...);
static void putchar(int);
@@ -170,7 +169,7 @@
#include "ufsread.c"
static inline int
-xfsread(ino_t inode, void *buf, size_t nbyte)
+xfsread(ufs_ino_t inode, void *buf, size_t nbyte)
{
if ((size_t)fsread(inode, buf, nbyte) != nbyte) {
printf("Invalid %s\n", "format");
@@ -222,7 +221,7 @@
main(void)
{
uint8_t autoboot;
- ino_t ino;
+ ufs_ino_t ino;
size_t nbyte;
dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base);
@@ -307,7 +306,7 @@
static Elf32_Phdr ep[2];
static Elf32_Shdr es[2];
caddr_t p;
- ino_t ino;
+ ufs_ino_t ino;
uint32_t addr;
int i, j;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/btx/btx/Makefile
--- a/head/sys/boot/i386/btx/btx/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/btx/btx/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-# $FreeBSD: head/sys/boot/i386/btx/btx/Makefile 232263 2012-02-28 18:30:18Z dim $
+# $FreeBSD: head/sys/boot/i386/btx/btx/Makefile 235154 2012-05-09 08:04:29Z avg $
PROG= btx
INTERNALPROG=
@@ -12,6 +12,7 @@
.endif
CFLAGS+=-DBTX_FLAGS=${BOOT_BTX_FLAGS}
+CFLAGS+=-I${.CURDIR}/../../common
.if defined(BTX_SERIAL)
BOOT_COMCONSOLE_PORT?= 0x3f8
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/btx/btx/btx.S
--- a/head/sys/boot/i386/btx/btx/btx.S Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/btx/btx/btx.S Wed Jul 25 16:45:04 2012 +0300
@@ -12,9 +12,11 @@
* warranties of merchantability and fitness for a particular
* purpose.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/boot/i386/btx/btx/btx.S 235154 2012-05-09 08:04:29Z avg $
*/
+#include <bootargs.h>
+
/*
* Memory layout.
*/
@@ -205,7 +207,7 @@
movl $MEM_USR,%edx # User base address
movzwl %ss:BDA_MEM,%eax # Get free memory
shll $0xa,%eax # To bytes
- subl $0x1000,%eax # Less arg space
+ subl $ARGSPACE,%eax # Less arg space
subl %edx,%eax # Less base
movb $SEL_UDATA,%cl # User data selector
pushl %ecx # Set SS
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/btx/btxldr/Makefile
--- a/head/sys/boot/i386/btx/btxldr/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/btx/btxldr/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-# $FreeBSD: head/sys/boot/i386/btx/btxldr/Makefile 232263 2012-02-28 18:30:18Z dim $
+# $FreeBSD: head/sys/boot/i386/btx/btxldr/Makefile 235154 2012-05-09 08:04:29Z avg $
PROG= btxldr
INTERNALPROG=
@@ -6,6 +6,7 @@
SRCS= btxldr.S
CFLAGS+=-DLOADER_ADDRESS=${LOADER_ADDRESS}
+CFLAGS+=-I${.CURDIR}/../../common
.if defined(BTXLDR_VERBOSE)
CFLAGS+=-DBTXLDR_VERBOSE
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/btx/btxldr/btxldr.S
--- a/head/sys/boot/i386/btx/btxldr/btxldr.S Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/btx/btxldr/btxldr.S Wed Jul 25 16:45:04 2012 +0300
@@ -12,9 +12,11 @@
* warranties of merchantability and fitness for a particular
* purpose.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/boot/i386/btx/btxldr/btxldr.S 235154 2012-05-09 08:04:29Z avg $
*/
+#include <bootargs.h>
+
#define RBX_MUTE 0x10 /* -m */
#define OPT_SET(opt) (1 << (opt))
@@ -89,7 +91,7 @@
call hexout # stack
call putstr # pointer
movl $m_args,%esi # Format string
- leal 0x4(%esp,1),%ebx # First argument
+ leal 0x4(%esp),%ebx # First argument
movl $0x6,%ecx # Count
start.1: movl (%ebx),%eax # Get argument and
addl $0x4,%ebx # bump pointer
@@ -97,24 +99,28 @@
loop start.1 # Till done
call putstr # End message
#endif
- movl $0x48,%ecx # Allocate space
- subl %ecx,%ebp # for bootinfo
- movl 0x18(%esp,1),%esi # Source: bootinfo
+ movl BA_BOOTINFO+4(%esp),%esi # Source: bootinfo
cmpl $0x0, %esi # If the bootinfo pointer
je start_null_bi # is null, don't copy it
+ movl BI_SIZE(%esi),%ecx # Allocate space
+ subl %ecx,%ebp # for bootinfo
movl %ebp,%edi # Destination
rep # Copy
movsb # it
- movl %ebp,0x18(%esp,1) # Update pointer
+ movl %ebp,BA_BOOTINFO+4(%esp) # Update pointer
+ movl %edi,%ebp # Restore base pointer
#ifdef BTXLDR_VERBOSE
movl $m_rel_bi,%esi # Display
movl %ebp,%eax # bootinfo
call hexout # relocation
call putstr # message
#endif
-start_null_bi: movl $0x18,%ecx # Allocate space
- subl %ecx,%ebp # for arguments
- leal 0x4(%esp,1),%esi # Source
+start_null_bi: movl $BOOTARGS_SIZE,%ecx # Fixed size of arguments
+ testl $KARGS_FLAGS_EXTARG, BA_BOOTFLAGS+4(%esp) # Check for extra data
+ jz start_fixed # Skip if the flag is not set
+ addl BOOTARGS_SIZE+4(%esp),%ecx # Add size of variable args
+start_fixed: subl $ARGOFF,%ebp # Place args at fixed offset
+ leal 0x4(%esp),%esi # Source
movl %ebp,%edi # Destination
rep # Copy
movsb # them
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/btx/lib/Makefile
--- a/head/sys/boot/i386/btx/lib/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/btx/lib/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,9 +1,10 @@
-# $FreeBSD$
+# $FreeBSD: head/sys/boot/i386/btx/lib/Makefile 235154 2012-05-09 08:04:29Z avg $
PROG= crt0.o
INTERNALPROG=
NO_MAN=
-SRCS= btxcsu.s btxsys.s btxv86.s
+SRCS= btxcsu.S btxsys.s btxv86.s
+CFLAGS+=-I${.CURDIR}/../../common
LDFLAGS=-Wl,-r
.include <bsd.prog.mk>
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/btx/lib/btxcsu.S
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/boot/i386/btx/lib/btxcsu.S Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 1998 Robert Nordier
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are freely
+# permitted provided that the above copyright notice and this
+# paragraph and the following disclaimer are duplicated in all
+# such forms.
+#
+# This software is provided "AS IS" and without any express or
+# implied warranties, including, without limitation, the implied
+# warranties of merchantability and fitness for a particular
+# purpose.
+#
+
+# $FreeBSD: head/sys/boot/i386/btx/lib/btxcsu.S 235154 2012-05-09 08:04:29Z avg $
+
+#include <bootargs.h>
+
+#
+# BTX C startup code (ELF).
+#
+
+#
+# Globals.
+#
+ .global _start
+#
+# Client entry point.
+#
+_start: cld
+ pushl %eax
+ movl $_edata,%edi
+ movl $_end,%ecx
+ subl %edi, %ecx
+ xorb %al, %al
+ rep
+ stosb
+ popl __base
+ movl %esp,%eax # Set
+ addl $ARGADJ,%eax # argument
+ movl %eax,__args # pointer
+ call main # Invoke client main()
+ call exit # Invoke client exit()
+#
+# Data.
+#
+ .comm __base,4 # Client base address
+ .comm __args,4 # Client arguments
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/btx/lib/btxcsu.s
--- a/head/sys/boot/i386/btx/lib/btxcsu.s Wed Jul 25 16:42:35 2012 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-#
-# Copyright (c) 1998 Robert Nordier
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms are freely
-# permitted provided that the above copyright notice and this
-# paragraph and the following disclaimer are duplicated in all
-# such forms.
-#
-# This software is provided "AS IS" and without any express or
-# implied warranties, including, without limitation, the implied
-# warranties of merchantability and fitness for a particular
-# purpose.
-#
-
-# $FreeBSD$
-
-#
-# BTX C startup code (ELF).
-#
-
-#
-# Globals.
-#
- .global _start
-#
-# Constants.
-#
- .set ARGADJ,0xfa0 # Argument adjustment
-#
-# Client entry point.
-#
-_start: cld
- pushl %eax
- movl $_edata,%edi
- movl $_end,%ecx
- subl %edi, %ecx
- xorb %al, %al
- rep
- stosb
- popl __base
- movl %esp,%eax # Set
- addl $ARGADJ,%eax # argument
- movl %eax,__args # pointer
- call main # Invoke client main()
- call exit # Invoke client exit()
-#
-# Data.
-#
- .comm __base,4 # Client base address
- .comm __args,4 # Client arguments
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/cdboot/Makefile
--- a/head/sys/boot/i386/cdboot/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/cdboot/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,13 +1,19 @@
-# $FreeBSD$
+# $FreeBSD: head/sys/boot/i386/cdboot/Makefile 235281 2012-05-11 18:07:23Z dim $
PROG= cdboot
STRIP=
BINMODE=${NOBINMODE}
NO_MAN=
-SRCS= ${PROG}.s
+SRCS= ${PROG}.S
+
+CFLAGS+=-I${.CURDIR}/../common
ORG= 0x7c00
LDFLAGS=-e start -Ttext ${ORG} -Wl,-N,-S,--oformat,binary
.include <bsd.prog.mk>
+
+# XXX: clang integrated-as doesn't grok .codeNN directives yet
+CFLAGS.cdboot.S= ${CLANG_NO_IAS}
+CFLAGS+= ${CFLAGS.${.IMPSRC:T}}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/cdboot/cdboot.S
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/boot/i386/cdboot/cdboot.S Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,597 @@
+#
+# Copyright (c) 2001 John Baldwin <jhb at 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.
+# 3. Neither the name of the author nor the names of any co-contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# $FreeBSD: head/sys/boot/i386/cdboot/cdboot.S 235219 2012-05-10 09:47:04Z avg $
+
+#
+# This program is a freestanding boot program to load an a.out binary
+# from a CD-ROM booted with no emulation mode as described by the El
+# Torito standard. Due to broken BIOSen that do not load the desired
+# number of sectors, we try to fit this in as small a space as possible.
+#
+# Basically, we first create a set of boot arguments to pass to the loaded
+# binary. Then we attempt to load /boot/loader from the CD we were booted
+# off of.
+#
+
+#include <bootargs.h>
+
+#
+# Memory locations.
+#
+ .set MEM_PAGE_SIZE,0x1000 # memory page size, 4k
+ .set MEM_ARG,0x900 # Arguments at start
+ .set MEM_ARG_BTX,0xa100 # Where we move them to so the
+ # BTX client can see them
+ .set MEM_ARG_SIZE,0x18 # Size of the arguments
+ .set MEM_BTX_ADDRESS,0x9000 # where BTX lives
+ .set MEM_BTX_ENTRY,0x9010 # where BTX starts to execute
+ .set MEM_BTX_OFFSET,MEM_PAGE_SIZE # offset of BTX in the loader
+ .set MEM_BTX_CLIENT,0xa000 # where BTX clients live
+#
+# a.out header fields
+#
+ .set AOUT_TEXT,0x04 # text segment size
+ .set AOUT_DATA,0x08 # data segment size
+ .set AOUT_BSS,0x0c # zero'd BSS size
+ .set AOUT_SYMBOLS,0x10 # symbol table
+ .set AOUT_ENTRY,0x14 # entry point
+ .set AOUT_HEADER,MEM_PAGE_SIZE # size of the a.out header
+#
+# Segment selectors.
+#
+ .set SEL_SDATA,0x8 # Supervisor data
+ .set SEL_RDATA,0x10 # Real mode data
+ .set SEL_SCODE,0x18 # PM-32 code
+ .set SEL_SCODE16,0x20 # PM-16 code
+#
+# BTX constants
+#
+ .set INT_SYS,0x30 # BTX syscall interrupt
+#
+# Constants for reading from the CD.
+#
+ .set ERROR_TIMEOUT,0x80 # BIOS timeout on read
+ .set NUM_RETRIES,3 # Num times to retry
+ .set SECTOR_SIZE,0x800 # size of a sector
+ .set SECTOR_SHIFT,11 # number of place to shift
+ .set BUFFER_LEN,0x100 # number of sectors in buffer
+ .set MAX_READ,0x10000 # max we can read at a time
+ .set MAX_READ_SEC,MAX_READ >> SECTOR_SHIFT
+ .set MEM_READ_BUFFER,0x9000 # buffer to read from CD
+ .set MEM_VOLDESC,MEM_READ_BUFFER # volume descriptor
+ .set MEM_DIR,MEM_VOLDESC+SECTOR_SIZE # Lookup buffer
+ .set VOLDESC_LBA,0x10 # LBA of vol descriptor
+ .set VD_PRIMARY,1 # Primary VD
+ .set VD_END,255 # VD Terminator
+ .set VD_ROOTDIR,156 # Offset of Root Dir Record
+ .set DIR_LEN,0 # Offset of Dir Record length
+ .set DIR_EA_LEN,1 # Offset of EA length
+ .set DIR_EXTENT,2 # Offset of 64-bit LBA
+ .set DIR_SIZE,10 # Offset of 64-bit length
+ .set DIR_NAMELEN,32 # Offset of 8-bit name len
+ .set DIR_NAME,33 # Offset of dir name
+#
+# We expect to be loaded by the BIOS at 0x7c00 (standard boot loader entry
+# point)
+#
+ .code16
+ .globl start
+ .org 0x0, 0x0
+#
+# Program start.
+#
+start: cld # string ops inc
+ xor %ax,%ax # zero %ax
+ mov %ax,%ss # setup the
+ mov $start,%sp # stack
+ mov %ax,%ds # setup the
+ mov %ax,%es # data segments
+ mov %dl,drive # Save BIOS boot device
+ mov $msg_welcome,%si # %ds:(%si) -> welcome message
+ call putstr # display the welcome message
+#
+# Setup the arguments that the loader is expecting from boot[12]
+#
+ mov $msg_bootinfo,%si # %ds:(%si) -> boot args message
+ call putstr # display the message
+ mov $MEM_ARG,%bx # %ds:(%bx) -> boot args
+ mov %bx,%di # %es:(%di) -> boot args
+ xor %eax,%eax # zero %eax
+ mov $(MEM_ARG_SIZE/4),%cx # Size of arguments in 32-bit
+ # dwords
+ rep # Clear the arguments
+ stosl # to zero
+ mov drive,%dl # Store BIOS boot device
+ mov %dl,0x4(%bx) # in kargs->bootdev
+ or $KARGS_FLAGS_CD,0x8(%bx) # kargs->bootflags |=
+ # KARGS_FLAGS_CD
+#
+# Load Volume Descriptor
+#
+ mov $VOLDESC_LBA,%eax # Set LBA of first VD
+load_vd: push %eax # Save %eax
+ mov $1,%dh # One sector
+ mov $MEM_VOLDESC,%ebx # Destination
+ call read # Read it in
+ cmpb $VD_PRIMARY,(%bx) # Primary VD?
+ je have_vd # Yes
+ pop %eax # Prepare to
+ inc %eax # try next
+ cmpb $VD_END,(%bx) # Last VD?
+ jne load_vd # No, read next
+ mov $msg_novd,%si # No VD
+ jmp error # Halt
+have_vd: # Have Primary VD
+#
+# Try to look up the loader binary using the paths in the loader_paths
+# array.
+#
+ mov $loader_paths,%si # Point to start of array
+lookup_path: push %si # Save file name pointer
+ call lookup # Try to find file
+ pop %di # Restore file name pointer
+ jnc lookup_found # Found this file
+ xor %al,%al # Look for next
+ mov $0xffff,%cx # path name by
+ repnz # scanning for
+ scasb # nul char
+ mov %di,%si # Point %si at next path
+ mov (%si),%al # Get first char of next path
+ or %al,%al # Is it double nul?
+ jnz lookup_path # No, try it.
+ mov $msg_failed,%si # Failed message
+ jmp error # Halt
+lookup_found: # Found a loader file
+#
+# Load the binary into the buffer. Due to real mode addressing limitations
+# we have to read it in 64k chunks.
+#
+ mov DIR_SIZE(%bx),%eax # Read file length
+ add $SECTOR_SIZE-1,%eax # Convert length to sectors
+ shr $SECTOR_SHIFT,%eax
+ cmp $BUFFER_LEN,%eax
+ jbe load_sizeok
+ mov $msg_load2big,%si # Error message
+ call error
+load_sizeok: movzbw %al,%cx # Num sectors to read
+ mov DIR_EXTENT(%bx),%eax # Load extent
+ xor %edx,%edx
+ mov DIR_EA_LEN(%bx),%dl
+ add %edx,%eax # Skip extended
+ mov $MEM_READ_BUFFER,%ebx # Read into the buffer
+load_loop: mov %cl,%dh
+ cmp $MAX_READ_SEC,%cl # Truncate to max read size
+ jbe load_notrunc
+ mov $MAX_READ_SEC,%dh
+load_notrunc: sub %dh,%cl # Update count
+ push %eax # Save
+ call read # Read it in
+ pop %eax # Restore
+ add $MAX_READ_SEC,%eax # Update LBA
+ add $MAX_READ,%ebx # Update dest addr
+ jcxz load_done # Done?
+ jmp load_loop # Keep going
+load_done:
+#
+# Turn on the A20 address line
+#
+ call seta20 # Turn A20 on
+#
+# Relocate the loader and BTX using a very lazy protected mode
+#
+ mov $msg_relocate,%si # Display the
+ call putstr # relocation message
+ mov MEM_READ_BUFFER+AOUT_ENTRY,%edi # %edi is the destination
+ mov $(MEM_READ_BUFFER+AOUT_HEADER),%esi # %esi is
+ # the start of the text
+ # segment
+ mov MEM_READ_BUFFER+AOUT_TEXT,%ecx # %ecx = length of the text
+ # segment
+ push %edi # Save entry point for later
+ lgdt gdtdesc # setup our own gdt
+ cli # turn off interrupts
+ mov %cr0,%eax # Turn on
+ or $0x1,%al # protected
+ mov %eax,%cr0 # mode
+ ljmp $SEL_SCODE,$pm_start # long jump to clear the
+ # instruction pre-fetch queue
+ .code32
+pm_start: mov $SEL_SDATA,%ax # Initialize
+ mov %ax,%ds # %ds and
+ mov %ax,%es # %es to a flat selector
+ rep # Relocate the
+ movsb # text segment
+ add $(MEM_PAGE_SIZE - 1),%edi # pad %edi out to a new page
+ and $~(MEM_PAGE_SIZE - 1),%edi # for the data segment
+ mov MEM_READ_BUFFER+AOUT_DATA,%ecx # size of the data segment
+ rep # Relocate the
+ movsb # data segment
+ mov MEM_READ_BUFFER+AOUT_BSS,%ecx # size of the bss
+ xor %eax,%eax # zero %eax
+ add $3,%cl # round %ecx up to
+ shr $2,%ecx # a multiple of 4
+ rep # zero the
+ stosl # bss
+ mov MEM_READ_BUFFER+AOUT_ENTRY,%esi # %esi -> relocated loader
+ add $MEM_BTX_OFFSET,%esi # %esi -> BTX in the loader
+ mov $MEM_BTX_ADDRESS,%edi # %edi -> where BTX needs to go
+ movzwl 0xa(%esi),%ecx # %ecx -> length of BTX
+ rep # Relocate
+ movsb # BTX
+ ljmp $SEL_SCODE16,$pm_16 # Jump to 16-bit PM
+ .code16
+pm_16: mov $SEL_RDATA,%ax # Initialize
+ mov %ax,%ds # %ds and
+ mov %ax,%es # %es to a real mode selector
+ mov %cr0,%eax # Turn off
+ and $~0x1,%al # protected
+ mov %eax,%cr0 # mode
+ ljmp $0,$pm_end # Long jump to clear the
+ # instruction pre-fetch queue
+pm_end: sti # Turn interrupts back on now
+#
+# Copy the BTX client to MEM_BTX_CLIENT
+#
+ xor %ax,%ax # zero %ax and set
+ mov %ax,%ds # %ds and %es
+ mov %ax,%es # to segment 0
+ mov $MEM_BTX_CLIENT,%di # Prepare to relocate
+ mov $btx_client,%si # the simple btx client
+ mov $(btx_client_end-btx_client),%cx # length of btx client
+ rep # Relocate the
+ movsb # simple BTX client
+#
+# Copy the boot[12] args to where the BTX client can see them
+#
+ mov $MEM_ARG,%si # where the args are at now
+ mov $MEM_ARG_BTX,%di # where the args are moving to
+ mov $(MEM_ARG_SIZE/4),%cx # size of the arguments in longs
+ rep # Relocate
+ movsl # the words
+#
+# Save the entry point so the client can get to it later on
+#
+ pop %eax # Restore saved entry point
+ stosl # and add it to the end of
+ # the arguments
+#
+# Now we just start up BTX and let it do the rest
+#
+ mov $msg_jump,%si # Display the
+ call putstr # jump message
+ ljmp $0,$MEM_BTX_ENTRY # Jump to the BTX entry point
+
+#
+# Lookup the file in the path at [SI] from the root directory.
+#
+# Trashes: All but BX
+# Returns: CF = 0 (success), BX = pointer to record
+# CF = 1 (not found)
+#
+lookup: mov $VD_ROOTDIR+MEM_VOLDESC,%bx # Root directory record
+ push %si
+ mov $msg_lookup,%si # Display lookup message
+ call putstr
+ pop %si
+ push %si
+ call putstr
+ mov $msg_lookup2,%si
+ call putstr
+ pop %si
+lookup_dir: lodsb # Get first char of path
+ cmp $0,%al # Are we done?
+ je lookup_done # Yes
+ cmp $'/',%al # Skip path separator.
+ je lookup_dir
+ dec %si # Undo lodsb side effect
+ call find_file # Lookup first path item
+ jnc lookup_dir # Try next component
+ mov $msg_lookupfail,%si # Not found message
+ call putstr
+ stc # Set carry
+ ret
+ jmp error
+lookup_done: mov $msg_lookupok,%si # Success message
+ call putstr
+ clc # Clear carry
+ ret
+
+#
+# Lookup file at [SI] in directory whose record is at [BX].
+#
+# Trashes: All but returns
+# Returns: CF = 0 (success), BX = pointer to record, SI = next path item
+# CF = 1 (not found), SI = preserved
+#
+find_file: mov DIR_EXTENT(%bx),%eax # Load extent
+ xor %edx,%edx
+ mov DIR_EA_LEN(%bx),%dl
+ add %edx,%eax # Skip extended attributes
+ mov %eax,rec_lba # Save LBA
+ mov DIR_SIZE(%bx),%eax # Save size
+ mov %eax,rec_size
+ xor %cl,%cl # Zero length
+ push %si # Save
+ff.namelen: inc %cl # Update length
+ lodsb # Read char
+ cmp $0,%al # Nul?
+ je ff.namedone # Yes
+ cmp $'/',%al # Path separator?
+ jnz ff.namelen # No, keep going
+ff.namedone: dec %cl # Adjust length and save
+ mov %cl,name_len
+ pop %si # Restore
+ff.load: mov rec_lba,%eax # Load LBA
+ mov $MEM_DIR,%ebx # Address buffer
+ mov $1,%dh # One sector
+ call read # Read directory block
+ incl rec_lba # Update LBA to next block
+ff.scan: mov %ebx,%edx # Check for EOF
+ sub $MEM_DIR,%edx
+ cmp %edx,rec_size
+ ja ff.scan.1
+ stc # EOF reached
+ ret
+ff.scan.1: cmpb $0,DIR_LEN(%bx) # Last record in block?
+ je ff.nextblock
+ push %si # Save
+ movzbw DIR_NAMELEN(%bx),%si # Find end of string
+ff.checkver: cmpb $'0',DIR_NAME-1(%bx,%si) # Less than '0'?
+ jb ff.checkver.1
+ cmpb $'9',DIR_NAME-1(%bx,%si) # Greater than '9'?
+ ja ff.checkver.1
+ dec %si # Next char
+ jnz ff.checkver
+ jmp ff.checklen # All numbers in name, so
+ # no version
+ff.checkver.1: movzbw DIR_NAMELEN(%bx),%cx
+ cmp %cx,%si # Did we find any digits?
+ je ff.checkdot # No
+ cmpb $';',DIR_NAME-1(%bx,%si) # Check for semicolon
+ jne ff.checkver.2
+ dec %si # Skip semicolon
+ mov %si,%cx
+ mov %cl,DIR_NAMELEN(%bx) # Adjust length
+ jmp ff.checkdot
+ff.checkver.2: mov %cx,%si # Restore %si to end of string
+ff.checkdot: cmpb $'.',DIR_NAME-1(%bx,%si) # Trailing dot?
+ jne ff.checklen # No
+ decb DIR_NAMELEN(%bx) # Adjust length
+ff.checklen: pop %si # Restore
+ movzbw name_len,%cx # Load length of name
+ cmp %cl,DIR_NAMELEN(%bx) # Does length match?
+ je ff.checkname # Yes, check name
+ff.nextrec: add DIR_LEN(%bx),%bl # Next record
+ adc $0,%bh
+ jmp ff.scan
+ff.nextblock: subl $SECTOR_SIZE,rec_size # Adjust size
+ jnc ff.load # If subtract ok, keep going
+ ret # End of file, so not found
+ff.checkname: lea DIR_NAME(%bx),%di # Address name in record
+ push %si # Save
+ repe cmpsb # Compare name
+ je ff.match # We have a winner!
+ pop %si # Restore
+ jmp ff.nextrec # Keep looking.
+ff.match: add $2,%sp # Discard saved %si
+ clc # Clear carry
+ ret
+
+#
+# Load DH sectors starting at LBA EAX into [EBX].
+#
+# Trashes: EAX
+#
+read: push %si # Save
+ push %cx # Save since some BIOSs trash
+ mov %eax,edd_lba # LBA to read from
+ mov %ebx,%eax # Convert address
+ shr $4,%eax # to segment
+ mov %ax,edd_addr+0x2 # and store
+read.retry: call twiddle # Entertain the user
+ push %dx # Save
+ mov $edd_packet,%si # Address Packet
+ mov %dh,edd_len # Set length
+ mov drive,%dl # BIOS Device
+ mov $0x42,%ah # BIOS: Extended Read
+ int $0x13 # Call BIOS
+ pop %dx # Restore
+ jc read.fail # Worked?
+ pop %cx # Restore
+ pop %si
+ ret # Return
+read.fail: cmp $ERROR_TIMEOUT,%ah # Timeout?
+ je read.retry # Yes, Retry.
+read.error: mov %ah,%al # Save error
+ mov $hex_error,%di # Format it
+ call hex8 # as hex
+ mov $msg_badread,%si # Display Read error message
+
+#
+# Display error message at [SI] and halt.
+#
+error: call putstr # Display message
+halt: hlt
+ jmp halt # Spin
+
+#
+# Display a null-terminated string.
+#
+# Trashes: AX, SI
+#
+putstr: push %bx # Save
+putstr.load: lodsb # load %al from %ds:(%si)
+ test %al,%al # stop at null
+ jnz putstr.putc # if the char != null, output it
+ pop %bx # Restore
+ ret # return when null is hit
+putstr.putc: call putc # output char
+ jmp putstr.load # next char
+
+#
+# Display a single char.
+#
+putc: mov $0x7,%bx # attribute for output
+ mov $0xe,%ah # BIOS: put_char
+ int $0x10 # call BIOS, print char in %al
+ ret # Return to caller
+
+#
+# Output the "twiddle"
+#
+twiddle: push %ax # Save
+ push %bx # Save
+ mov twiddle_index,%al # Load index
+ mov $twiddle_chars,%bx # Address table
+ inc %al # Next
+ and $3,%al # char
+ mov %al,twiddle_index # Save index for next call
+ xlat # Get char
+ call putc # Output it
+ mov $8,%al # Backspace
+ call putc # Output it
+ pop %bx # Restore
+ pop %ax # Restore
+ ret
+
+#
+# Enable A20. Put an upper limit on the amount of time we wait for the
+# keyboard controller to get ready (65K x ISA access time). If
+# we wait more than that amount, the hardware is probably
+# legacy-free and simply doesn't have a keyboard controller.
+# Thus, the A20 line is already enabled.
+#
+seta20: cli # Disable interrupts
+ xor %cx,%cx # Clear
+seta20.1: inc %cx # Increment, overflow?
+ jz seta20.3 # Yes
+ in $0x64,%al # Get status
+ test $0x2,%al # Busy?
+ jnz seta20.1 # Yes
+ mov $0xd1,%al # Command: Write
+ out %al,$0x64 # output port
+seta20.2: in $0x64,%al # Get status
+ test $0x2,%al # Busy?
+ jnz seta20.2 # Yes
+ mov $0xdf,%al # Enable
+ out %al,$0x60 # A20
+seta20.3: sti # Enable interrupts
+ ret # To caller
+
+#
+# Convert AL to hex, saving the result to [EDI].
+#
+hex8: pushl %eax # Save
+ shrb $0x4,%al # Do upper
+ call hex8.1 # 4
+ popl %eax # Restore
+hex8.1: andb $0xf,%al # Get lower 4
+ cmpb $0xa,%al # Convert
+ sbbb $0x69,%al # to hex
+ das # digit
+ orb $0x20,%al # To lower case
+ stosb # Save char
+ ret # (Recursive)
+
+#
+# BTX client to start btxldr
+#
+ .code32
+btx_client: mov $(MEM_ARG_BTX-MEM_BTX_CLIENT+MEM_ARG_SIZE-4), %esi
+ # %ds:(%esi) -> end
+ # of boot[12] args
+ mov $(MEM_ARG_SIZE/4),%ecx # Number of words to push
+ std # Go backwards
+push_arg: lodsl # Read argument
+ push %eax # Push it onto the stack
+ loop push_arg # Push all of the arguments
+ cld # In case anyone depends on this
+ pushl MEM_ARG_BTX-MEM_BTX_CLIENT+MEM_ARG_SIZE # Entry point of
+ # the loader
+ push %eax # Emulate a near call
+ mov $0x1,%eax # 'exec' system call
+ int $INT_SYS # BTX system call
+btx_client_end:
+ .code16
+
+ .p2align 4
+#
+# Global descriptor table.
+#
+gdt: .word 0x0,0x0,0x0,0x0 # Null entry
+ .word 0xffff,0x0,0x9200,0xcf # SEL_SDATA
+ .word 0xffff,0x0,0x9200,0x0 # SEL_RDATA
+ .word 0xffff,0x0,0x9a00,0xcf # SEL_SCODE (32-bit)
+ .word 0xffff,0x0,0x9a00,0x8f # SEL_SCODE16 (16-bit)
+gdt.1:
+#
+# Pseudo-descriptors.
+#
+gdtdesc: .word gdt.1-gdt-1 # Limit
+ .long gdt # Base
+#
+# EDD Packet
+#
+edd_packet: .byte 0x10 # Length
+ .byte 0 # Reserved
+edd_len: .byte 0x0 # Num to read
+ .byte 0 # Reserved
+edd_addr: .word 0x0,0x0 # Seg:Off
+edd_lba: .quad 0x0 # LBA
+
+drive: .byte 0
+
+#
+# State for searching dir
+#
+rec_lba: .long 0x0 # LBA (adjusted for EA)
+rec_size: .long 0x0 # File size
+name_len: .byte 0x0 # Length of current name
+
+twiddle_index: .byte 0x0
+
+msg_welcome: .asciz "CD Loader 1.2\r\n\n"
+msg_bootinfo: .asciz "Building the boot loader arguments\r\n"
+msg_relocate: .asciz "Relocating the loader and the BTX\r\n"
+msg_jump: .asciz "Starting the BTX loader\r\n"
+msg_badread: .ascii "Read Error: 0x"
+hex_error: .asciz "00\r\n"
+msg_novd: .asciz "Could not find Primary Volume Descriptor\r\n"
+msg_lookup: .asciz "Looking up "
+msg_lookup2: .asciz "... "
+msg_lookupok: .asciz "Found\r\n"
+msg_lookupfail: .asciz "File not found\r\n"
+msg_load2big: .asciz "File too big\r\n"
+msg_failed: .asciz "Boot failed\r\n"
+twiddle_chars: .ascii "|/-\\"
+loader_paths: .asciz "/BOOT/LOADER"
+ .asciz "/boot/loader"
+ .byte 0
+
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/cdboot/cdboot.s
--- a/head/sys/boot/i386/cdboot/cdboot.s Wed Jul 25 16:42:35 2012 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,600 +0,0 @@
-#
-# Copyright (c) 2001 John Baldwin <jhb at 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.
-# 3. Neither the name of the author nor the names of any co-contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-#
-
-# $FreeBSD$
-
-#
-# This program is a freestanding boot program to load an a.out binary
-# from a CD-ROM booted with no emulation mode as described by the El
-# Torito standard. Due to broken BIOSen that do not load the desired
-# number of sectors, we try to fit this in as small a space as possible.
-#
-# Basically, we first create a set of boot arguments to pass to the loaded
-# binary. Then we attempt to load /boot/loader from the CD we were booted
-# off of.
-#
-
-#
-# Memory locations.
-#
- .set MEM_PAGE_SIZE,0x1000 # memory page size, 4k
- .set MEM_ARG,0x900 # Arguments at start
- .set MEM_ARG_BTX,0xa100 # Where we move them to so the
- # BTX client can see them
- .set MEM_ARG_SIZE,0x18 # Size of the arguments
- .set MEM_BTX_ADDRESS,0x9000 # where BTX lives
- .set MEM_BTX_ENTRY,0x9010 # where BTX starts to execute
- .set MEM_BTX_OFFSET,MEM_PAGE_SIZE # offset of BTX in the loader
- .set MEM_BTX_CLIENT,0xa000 # where BTX clients live
-#
-# a.out header fields
-#
- .set AOUT_TEXT,0x04 # text segment size
- .set AOUT_DATA,0x08 # data segment size
- .set AOUT_BSS,0x0c # zero'd BSS size
- .set AOUT_SYMBOLS,0x10 # symbol table
- .set AOUT_ENTRY,0x14 # entry point
- .set AOUT_HEADER,MEM_PAGE_SIZE # size of the a.out header
-#
-# Flags for kargs->bootflags
-#
- .set KARGS_FLAGS_CD,0x1 # flag to indicate booting from
- # CD loader
-#
-# Segment selectors.
-#
- .set SEL_SDATA,0x8 # Supervisor data
- .set SEL_RDATA,0x10 # Real mode data
- .set SEL_SCODE,0x18 # PM-32 code
- .set SEL_SCODE16,0x20 # PM-16 code
-#
-# BTX constants
-#
- .set INT_SYS,0x30 # BTX syscall interrupt
-#
-# Constants for reading from the CD.
-#
- .set ERROR_TIMEOUT,0x80 # BIOS timeout on read
- .set NUM_RETRIES,3 # Num times to retry
- .set SECTOR_SIZE,0x800 # size of a sector
- .set SECTOR_SHIFT,11 # number of place to shift
- .set BUFFER_LEN,0x100 # number of sectors in buffer
- .set MAX_READ,0x10000 # max we can read at a time
- .set MAX_READ_SEC,MAX_READ >> SECTOR_SHIFT
- .set MEM_READ_BUFFER,0x9000 # buffer to read from CD
- .set MEM_VOLDESC,MEM_READ_BUFFER # volume descriptor
- .set MEM_DIR,MEM_VOLDESC+SECTOR_SIZE # Lookup buffer
- .set VOLDESC_LBA,0x10 # LBA of vol descriptor
- .set VD_PRIMARY,1 # Primary VD
- .set VD_END,255 # VD Terminator
- .set VD_ROOTDIR,156 # Offset of Root Dir Record
- .set DIR_LEN,0 # Offset of Dir Record length
- .set DIR_EA_LEN,1 # Offset of EA length
- .set DIR_EXTENT,2 # Offset of 64-bit LBA
- .set DIR_SIZE,10 # Offset of 64-bit length
- .set DIR_NAMELEN,32 # Offset of 8-bit name len
- .set DIR_NAME,33 # Offset of dir name
-#
-# We expect to be loaded by the BIOS at 0x7c00 (standard boot loader entry
-# point)
-#
- .code16
- .globl start
- .org 0x0, 0x0
-#
-# Program start.
-#
-start: cld # string ops inc
- xor %ax,%ax # zero %ax
- mov %ax,%ss # setup the
- mov $start,%sp # stack
- mov %ax,%ds # setup the
- mov %ax,%es # data segments
- mov %dl,drive # Save BIOS boot device
- mov $msg_welcome,%si # %ds:(%si) -> welcome message
- call putstr # display the welcome message
-#
-# Setup the arguments that the loader is expecting from boot[12]
-#
- mov $msg_bootinfo,%si # %ds:(%si) -> boot args message
- call putstr # display the message
- mov $MEM_ARG,%bx # %ds:(%bx) -> boot args
- mov %bx,%di # %es:(%di) -> boot args
- xor %eax,%eax # zero %eax
- mov $(MEM_ARG_SIZE/4),%cx # Size of arguments in 32-bit
- # dwords
- rep # Clear the arguments
- stosl # to zero
- mov drive,%dl # Store BIOS boot device
- mov %dl,0x4(%bx) # in kargs->bootdev
- or $KARGS_FLAGS_CD,0x8(%bx) # kargs->bootflags |=
- # KARGS_FLAGS_CD
-#
-# Load Volume Descriptor
-#
- mov $VOLDESC_LBA,%eax # Set LBA of first VD
-load_vd: push %eax # Save %eax
- mov $1,%dh # One sector
- mov $MEM_VOLDESC,%ebx # Destination
- call read # Read it in
- cmpb $VD_PRIMARY,(%bx) # Primary VD?
- je have_vd # Yes
- pop %eax # Prepare to
- inc %eax # try next
- cmpb $VD_END,(%bx) # Last VD?
- jne load_vd # No, read next
- mov $msg_novd,%si # No VD
- jmp error # Halt
-have_vd: # Have Primary VD
-#
-# Try to look up the loader binary using the paths in the loader_paths
-# array.
-#
- mov $loader_paths,%si # Point to start of array
-lookup_path: push %si # Save file name pointer
- call lookup # Try to find file
- pop %di # Restore file name pointer
- jnc lookup_found # Found this file
- xor %al,%al # Look for next
- mov $0xffff,%cx # path name by
- repnz # scanning for
- scasb # nul char
- mov %di,%si # Point %si at next path
- mov (%si),%al # Get first char of next path
- or %al,%al # Is it double nul?
- jnz lookup_path # No, try it.
- mov $msg_failed,%si # Failed message
- jmp error # Halt
-lookup_found: # Found a loader file
-#
-# Load the binary into the buffer. Due to real mode addressing limitations
-# we have to read it in 64k chunks.
-#
- mov DIR_SIZE(%bx),%eax # Read file length
- add $SECTOR_SIZE-1,%eax # Convert length to sectors
- shr $SECTOR_SHIFT,%eax
- cmp $BUFFER_LEN,%eax
- jbe load_sizeok
- mov $msg_load2big,%si # Error message
- call error
-load_sizeok: movzbw %al,%cx # Num sectors to read
- mov DIR_EXTENT(%bx),%eax # Load extent
- xor %edx,%edx
- mov DIR_EA_LEN(%bx),%dl
- add %edx,%eax # Skip extended
- mov $MEM_READ_BUFFER,%ebx # Read into the buffer
-load_loop: mov %cl,%dh
- cmp $MAX_READ_SEC,%cl # Truncate to max read size
- jbe load_notrunc
- mov $MAX_READ_SEC,%dh
-load_notrunc: sub %dh,%cl # Update count
- push %eax # Save
- call read # Read it in
- pop %eax # Restore
- add $MAX_READ_SEC,%eax # Update LBA
- add $MAX_READ,%ebx # Update dest addr
- jcxz load_done # Done?
- jmp load_loop # Keep going
-load_done:
-#
-# Turn on the A20 address line
-#
- call seta20 # Turn A20 on
-#
-# Relocate the loader and BTX using a very lazy protected mode
-#
- mov $msg_relocate,%si # Display the
- call putstr # relocation message
- mov MEM_READ_BUFFER+AOUT_ENTRY,%edi # %edi is the destination
- mov $(MEM_READ_BUFFER+AOUT_HEADER),%esi # %esi is
- # the start of the text
- # segment
- mov MEM_READ_BUFFER+AOUT_TEXT,%ecx # %ecx = length of the text
- # segment
- push %edi # Save entry point for later
- lgdt gdtdesc # setup our own gdt
- cli # turn off interrupts
- mov %cr0,%eax # Turn on
- or $0x1,%al # protected
- mov %eax,%cr0 # mode
- ljmp $SEL_SCODE,$pm_start # long jump to clear the
- # instruction pre-fetch queue
- .code32
-pm_start: mov $SEL_SDATA,%ax # Initialize
- mov %ax,%ds # %ds and
- mov %ax,%es # %es to a flat selector
- rep # Relocate the
- movsb # text segment
- add $(MEM_PAGE_SIZE - 1),%edi # pad %edi out to a new page
- and $~(MEM_PAGE_SIZE - 1),%edi # for the data segment
- mov MEM_READ_BUFFER+AOUT_DATA,%ecx # size of the data segment
- rep # Relocate the
- movsb # data segment
- mov MEM_READ_BUFFER+AOUT_BSS,%ecx # size of the bss
- xor %eax,%eax # zero %eax
- add $3,%cl # round %ecx up to
- shr $2,%ecx # a multiple of 4
- rep # zero the
- stosl # bss
- mov MEM_READ_BUFFER+AOUT_ENTRY,%esi # %esi -> relocated loader
- add $MEM_BTX_OFFSET,%esi # %esi -> BTX in the loader
- mov $MEM_BTX_ADDRESS,%edi # %edi -> where BTX needs to go
- movzwl 0xa(%esi),%ecx # %ecx -> length of BTX
- rep # Relocate
- movsb # BTX
- ljmp $SEL_SCODE16,$pm_16 # Jump to 16-bit PM
- .code16
-pm_16: mov $SEL_RDATA,%ax # Initialize
- mov %ax,%ds # %ds and
- mov %ax,%es # %es to a real mode selector
- mov %cr0,%eax # Turn off
- and $~0x1,%al # protected
- mov %eax,%cr0 # mode
- ljmp $0,$pm_end # Long jump to clear the
- # instruction pre-fetch queue
-pm_end: sti # Turn interrupts back on now
-#
-# Copy the BTX client to MEM_BTX_CLIENT
-#
- xor %ax,%ax # zero %ax and set
- mov %ax,%ds # %ds and %es
- mov %ax,%es # to segment 0
- mov $MEM_BTX_CLIENT,%di # Prepare to relocate
- mov $btx_client,%si # the simple btx client
- mov $(btx_client_end-btx_client),%cx # length of btx client
- rep # Relocate the
- movsb # simple BTX client
-#
-# Copy the boot[12] args to where the BTX client can see them
-#
- mov $MEM_ARG,%si # where the args are at now
- mov $MEM_ARG_BTX,%di # where the args are moving to
- mov $(MEM_ARG_SIZE/4),%cx # size of the arguments in longs
- rep # Relocate
- movsl # the words
-#
-# Save the entry point so the client can get to it later on
-#
- pop %eax # Restore saved entry point
- stosl # and add it to the end of
- # the arguments
-#
-# Now we just start up BTX and let it do the rest
-#
- mov $msg_jump,%si # Display the
- call putstr # jump message
- ljmp $0,$MEM_BTX_ENTRY # Jump to the BTX entry point
-
-#
-# Lookup the file in the path at [SI] from the root directory.
-#
-# Trashes: All but BX
-# Returns: CF = 0 (success), BX = pointer to record
-# CF = 1 (not found)
-#
-lookup: mov $VD_ROOTDIR+MEM_VOLDESC,%bx # Root directory record
- push %si
- mov $msg_lookup,%si # Display lookup message
- call putstr
- pop %si
- push %si
- call putstr
- mov $msg_lookup2,%si
- call putstr
- pop %si
-lookup_dir: lodsb # Get first char of path
- cmp $0,%al # Are we done?
- je lookup_done # Yes
- cmp $'/',%al # Skip path separator.
- je lookup_dir
- dec %si # Undo lodsb side effect
- call find_file # Lookup first path item
- jnc lookup_dir # Try next component
- mov $msg_lookupfail,%si # Not found message
- call putstr
- stc # Set carry
- ret
- jmp error
-lookup_done: mov $msg_lookupok,%si # Success message
- call putstr
- clc # Clear carry
- ret
-
-#
-# Lookup file at [SI] in directory whose record is at [BX].
-#
-# Trashes: All but returns
-# Returns: CF = 0 (success), BX = pointer to record, SI = next path item
-# CF = 1 (not found), SI = preserved
-#
-find_file: mov DIR_EXTENT(%bx),%eax # Load extent
- xor %edx,%edx
- mov DIR_EA_LEN(%bx),%dl
- add %edx,%eax # Skip extended attributes
- mov %eax,rec_lba # Save LBA
- mov DIR_SIZE(%bx),%eax # Save size
- mov %eax,rec_size
- xor %cl,%cl # Zero length
- push %si # Save
-ff.namelen: inc %cl # Update length
- lodsb # Read char
- cmp $0,%al # Nul?
- je ff.namedone # Yes
- cmp $'/',%al # Path separator?
- jnz ff.namelen # No, keep going
-ff.namedone: dec %cl # Adjust length and save
- mov %cl,name_len
- pop %si # Restore
-ff.load: mov rec_lba,%eax # Load LBA
- mov $MEM_DIR,%ebx # Address buffer
- mov $1,%dh # One sector
- call read # Read directory block
- incl rec_lba # Update LBA to next block
-ff.scan: mov %ebx,%edx # Check for EOF
- sub $MEM_DIR,%edx
- cmp %edx,rec_size
- ja ff.scan.1
- stc # EOF reached
- ret
-ff.scan.1: cmpb $0,DIR_LEN(%bx) # Last record in block?
- je ff.nextblock
- push %si # Save
- movzbw DIR_NAMELEN(%bx),%si # Find end of string
-ff.checkver: cmpb $'0',DIR_NAME-1(%bx,%si) # Less than '0'?
- jb ff.checkver.1
- cmpb $'9',DIR_NAME-1(%bx,%si) # Greater than '9'?
- ja ff.checkver.1
- dec %si # Next char
- jnz ff.checkver
- jmp ff.checklen # All numbers in name, so
- # no version
-ff.checkver.1: movzbw DIR_NAMELEN(%bx),%cx
- cmp %cx,%si # Did we find any digits?
- je ff.checkdot # No
- cmpb $';',DIR_NAME-1(%bx,%si) # Check for semicolon
- jne ff.checkver.2
- dec %si # Skip semicolon
- mov %si,%cx
- mov %cl,DIR_NAMELEN(%bx) # Adjust length
- jmp ff.checkdot
-ff.checkver.2: mov %cx,%si # Restore %si to end of string
-ff.checkdot: cmpb $'.',DIR_NAME-1(%bx,%si) # Trailing dot?
- jne ff.checklen # No
- decb DIR_NAMELEN(%bx) # Adjust length
-ff.checklen: pop %si # Restore
- movzbw name_len,%cx # Load length of name
- cmp %cl,DIR_NAMELEN(%bx) # Does length match?
- je ff.checkname # Yes, check name
-ff.nextrec: add DIR_LEN(%bx),%bl # Next record
- adc $0,%bh
- jmp ff.scan
-ff.nextblock: subl $SECTOR_SIZE,rec_size # Adjust size
- jnc ff.load # If subtract ok, keep going
- ret # End of file, so not found
-ff.checkname: lea DIR_NAME(%bx),%di # Address name in record
- push %si # Save
- repe cmpsb # Compare name
- je ff.match # We have a winner!
- pop %si # Restore
- jmp ff.nextrec # Keep looking.
-ff.match: add $2,%sp # Discard saved %si
- clc # Clear carry
- ret
-
-#
-# Load DH sectors starting at LBA EAX into [EBX].
-#
-# Trashes: EAX
-#
-read: push %si # Save
- push %cx # Save since some BIOSs trash
- mov %eax,edd_lba # LBA to read from
- mov %ebx,%eax # Convert address
- shr $4,%eax # to segment
- mov %ax,edd_addr+0x2 # and store
-read.retry: call twiddle # Entertain the user
- push %dx # Save
- mov $edd_packet,%si # Address Packet
- mov %dh,edd_len # Set length
- mov drive,%dl # BIOS Device
- mov $0x42,%ah # BIOS: Extended Read
- int $0x13 # Call BIOS
- pop %dx # Restore
- jc read.fail # Worked?
- pop %cx # Restore
- pop %si
- ret # Return
-read.fail: cmp $ERROR_TIMEOUT,%ah # Timeout?
- je read.retry # Yes, Retry.
-read.error: mov %ah,%al # Save error
- mov $hex_error,%di # Format it
- call hex8 # as hex
- mov $msg_badread,%si # Display Read error message
-
-#
-# Display error message at [SI] and halt.
-#
-error: call putstr # Display message
-halt: hlt
- jmp halt # Spin
-
-#
-# Display a null-terminated string.
-#
-# Trashes: AX, SI
-#
-putstr: push %bx # Save
-putstr.load: lodsb # load %al from %ds:(%si)
- test %al,%al # stop at null
- jnz putstr.putc # if the char != null, output it
- pop %bx # Restore
- ret # return when null is hit
-putstr.putc: call putc # output char
- jmp putstr.load # next char
-
-#
-# Display a single char.
-#
-putc: mov $0x7,%bx # attribute for output
- mov $0xe,%ah # BIOS: put_char
- int $0x10 # call BIOS, print char in %al
- ret # Return to caller
-
-#
-# Output the "twiddle"
-#
-twiddle: push %ax # Save
- push %bx # Save
- mov twiddle_index,%al # Load index
- mov $twiddle_chars,%bx # Address table
- inc %al # Next
- and $3,%al # char
- mov %al,twiddle_index # Save index for next call
- xlat # Get char
- call putc # Output it
- mov $8,%al # Backspace
- call putc # Output it
- pop %bx # Restore
- pop %ax # Restore
- ret
-
-#
-# Enable A20. Put an upper limit on the amount of time we wait for the
-# keyboard controller to get ready (65K x ISA access time). If
-# we wait more than that amount, the hardware is probably
-# legacy-free and simply doesn't have a keyboard controller.
-# Thus, the A20 line is already enabled.
-#
-seta20: cli # Disable interrupts
- xor %cx,%cx # Clear
-seta20.1: inc %cx # Increment, overflow?
- jz seta20.3 # Yes
- in $0x64,%al # Get status
- test $0x2,%al # Busy?
- jnz seta20.1 # Yes
- mov $0xd1,%al # Command: Write
- out %al,$0x64 # output port
-seta20.2: in $0x64,%al # Get status
- test $0x2,%al # Busy?
- jnz seta20.2 # Yes
- mov $0xdf,%al # Enable
- out %al,$0x60 # A20
-seta20.3: sti # Enable interrupts
- ret # To caller
-
-#
-# Convert AL to hex, saving the result to [EDI].
-#
-hex8: pushl %eax # Save
- shrb $0x4,%al # Do upper
- call hex8.1 # 4
- popl %eax # Restore
-hex8.1: andb $0xf,%al # Get lower 4
- cmpb $0xa,%al # Convert
- sbbb $0x69,%al # to hex
- das # digit
- orb $0x20,%al # To lower case
- stosb # Save char
- ret # (Recursive)
-
-#
-# BTX client to start btxldr
-#
- .code32
-btx_client: mov $(MEM_ARG_BTX-MEM_BTX_CLIENT+MEM_ARG_SIZE-4), %esi
- # %ds:(%esi) -> end
- # of boot[12] args
- mov $(MEM_ARG_SIZE/4),%ecx # Number of words to push
- std # Go backwards
-push_arg: lodsl # Read argument
- push %eax # Push it onto the stack
- loop push_arg # Push all of the arguments
- cld # In case anyone depends on this
- pushl MEM_ARG_BTX-MEM_BTX_CLIENT+MEM_ARG_SIZE # Entry point of
- # the loader
- push %eax # Emulate a near call
- mov $0x1,%eax # 'exec' system call
- int $INT_SYS # BTX system call
-btx_client_end:
- .code16
-
- .p2align 4
-#
-# Global descriptor table.
-#
-gdt: .word 0x0,0x0,0x0,0x0 # Null entry
- .word 0xffff,0x0,0x9200,0xcf # SEL_SDATA
- .word 0xffff,0x0,0x9200,0x0 # SEL_RDATA
- .word 0xffff,0x0,0x9a00,0xcf # SEL_SCODE (32-bit)
- .word 0xffff,0x0,0x9a00,0x8f # SEL_SCODE16 (16-bit)
-gdt.1:
-#
-# Pseudo-descriptors.
-#
-gdtdesc: .word gdt.1-gdt-1 # Limit
- .long gdt # Base
-#
-# EDD Packet
-#
-edd_packet: .byte 0x10 # Length
- .byte 0 # Reserved
-edd_len: .byte 0x0 # Num to read
- .byte 0 # Reserved
-edd_addr: .word 0x0,0x0 # Seg:Off
-edd_lba: .quad 0x0 # LBA
-
-drive: .byte 0
-
-#
-# State for searching dir
-#
-rec_lba: .long 0x0 # LBA (adjusted for EA)
-rec_size: .long 0x0 # File size
-name_len: .byte 0x0 # Length of current name
-
-twiddle_index: .byte 0x0
-
-msg_welcome: .asciz "CD Loader 1.2\r\n\n"
-msg_bootinfo: .asciz "Building the boot loader arguments\r\n"
-msg_relocate: .asciz "Relocating the loader and the BTX\r\n"
-msg_jump: .asciz "Starting the BTX loader\r\n"
-msg_badread: .ascii "Read Error: 0x"
-hex_error: .asciz "00\r\n"
-msg_novd: .asciz "Could not find Primary Volume Descriptor\r\n"
-msg_lookup: .asciz "Looking up "
-msg_lookup2: .asciz "... "
-msg_lookupok: .asciz "Found\r\n"
-msg_lookupfail: .asciz "File not found\r\n"
-msg_load2big: .asciz "File too big\r\n"
-msg_failed: .asciz "Boot failed\r\n"
-twiddle_chars: .ascii "|/-\\"
-loader_paths: .asciz "/BOOT/LOADER"
- .asciz "/boot/loader"
- .byte 0
-
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/common/bootargs.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/boot/i386/common/bootargs.h Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 2012 Andriy Gapon <avg at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ *
+ * $FreeBSD: head/sys/boot/i386/common/bootargs.h 235154 2012-05-09 08:04:29Z avg $
+ */
+
+#ifndef _BOOT_I386_ARGS_H_
+#define _BOOT_I386_ARGS_H_
+
+#define KARGS_FLAGS_CD 0x1
+#define KARGS_FLAGS_PXE 0x2
+#define KARGS_FLAGS_ZFS 0x4
+#define KARGS_FLAGS_EXTARG 0x8 /* variably sized extended argument */
+
+#define BOOTARGS_SIZE 24 /* sizeof(struct bootargs) */
+#define BA_BOOTFLAGS 8 /* offsetof(struct bootargs, bootflags) */
+#define BA_BOOTINFO 20 /* offsetof(struct bootargs, bootinfo) */
+#define BI_SIZE 48 /* offsetof(struct bootinfo, bi_size) */
+
+/*
+ * We reserve some space above BTX allocated stack for the arguments
+ * and certain data that could hang off them. Currently only struct bootinfo
+ * is supported in that category. The bootinfo is placed at the top
+ * of the arguments area and the actual arguments are placed at ARGOFF offset
+ * from the top and grow towards the top. Hopefully we have enough space
+ * for bootinfo and the arguments to not run into each other.
+ * Arguments area below ARGOFF is reserved for future use.
+ */
+#define ARGSPACE 0x1000 /* total size of the BTX args area */
+#define ARGOFF 0x800 /* actual args offset within the args area */
+#define ARGADJ (ARGSPACE - ARGOFF)
+
+#ifndef __ASSEMBLER__
+
+struct bootargs
+{
+ uint32_t howto;
+ uint32_t bootdev;
+ uint32_t bootflags;
+ union {
+ struct {
+ uint32_t pxeinfo;
+ uint32_t reserved;
+ };
+ uint64_t zfspool;
+ };
+ uint32_t bootinfo;
+
+ /*
+ * If KARGS_FLAGS_EXTARG is set in bootflags, then the above fields
+ * are followed by a uint32_t field that specifies a size of the
+ * extended arguments (including the size field).
+ */
+};
+
+#endif /*__ASSEMBLER__*/
+
+#endif /* !_BOOT_I386_ARGS_H_ */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/efi/reloc.c
--- a/head/sys/boot/i386/efi/reloc.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/efi/reloc.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,21 +25,12 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/boot/i386/efi/reloc.c 235153 2012-05-09 07:55:42Z avg $");
#include <sys/types.h>
#include <sys/elf32.h>
#include <efi.h>
-
-/*
- * XXX: we can't include sys/systm.h.
- */
-#ifndef CTASSERT /* Allow lint to override */
-#define CTASSERT(x) _CTASSERT(x, __LINE__)
-#define _CTASSERT(x, y) __CTASSERT(x, y)
-#define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1]
-#endif
-
+#include <bootstrap.h>
/*
* A simple relocator for IA32 EFI binaries.
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/gptboot/gptboot.c
--- a/head/sys/boot/i386/gptboot/gptboot.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/gptboot/gptboot.c Wed Jul 25 16:45:04 2012 +0300
@@ -14,7 +14,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/boot/i386/gptboot/gptboot.c 226506 2011-10-18 09:46:52Z des $");
+__FBSDID("$FreeBSD: head/sys/boot/i386/gptboot/gptboot.c 235988 2012-05-25 09:36:39Z gleb $");
#include <sys/param.h>
#include <sys/gpt.h>
@@ -90,14 +90,13 @@
void exit(int);
static void load(void);
static int parse(char *, int *);
-static int xfsread(ino_t, void *, size_t);
static int dskread(void *, daddr_t, unsigned);
static uint32_t memsize(void);
#include "ufsread.c"
static inline int
-xfsread(ino_t inode, void *buf, size_t nbyte)
+xfsread(ufs_ino_t inode, void *buf, size_t nbyte)
{
if ((size_t)fsread(inode, buf, nbyte) != nbyte) {
@@ -138,7 +137,7 @@
{
char cmd[512], cmdtmp[512];
int autoboot, dskupdated;
- ino_t ino;
+ ufs_ino_t ino;
dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base);
v86.ctl = V86_FLAGS;
@@ -247,7 +246,7 @@
static Elf32_Phdr ep[2];
static Elf32_Shdr es[2];
caddr_t p;
- ino_t ino;
+ ufs_ino_t ino;
uint32_t addr, x;
int fmt, i, j;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/libi386/Makefile
--- a/head/sys/boot/i386/libi386/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/libi386/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-# $FreeBSD: head/sys/boot/i386/libi386/Makefile 232263 2012-02-28 18:30:18Z dim $
+# $FreeBSD: head/sys/boot/i386/libi386/Makefile 235329 2012-05-12 09:03:30Z avg $
#
LIB= i386
INTERNALLIB=
@@ -9,6 +9,8 @@
elf64_freebsd.c \
i386_copy.c i386_module.c nullconsole.c pxe.c pxetramp.s \
smbios.c time.c vidconsole.c amd64_tramp.S spinconsole.c
+.PATH: ${.CURDIR}/../../zfs
+SRCS+= devicename_stubs.c
# Enable PXE TFTP or NFS support, not both.
.if defined(LOADER_TFTP_SUPPORT)
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/libi386/biosdisk.c
--- a/head/sys/boot/i386/libi386/biosdisk.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/libi386/biosdisk.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/boot/i386/libi386/biosdisk.c 226748 2011-10-25 19:54:06Z jhb $");
+__FBSDID("$FreeBSD: head/sys/boot/i386/libi386/biosdisk.c 235155 2012-05-09 08:05:50Z avg $");
/*
* BIOS disk device handling.
@@ -55,7 +55,6 @@
#define BIOS_NUMDRIVES 0x475
#define BIOSDISK_SECSIZE 512
#define BUFSIZE (1 * BIOSDISK_SECSIZE)
-#define MAXBDDEV MAXDEV
#define DT_ATAPI 0x10 /* disk type for ATAPI floppies */
#define WDMAJOR 0 /* major numbers for devices we frontend for */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/libi386/biospnp.c
--- a/head/sys/boot/i386/libi386/biospnp.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/libi386/biospnp.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/boot/i386/libi386/biospnp.c 236213 2012-05-29 01:48:06Z kevlo $");
/*
* PnP BIOS enumerator.
@@ -276,6 +276,7 @@
break;
}
}
+ va_end(ap);
/* BIOS segment last */
*(u_int16_t *)argp = pnp_Icheck->pnp_rmds;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/libi386/devicename.c
--- a/head/sys/boot/i386/libi386/devicename.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/libi386/devicename.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,13 +25,14 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/boot/i386/libi386/devicename.c 235329 2012-05-12 09:03:30Z avg $");
#include <stand.h>
#include <string.h>
#include <sys/disklabel.h>
#include "bootstrap.h"
#include "libi386.h"
+#include "../zfs/libzfs.h"
static int i386_parsedev(struct i386_devdesc **dev, const char *devspec, const char **path);
@@ -171,7 +172,6 @@
case DEVT_CD:
case DEVT_NET:
- case DEVT_ZFS:
unit = 0;
if (*np && (*np != ':')) {
@@ -192,7 +192,11 @@
if (path != NULL)
*path = (*cp == 0) ? cp : cp + 1;
break;
-
+ case DEVT_ZFS:
+ err = zfs_parsedev((struct zfs_devdesc *)idev, np, path);
+ if (err != 0)
+ goto fail;
+ break;
default:
err = EINVAL;
goto fail;
@@ -247,9 +251,10 @@
break;
case DEVT_NET:
- case DEVT_ZFS:
sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
break;
+ case DEVT_ZFS:
+ return(zfs_fmtdev(vdev));
}
return(buf);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/libi386/libi386.h
--- a/head/sys/boot/i386/libi386/libi386.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/libi386/libi386.h Wed Jul 25 16:45:04 2012 +0300
@@ -23,14 +23,15 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/boot/i386/libi386/libi386.h 229435 2012-01-03 22:36:12Z kib $
+ * $FreeBSD: head/sys/boot/i386/libi386/libi386.h 235329 2012-05-12 09:03:30Z avg $
*/
/*
* i386 fully-qualified device descriptor.
* Note, this must match the 'struct devdesc' declaration
- * in bootstrap.h.
+ * in bootstrap.h and also with struct zfs_devdesc for zfs
+ * support.
*/
struct i386_devdesc
{
@@ -49,6 +50,12 @@
{
void *data;
} bioscd;
+ struct
+ {
+ void *data;
+ uint64_t pool_guid;
+ uint64_t root_guid;
+ } zfs;
} d_kind;
};
@@ -58,7 +65,8 @@
extern struct devdesc currdev; /* our current device */
-#define MAXDEV 31 /* maximum number of distinct devices */
+#define MAXDEV 31 /* maximum number of distinct devices */
+#define MAXBDDEV MAXDEV
/* exported devices XXX rename? */
extern struct devsw bioscd;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/loader/Makefile
--- a/head/sys/boot/i386/loader/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/loader/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-# $FreeBSD: head/sys/boot/i386/loader/Makefile 227726 2011-11-19 14:42:06Z miwi $
+# $FreeBSD: head/sys/boot/i386/loader/Makefile 235537 2012-05-17 10:11:18Z gber $
.include <bsd.own.mk>
MK_SSP= no
@@ -20,9 +20,7 @@
# Set by zfsloader Makefile
.if defined(LOADER_ZFS_SUPPORT)
CFLAGS+= -DLOADER_ZFS_SUPPORT
-LIBZFS= ${.OBJDIR}/../../zfs/libzfsboot.a
-.else
-LIBZFS=
+LIBZFSBOOT= ${.OBJDIR}/../../zfs/libzfsboot.a
.endif
# Enable PXE TFTP or NFS support, not both.
@@ -55,6 +53,9 @@
.if !defined(LOADER_NO_GPT_SUPPORT)
CFLAGS+= -DLOADER_GPT_SUPPORT
.endif
+.if defined(LOADER_NANDFS_SUPPORT)
+CFLAGS+= -DLOADER_NANDFS_SUPPORT
+.endif
# Always add MI sources
.PATH: ${.CURDIR}/../../common
@@ -119,8 +120,8 @@
# XXX crt0.o needs to be first for pxeboot(8) to work
OBJS= ${BTXCRT}
-DPADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFS} ${LIBI386} ${LIBSTAND}
-LDADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFS} ${LIBI386} ${LIBSTAND}
+DPADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBSTAND}
+LDADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBSTAND}
.include <bsd.prog.mk>
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/loader/conf.c
--- a/head/sys/boot/i386/loader/conf.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/loader/conf.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,11 +25,14 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/boot/i386/loader/conf.c 235537 2012-05-17 10:11:18Z gber $");
#include <stand.h>
#include <bootstrap.h>
#include "libi386/libi386.h"
+#if defined(LOADER_ZFS_SUPPORT)
+#include "../zfs/libzfs.h"
+#endif
/*
* We could use linker sets for some or all of these, but
@@ -50,10 +53,6 @@
extern struct devsw fwohci;
#endif
-#if defined(LOADER_ZFS_SUPPORT)
-extern struct devsw zfs_dev;
-#endif
-
/* Exported for libstand */
struct devsw *devsw[] = {
&bioscd,
@@ -70,15 +69,14 @@
NULL
};
-#if defined(LOADER_ZFS_SUPPORT)
-extern struct fs_ops zfs_fsops;
-#endif
-
struct fs_ops *file_system[] = {
&ufs_fsops,
&ext2fs_fsops,
&dosfs_fsops,
&cd9660_fsops,
+#if defined(LOADER_NANDFS_SUPPORT)
+ &nandfs_fsops,
+#endif
&splitfs_fsops,
#if defined(LOADER_ZFS_SUPPORT)
&zfs_fsops,
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/loader/main.c
--- a/head/sys/boot/i386/loader/main.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/loader/main.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/boot/i386/loader/main.c 235329 2012-05-12 09:03:30Z avg $");
/*
* MD bootstrap main() and assorted miscellaneous
@@ -33,34 +33,28 @@
*/
#include <stand.h>
+#include <stddef.h>
#include <string.h>
#include <machine/bootinfo.h>
#include <machine/psl.h>
#include <sys/reboot.h>
#include "bootstrap.h"
+#include "common/bootargs.h"
#include "libi386/libi386.h"
#include "btxv86.h"
-#define KARGS_FLAGS_CD 0x1
-#define KARGS_FLAGS_PXE 0x2
-#define KARGS_FLAGS_ZFS 0x4
+#ifdef LOADER_ZFS_SUPPORT
+#include "../zfs/libzfs.h"
+#endif
+
+CTASSERT(sizeof(struct bootargs) == BOOTARGS_SIZE);
+CTASSERT(offsetof(struct bootargs, bootinfo) == BA_BOOTINFO);
+CTASSERT(offsetof(struct bootargs, bootflags) == BA_BOOTFLAGS);
+CTASSERT(offsetof(struct bootinfo, bi_size) == BI_SIZE);
/* Arguments passed in from the boot1/boot2 loader */
-static struct
-{
- u_int32_t howto;
- u_int32_t bootdev;
- u_int32_t bootflags;
- union {
- struct {
- u_int32_t pxeinfo;
- u_int32_t res2;
- };
- uint64_t zfspool;
- };
- u_int32_t bootinfo;
-} *kargs;
+static struct bootargs *kargs;
static u_int32_t initial_howto;
static u_int32_t initial_bootdev;
@@ -72,6 +66,9 @@
static int isa_inb(int port);
static void isa_outb(int port, int value);
void exit(int code);
+#ifdef LOADER_ZFS_SUPPORT
+static void i386_zfs_probe(void);
+#endif
/* from vers.c */
extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
@@ -163,6 +160,9 @@
archsw.arch_readin = i386_readin;
archsw.arch_isainb = isa_inb;
archsw.arch_isaoutb = isa_outb;
+#ifdef LOADER_ZFS_SUPPORT
+ archsw.arch_zfs_probe = i386_zfs_probe;
+#endif
/*
* March through the device switch probing for things.
@@ -206,8 +206,11 @@
static void
extract_currdev(void)
{
- struct i386_devdesc new_currdev;
- int biosdev = -1;
+ struct i386_devdesc new_currdev;
+#ifdef LOADER_ZFS_SUPPORT
+ struct zfs_boot_args *zargs;
+#endif
+ int biosdev = -1;
/* Assume we are booting from a BIOS disk by default */
new_currdev.d_dev = &biosdisk;
@@ -228,6 +231,24 @@
new_currdev.d_kind.biosdisk.partition = 0;
biosdev = -1;
}
+#ifdef LOADER_ZFS_SUPPORT
+ } else if ((kargs->bootflags & KARGS_FLAGS_ZFS) != 0) {
+ zargs = NULL;
+ /* check for new style extended argument */
+ if ((kargs->bootflags & KARGS_FLAGS_EXTARG) != 0)
+ zargs = (struct zfs_boot_args *)(kargs + 1);
+
+ if (zargs != NULL && zargs->size >= sizeof(*zargs)) {
+ /* sufficient data is provided */
+ new_currdev.d_kind.zfs.pool_guid = zargs->pool;
+ new_currdev.d_kind.zfs.root_guid = zargs->root;
+ } else {
+ /* old style zfsboot block */
+ new_currdev.d_kind.zfs.pool_guid = kargs->zfspool;
+ new_currdev.d_kind.zfs.root_guid = 0;
+ }
+ new_currdev.d_dev = &zfs_dev;
+#endif
} else if ((initial_bootdev & B_MAGICMASK) != B_DEVMAGIC) {
/* The passed-in boot device is bad */
new_currdev.d_kind.biosdisk.slice = -1;
@@ -248,7 +269,7 @@
biosdev = 0x80 + B_UNIT(initial_bootdev); /* assume harddisk */
}
new_currdev.d_type = new_currdev.d_dev->dv_type;
-
+
/*
* If we are booting off of a BIOS disk and we didn't succeed in determining
* which one we booted off of, just use disk0: as a reasonable default.
@@ -259,33 +280,11 @@
"Guessed BIOS device 0x%x not found by probes, defaulting to disk0:\n", biosdev);
new_currdev.d_unit = 0;
}
+
env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&new_currdev),
i386_setcurrdev, env_nounset);
env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&new_currdev), env_noset,
env_nounset);
-
-#ifdef LOADER_ZFS_SUPPORT
- /*
- * If we were started from a ZFS-aware boot2, we can work out
- * which ZFS pool we are booting from.
- */
- if (kargs->bootflags & KARGS_FLAGS_ZFS) {
- /*
- * Dig out the pool guid and convert it to a 'unit number'
- */
- uint64_t guid;
- int unit;
- char devname[32];
- extern int zfs_guid_to_unit(uint64_t);
-
- guid = kargs->zfspool;
- unit = zfs_guid_to_unit(guid);
- if (unit >= 0) {
- sprintf(devname, "zfs%d", unit);
- setenv("currdev", devname, 1);
- }
- }
-#endif
}
COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
@@ -352,3 +351,30 @@
}
}
+#ifdef LOADER_ZFS_SUPPORT
+static void
+i386_zfs_probe(void)
+{
+ char devname[32];
+ int unit, slice;
+
+ /*
+ * Open all the disks we can find and see if we can reconstruct
+ * ZFS pools from them. Bogusly assumes that the disks are named
+ * diskN, diskNpM or diskNsM.
+ */
+ for (unit = 0; unit < MAXBDDEV; unit++) {
+ sprintf(devname, "disk%d:", unit);
+ if (zfs_probe_dev(devname, NULL) == ENXIO)
+ continue;
+ for (slice = 1; slice <= 128; slice++) {
+ sprintf(devname, "disk%dp%d:", unit, slice);
+ zfs_probe_dev(devname, NULL);
+ }
+ for (slice = 1; slice <= 4; slice++) {
+ sprintf(devname, "disk%ds%d:", unit, slice);
+ zfs_probe_dev(devname, NULL);
+ }
+ }
+}
+#endif
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/pxeldr/Makefile
--- a/head/sys/boot/i386/pxeldr/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/pxeldr/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-# $FreeBSD: head/sys/boot/i386/pxeldr/Makefile 232263 2012-02-28 18:30:18Z dim $
+# $FreeBSD: head/sys/boot/i386/pxeldr/Makefile 235219 2012-05-10 09:47:04Z avg $
# Pick up ../Makefile.inc early.
.include <bsd.init.mk>
@@ -23,6 +23,8 @@
CFLAGS+=-DALWAYS_SERIAL
.endif
+CFLAGS+=-I${.CURDIR}/../common
+
LOADERBIN= ${.OBJDIR}/../loader/loader.bin
CLEANFILES+= ${BOOT}.tmp
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/pxeldr/pxeldr.S
--- a/head/sys/boot/i386/pxeldr/pxeldr.S Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/pxeldr/pxeldr.S Wed Jul 25 16:45:04 2012 +0300
@@ -12,7 +12,7 @@
* warranties of merchantability and fitness for a particular
* purpose.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/boot/i386/pxeldr/pxeldr.S 235219 2012-05-10 09:47:04Z avg $
*/
/*
@@ -26,6 +26,7 @@
*/
#include <sys/reboot.h>
+#include <bootargs.h>
/*
* Memory locations.
@@ -50,11 +51,6 @@
.set AOUT_ENTRY,0x14 # entry point
.set AOUT_HEADER,MEM_PAGE_SIZE # size of the a.out header
/*
- * Flags for kargs->bootflags
- */
- .set KARGS_FLAGS_PXE,0x2 # flag to indicate booting from
- # PXE loader
-/*
* Segment selectors.
*/
.set SEL_SDATA,0x8 # Supervisor data
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/i386/zfsboot/zfsboot.c
--- a/head/sys/boot/i386/zfsboot/zfsboot.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/i386/zfsboot/zfsboot.c Wed Jul 25 16:45:04 2012 +0300
@@ -14,7 +14,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/boot/i386/zfsboot/zfsboot.c 234339 2012-04-16 10:43:06Z avg $");
+__FBSDID("$FreeBSD: head/sys/boot/i386/zfsboot/zfsboot.c 235329 2012-05-12 09:03:30Z avg $");
#include <sys/param.h>
#include <sys/errno.h>
@@ -41,9 +41,9 @@
#include "drv.h"
#include "util.h"
#include "cons.h"
+#include "bootargs.h"
-/* Hint to loader that we came from ZFS */
-#define KARGS_FLAGS_ZFS 0x4
+#include "libzfs.h"
#define PATH_DOTCONFIG "/boot.config"
#define PATH_CONFIG "/boot/config"
@@ -63,8 +63,6 @@
#define TYPE_MAXHARD TYPE_DA
#define TYPE_FD 2
-#define MAXBDDEV 31
-
extern uint32_t _end;
#ifdef GPT
@@ -95,9 +93,12 @@
static char cmd[512];
static char cmddup[512];
static char kname[1024];
+static char rootname[256];
static int comspeed = SIOSPD;
static struct bootinfo bootinfo;
static uint32_t bootdev;
+static struct zfs_boot_args zfsargs;
+static struct zfsmount zfsmount;
vm_offset_t high_heap_base;
uint32_t bios_basemem, bios_extmem, high_heap_size;
@@ -174,7 +175,7 @@
/*
* Current ZFS pool
*/
-spa_t *spa;
+static spa_t *spa;
/*
* A wrapper for dskread that doesn't have to worry about whether the
@@ -213,7 +214,7 @@
xfsread(const dnode_phys_t *dnode, off_t *offp, void *buf, size_t nbyte)
{
if ((size_t)zfs_read(spa, dnode, offp, buf, nbyte) != nbyte) {
- printf("Invalid %s\n", "format");
+ printf("Invalid format\n");
return -1;
}
return 0;
@@ -533,10 +534,12 @@
}
}
- zfs_mount_pool(spa);
-
- if (zfs_lookup(spa, PATH_CONFIG, &dn) == 0 ||
- zfs_lookup(spa, PATH_DOTCONFIG, &dn) == 0) {
+ if (zfs_spa_init(spa) != 0 || zfs_mount(spa, 0, &zfsmount) != 0) {
+ printf("%s: failed to mount default pool %s\n",
+ BOOTPROG, spa->spa_name);
+ autoboot = 0;
+ } else if (zfs_lookup(&zfsmount, PATH_CONFIG, &dn) == 0 ||
+ zfs_lookup(&zfsmount, PATH_DOTCONFIG, &dn) == 0) {
off = 0;
zfs_read(spa, &dn, &off, cmd, sizeof(cmd));
}
@@ -571,11 +574,17 @@
/* Present the user with the boot2 prompt. */
for (;;) {
- if (!autoboot || !OPT_CHECK(RBX_QUIET))
- printf("\nFreeBSD/x86 boot\n"
- "Default: %s:%s\n"
- "boot: ",
- spa->spa_name, kname);
+ if (!autoboot || !OPT_CHECK(RBX_QUIET)) {
+ printf("\nFreeBSD/x86 boot\n");
+ if (zfs_rlookup(spa, zfsmount.rootobj, rootname) != 0)
+ printf("Default: %s:<0x%llx>:%s\n"
+ "boot: ",
+ spa->spa_name, zfsmount.rootobj, kname);
+ else
+ printf("Default: %s:%s:%s\n"
+ "boot: ",
+ spa->spa_name, rootname, kname);
+ }
if (ioctrl & IO_SERIAL)
sio_flush();
if (!autoboot || keyhit(5))
@@ -611,7 +620,8 @@
uint32_t addr, x;
int fmt, i, j;
- if (zfs_lookup(spa, kname, &dn)) {
+ if (zfs_lookup(&zfsmount, kname, &dn)) {
+ printf("\nCan't find %s\n", kname);
return;
}
off = 0;
@@ -685,12 +695,16 @@
}
bootinfo.bi_esymtab = VTOP(p);
bootinfo.bi_kernelname = VTOP(kname);
+ zfsargs.size = sizeof(zfsargs);
+ zfsargs.pool = zfsmount.spa->spa_guid;
+ zfsargs.root = zfsmount.rootobj;
__exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
bootdev,
- KARGS_FLAGS_ZFS,
+ KARGS_FLAGS_ZFS | KARGS_FLAGS_EXTARG,
(uint32_t) spa->spa_guid,
(uint32_t) (spa->spa_guid >> 32),
- VTOP(&bootinfo));
+ VTOP(&bootinfo),
+ zfsargs);
}
static int
@@ -742,7 +756,7 @@
} if (c == '?') {
dnode_phys_t dn;
- if (zfs_lookup(spa, arg, &dn) == 0) {
+ if (zfs_lookup(&zfsmount, arg, &dn) == 0) {
zap_list(spa, &dn);
}
return -1;
@@ -764,17 +778,32 @@
q = (char *) strchr(arg, ':');
if (q) {
spa_t *newspa;
+ uint64_t newroot;
*q++ = 0;
newspa = spa_find_by_name(arg);
if (newspa) {
+ arg = q;
spa = newspa;
- zfs_mount_pool(spa);
+ newroot = 0;
+ q = (char *) strchr(arg, ':');
+ if (q) {
+ *q++ = 0;
+ if (zfs_lookup_dataset(spa, arg, &newroot)) {
+ printf("\nCan't find dataset %s in ZFS pool %s\n",
+ arg, spa->spa_name);
+ return -1;
+ }
+ arg = q;
+ }
+ if (zfs_mount(spa, newroot, &zfsmount)) {
+ printf("\nCan't mount ZFS dataset\n");
+ return -1;
+ }
} else {
printf("\nCan't find ZFS pool %s\n", arg);
return -1;
}
- arg = q;
}
if ((i = ep - arg)) {
if ((size_t)i >= sizeof(kname))
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/ofw/libofw/Makefile
--- a/head/sys/boot/ofw/libofw/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/ofw/libofw/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-# $FreeBSD$
+# $FreeBSD: head/sys/boot/ofw/libofw/Makefile 235364 2012-05-12 20:27:33Z avg $
LIB= ofw
INTERNALLIB=
@@ -6,6 +6,8 @@
SRCS= devicename.c elf_freebsd.c ofw_console.c ofw_copy.c ofw_disk.c \
ofw_memory.c ofw_module.c ofw_net.c ofw_reboot.c \
ofw_time.c openfirm.c
+.PATH: ${.CURDIR}/../../zfs
+SRCS+= devicename_stubs.c
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/ofw/libofw/devicename.c
--- a/head/sys/boot/ofw/libofw/devicename.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/ofw/libofw/devicename.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,10 +25,13 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/boot/ofw/libofw/devicename.c 235364 2012-05-12 20:27:33Z avg $");
#include <stand.h>
+
+#include "bootstrap.h"
#include "libofw.h"
+#include "../zfs/libzfs.h"
static int ofw_parsedev(struct ofw_devdesc **, const char *, const char **);
@@ -76,8 +79,10 @@
phandle_t handle;
const char *p;
const char *s;
+ char *ep;
char name[256];
char type[64];
+ int err;
int len;
int i;
@@ -87,9 +92,10 @@
len = s - devspec;
bcopy(devspec, name, len);
name[len] = '\0';
- if ((handle = OF_finddevice(name)) == -1)
- break;
- if (OF_getprop(handle, "device_type", type, sizeof(type)) == -1)
+ if ((handle = OF_finddevice(name)) == -1) {
+ bcopy(name, type, len);
+ type[len] = '\0';
+ } else if (OF_getprop(handle, "device_type", type, sizeof(type)) == -1)
continue;
for (i = 0; (dv = devsw[i]) != NULL; i++) {
if (strncmp(dv->dv_name, type, strlen(dv->dv_name)) == 0)
@@ -109,6 +115,15 @@
strcpy(idev->d_path, name);
idev->d_dev = dv;
idev->d_type = dv->dv_type;
+ if (idev->d_type == DEVT_ZFS) {
+ p = devspec + strlen(dv->dv_name);
+ err = zfs_parsedev((struct zfs_devdesc *)idev, p, path);
+ if (err != 0) {
+ free(idev);
+ return (err);
+ }
+ }
+
if (dev == NULL) {
free(idev);
} else {
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/ofw/libofw/libofw.h
--- a/head/sys/boot/ofw/libofw/libofw.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/ofw/libofw/libofw.h Wed Jul 25 16:45:04 2012 +0300
@@ -22,7 +22,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/boot/ofw/libofw/libofw.h 235364 2012-05-12 20:27:33Z avg $
*/
#include "openfirm.h"
@@ -33,7 +33,13 @@
int d_type;
int d_unit;
ihandle_t d_handle;
- char d_path[256];
+ union {
+ char d_path[256];
+ struct {
+ uint64_t pool_guid;
+ uint64_t root_guid;
+ };
+ };
};
extern int ofw_getdev(void **vdev, const char *devspec, const char **path);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/ofw/libofw/ofw_disk.c
--- a/head/sys/boot/ofw/libofw/ofw_disk.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/ofw/libofw/ofw_disk.c Wed Jul 25 16:45:04 2012 +0300
@@ -24,14 +24,13 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/boot/ofw/libofw/ofw_disk.c 236579 2012-06-04 20:45:33Z marius $");
/*
* Disk I/O routines using Open Firmware
*/
#include <sys/param.h>
-#include <sys/queue.h>
#include <netinet/in.h>
@@ -43,8 +42,8 @@
#include "libofw.h"
static int ofwd_init(void);
-static int ofwd_strategy(void *devdata, int flag, daddr_t dblk,
- size_t size, char *buf, size_t *rsize);
+static int ofwd_strategy(void *devdata, int flag, daddr_t dblk,
+ size_t size, char *buf, size_t *rsize);
static int ofwd_open(struct open_file *f, ...);
static int ofwd_close(struct open_file *f);
static int ofwd_ioctl(struct open_file *f, u_long cmd, void *data);
@@ -61,120 +60,109 @@
ofwd_print
};
-struct opened_dev {
- ihandle_t handle;
- u_int count;
- SLIST_ENTRY(opened_dev) link;
-};
-
-SLIST_HEAD(, opened_dev) opened_devs = SLIST_HEAD_INITIALIZER(opened_devs);
+/*
+ * We're not guaranteed to be able to open a device more than once and there
+ * is no OFW standard method to determine whether a device is already opened.
+ * Opening a device multiple times simultaneously happens to work with most
+ * OFW block device drivers but triggers a trap with at least the driver for
+ * the on-board controllers of Sun Fire V100 and Ultra 1. Upper layers and MI
+ * code expect to be able to open a device more than once however. Given that
+ * different partitions of the same device might be opened at the same time as
+ * done by ZFS, we can't generally just keep track of the opened devices and
+ * reuse the instance handle when asked to open an already opened device. So
+ * the best we can do is to cache the lastly used device path and close and
+ * open devices in ofwd_strategy() as needed.
+ */
+static struct ofw_devdesc *kdp;
static int
ofwd_init(void)
{
- return 0;
+ return (0);
}
static int
-ofwd_strategy(void *devdata, int flag, daddr_t dblk, size_t size, char *buf,
- size_t *rsize)
+ofwd_strategy(void *devdata, int flag __unused, daddr_t dblk, size_t size,
+ char *buf, size_t *rsize)
{
struct ofw_devdesc *dp = (struct ofw_devdesc *)devdata;
daddr_t pos;
int n;
+ if (dp != kdp) {
+ if (kdp != NULL) {
+#if !defined(__powerpc__)
+ OF_close(kdp->d_handle);
+#endif
+ kdp = NULL;
+ }
+ if ((dp->d_handle = OF_open(dp->d_path)) == -1)
+ return (ENOENT);
+ kdp = dp;
+ }
+
pos = dblk * 512;
do {
if (OF_seek(dp->d_handle, pos) < 0)
- return EIO;
+ return (EIO);
n = OF_read(dp->d_handle, buf, size);
if (n < 0 && n != -2)
- return EIO;
+ return (EIO);
} while (n == -2);
*rsize = size;
- return 0;
+ return (0);
}
static int
ofwd_open(struct open_file *f, ...)
{
- char path[256];
struct ofw_devdesc *dp;
- struct opened_dev *odp;
va_list vl;
va_start(vl, f);
dp = va_arg(vl, struct ofw_devdesc *);
va_end(vl);
- /*
- * We're not guaranteed to be able to open a device more than once
- * simultaneously and there is no OFW standard method to determine
- * whether a device is already opened. Opening a device more than
- * once happens to work with most OFW block device drivers but
- * triggers a trap with at least the driver for the on-board SCSI
- * controller in Sun Ultra 1. Upper layers and MI code expect to
- * be able to open a device more than once however. As a workaround
- * keep track of the opened devices and reuse the instance handle
- * when asked to open an already opened device.
- */
- SLIST_FOREACH(odp, &opened_devs, link) {
- if (OF_instance_to_path(odp->handle, path, sizeof(path)) == -1)
- continue;
- if (strcmp(path, dp->d_path) == 0) {
- odp->count++;
- dp->d_handle = odp->handle;
- return 0;
+
+ if (dp != kdp) {
+ if (kdp != NULL) {
+ OF_close(kdp->d_handle);
+ kdp = NULL;
}
+ if ((dp->d_handle = OF_open(dp->d_path)) == -1) {
+ printf("%s: Could not open %s\n", __func__,
+ dp->d_path);
+ return (ENOENT);
+ }
+ kdp = dp;
}
- odp = malloc(sizeof(struct opened_dev));
- if (odp == NULL) {
- printf("ofwd_open: malloc failed\n");
- return ENOMEM;
- }
- if ((odp->handle = OF_open(dp->d_path)) == -1) {
- printf("ofwd_open: Could not open %s\n", dp->d_path);
- free(odp);
- return ENOENT;
- }
- odp->count = 1;
- SLIST_INSERT_HEAD(&opened_devs, odp, link);
- dp->d_handle = odp->handle;
- return 0;
+ return (0);
}
static int
ofwd_close(struct open_file *f)
{
struct ofw_devdesc *dev = f->f_devdata;
- struct opened_dev *odp;
- SLIST_FOREACH(odp, &opened_devs, link) {
- if (odp->handle == dev->d_handle) {
- odp->count--;
- if (odp->count == 0) {
- SLIST_REMOVE(&opened_devs, odp, opened_dev,
- link);
- #if !defined(__powerpc__)
- OF_close(odp->handle);
- #endif
- free(odp);
- }
- break;
- }
+ if (dev == kdp) {
+#if !defined(__powerpc__)
+ OF_close(dev->d_handle);
+#endif
+ kdp = NULL;
}
- return 0;
+ return (0);
}
static int
-ofwd_ioctl(struct open_file *f, u_long cmd, void *data)
+ofwd_ioctl(struct open_file *f __unused, u_long cmd __unused,
+ void *data __unused)
{
return (EINVAL);
}
static void
-ofwd_print(int verbose)
+ofwd_print(int verbose __unused)
{
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/pc98/boot2/boot2.c
--- a/head/sys/boot/pc98/boot2/boot2.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/pc98/boot2/boot2.c Wed Jul 25 16:45:04 2012 +0300
@@ -15,7 +15,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/boot/pc98/boot2/boot2.c 232784 2012-03-10 15:08:37Z nyan $");
+__FBSDID("$FreeBSD: head/sys/boot/pc98/boot2/boot2.c 235988 2012-05-25 09:36:39Z gleb $");
#include <sys/param.h>
#include <sys/disklabel.h>
@@ -140,7 +140,6 @@
void exit(int);
static void load(void);
static int parse(void);
-static int xfsread(ino_t, void *, size_t);
static int dskread(void *, unsigned, unsigned);
static void printf(const char *,...);
static void putchar(int);
@@ -172,7 +171,7 @@
#include "ufsread.c"
static inline int
-xfsread(ino_t inode, void *buf, size_t nbyte)
+xfsread(ufs_ino_t inode, void *buf, size_t nbyte)
{
if ((size_t)fsread(inode, buf, nbyte) != nbyte) {
printf("Invalid %s\n", "format");
@@ -351,7 +350,7 @@
int i;
#endif
uint8_t autoboot;
- ino_t ino;
+ ufs_ino_t ino;
size_t nbyte;
dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base);
@@ -446,7 +445,7 @@
static Elf32_Phdr ep[2];
static Elf32_Shdr es[2];
caddr_t p;
- ino_t ino;
+ ufs_ino_t ino;
uint32_t addr;
int i, j;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/pc98/btx/btx/Makefile
--- a/head/sys/boot/pc98/btx/btx/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/pc98/btx/btx/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-# $FreeBSD: head/sys/boot/pc98/btx/btx/Makefile 232263 2012-02-28 18:30:18Z dim $
+# $FreeBSD: head/sys/boot/pc98/btx/btx/Makefile 235264 2012-05-11 09:46:17Z avg $
PROG= btx
INTERNALPROG=
@@ -12,6 +12,7 @@
.endif
CFLAGS+=-DBTX_FLAGS=${BOOT_BTX_FLAGS}
+CFLAGS+=-I${.CURDIR}/../../../i386/common
.if defined(BTX_SERIAL)
BOOT_COMCONSOLE_PORT?= 0x238
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/pc98/btx/btx/btx.S
--- a/head/sys/boot/pc98/btx/btx/btx.S Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/pc98/btx/btx/btx.S Wed Jul 25 16:45:04 2012 +0300
@@ -12,9 +12,11 @@
* warranties of merchantability and fitness for a particular
* purpose.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/boot/pc98/btx/btx/btx.S 235264 2012-05-11 09:46:17Z avg $
*/
+#include <bootargs.h>
+
/*
* Memory layout.
*/
@@ -205,7 +207,7 @@
andl $0x7,%eax
incl %eax
shll $0x11,%eax # To bytes
- subl $0x1000,%eax # Less arg space
+ subl $ARGSPACE,%eax # Less arg space
subl %edx,%eax # Less base
movb $SEL_UDATA,%cl # User data selector
pushl %ecx # Set SS
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/pc98/btx/btxldr/Makefile
--- a/head/sys/boot/pc98/btx/btxldr/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/pc98/btx/btxldr/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-# $FreeBSD: head/sys/boot/pc98/btx/btxldr/Makefile 232263 2012-02-28 18:30:18Z dim $
+# $FreeBSD: head/sys/boot/pc98/btx/btxldr/Makefile 235264 2012-05-11 09:46:17Z avg $
PROG= btxldr
INTERNALPROG=
@@ -6,6 +6,7 @@
SRCS= btxldr.S
CFLAGS+=-DLOADER_ADDRESS=${LOADER_ADDRESS}
+CFLAGS+=-I${.CURDIR}/../../../i386/common
.if defined(BTXLDR_VERBOSE)
CFLAGS+=-DBTXLDR_VERBOSE
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/pc98/btx/btxldr/btxldr.S
--- a/head/sys/boot/pc98/btx/btxldr/btxldr.S Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/pc98/btx/btxldr/btxldr.S Wed Jul 25 16:45:04 2012 +0300
@@ -12,7 +12,7 @@
* warranties of merchantability and fitness for a particular
* purpose.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/boot/pc98/btx/btxldr/btxldr.S 235264 2012-05-11 09:46:17Z avg $
*/
/*
@@ -20,6 +20,8 @@
* real thing should probably be more flexible, and in C.
*/
+#include <bootargs.h>
+
/*
* Memory locations.
*/
@@ -105,7 +107,7 @@
call hexout # stack
call putstr # pointer
movl $m_args,%esi # Format string
- leal 0x4(%esp,1),%ebx # First argument
+ leal 0x4(%esp),%ebx # First argument
movl $0x6,%ecx # Count
start.1: movl (%ebx),%eax # Get argument and
addl $0x4,%ebx # bump pointer
@@ -113,24 +115,28 @@
loop start.1 # Till done
call putstr # End message
#endif
- movl $0x48,%ecx # Allocate space
- subl %ecx,%ebp # for bootinfo
- movl 0x18(%esp,1),%esi # Source: bootinfo
+ movl BA_BOOTINFO+4(%esp),%esi # Source: bootinfo
cmpl $0x0, %esi # If the bootinfo pointer
je start_null_bi # is null, don't copy it
+ movl BI_SIZE(%esi),%ecx # Allocate space
+ subl %ecx,%ebp # for bootinfo
movl %ebp,%edi # Destination
rep # Copy
movsb # it
- movl %ebp,0x18(%esp,1) # Update pointer
+ movl %ebp,BA_BOOTINFO+4(%esp) # Update pointer
+ movl %edi,%ebp # Restore base pointer
#ifdef BTXLDR_VERBOSE
movl $m_rel_bi,%esi # Display
movl %ebp,%eax # bootinfo
call hexout # relocation
call putstr # message
#endif
-start_null_bi: movl $0x18,%ecx # Allocate space
- subl %ecx,%ebp # for arguments
- leal 0x4(%esp,1),%esi # Source
+start_null_bi: movl $BOOTARGS_SIZE,%ecx # Fixed size of arguments
+ testl $KARGS_FLAGS_EXTARG, BA_BOOTFLAGS+4(%esp) # Check for extra data
+ jz start_fixed # Skip if the flag is not set
+ addl BOOTARGS_SIZE+4(%esp),%ecx # Add size of variable args
+start_fixed: subl $ARGOFF,%ebp # Place args at fixed offset
+ leal 0x4(%esp),%esi # Source
movl %ebp,%edi # Destination
rep # Copy
movsb # them
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/pc98/btx/lib/Makefile
--- a/head/sys/boot/pc98/btx/lib/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/pc98/btx/lib/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,9 +1,10 @@
-# $FreeBSD$
+# $FreeBSD: head/sys/boot/pc98/btx/lib/Makefile 235264 2012-05-11 09:46:17Z avg $
PROG= crt0.o
INTERNALPROG=
NO_MAN=
-SRCS= btxcsu.s btxsys.s btxv86.s
+SRCS= btxcsu.S btxsys.s btxv86.s
+CFLAGS+=-I${.CURDIR}/../../../i386/common
LDFLAGS=-Wl,-r
.include <bsd.prog.mk>
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/pc98/btx/lib/btxcsu.S
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/boot/pc98/btx/lib/btxcsu.S Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 1998 Robert Nordier
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are freely
+# permitted provided that the above copyright notice and this
+# paragraph and the following disclaimer are duplicated in all
+# such forms.
+#
+# This software is provided "AS IS" and without any express or
+# implied warranties, including, without limitation, the implied
+# warranties of merchantability and fitness for a particular
+# purpose.
+#
+
+# $FreeBSD: head/sys/boot/pc98/btx/lib/btxcsu.S 235264 2012-05-11 09:46:17Z avg $
+
+#
+# BTX C startup code (ELF).
+#
+
+#include <bootargs.h>
+
+#
+# Globals.
+#
+ .global _start
+#
+# Client entry point.
+#
+_start: cld
+ pushl %eax
+ movl $_edata,%edi
+ movl $_end,%ecx
+ subl %edi, %ecx
+ xorb %al, %al
+ rep
+ stosb
+ popl __base
+ movl %esp,%eax # Set
+ addl $ARGADJ,%eax # argument
+ movl %eax,__args # pointer
+ call main # Invoke client main()
+ call exit # Invoke client exit()
+#
+# Data.
+#
+ .comm __base,4 # Client base address
+ .comm __args,4 # Client arguments
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/pc98/btx/lib/btxcsu.s
--- a/head/sys/boot/pc98/btx/lib/btxcsu.s Wed Jul 25 16:42:35 2012 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-#
-# Copyright (c) 1998 Robert Nordier
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms are freely
-# permitted provided that the above copyright notice and this
-# paragraph and the following disclaimer are duplicated in all
-# such forms.
-#
-# This software is provided "AS IS" and without any express or
-# implied warranties, including, without limitation, the implied
-# warranties of merchantability and fitness for a particular
-# purpose.
-#
-
-# $FreeBSD$
-
-#
-# BTX C startup code (ELF).
-#
-
-#
-# Globals.
-#
- .global _start
-#
-# Constants.
-#
- .set ARGADJ,0xfa0 # Argument adjustment
-#
-# Client entry point.
-#
-_start: cld
- pushl %eax
- movl $_edata,%edi
- movl $_end,%ecx
- subl %edi, %ecx
- xorb %al, %al
- rep
- stosb
- popl __base
- movl %esp,%eax # Set
- addl $ARGADJ,%eax # argument
- movl %eax,__args # pointer
- call main # Invoke client main()
- call exit # Invoke client exit()
-#
-# Data.
-#
- .comm __base,4 # Client base address
- .comm __args,4 # Client arguments
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/pc98/cdboot/Makefile
--- a/head/sys/boot/pc98/cdboot/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/pc98/cdboot/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,10 +1,12 @@
-# $FreeBSD$
+# $FreeBSD: head/sys/boot/pc98/cdboot/Makefile 235264 2012-05-11 09:46:17Z avg $
PROG= cdboot
STRIP=
BINMODE=${NOBINMODE}
NO_MAN=
-SRCS= ${PROG}.s
+SRCS= ${PROG}.S
+
+CFLAGS+=-I${.CURDIR}/../../i386/common
ORG= 0x0000
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/pc98/cdboot/cdboot.S
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/boot/pc98/cdboot/cdboot.S Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,808 @@
+#
+# Copyright (c) 2006 TAKAHASHI Yoshihiro <nyan at FreeBSD.org>
+# Copyright (c) 2001 John Baldwin <jhb at 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.
+# 3. Neither the name of the author nor the names of any co-contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# $FreeBSD: head/sys/boot/pc98/cdboot/cdboot.S 235264 2012-05-11 09:46:17Z avg $
+
+#include <bootargs.h>
+
+#
+# Basically, we first create a set of boot arguments to pass to the loaded
+# binary. Then we attempt to load /boot/loader from the CD we were booted
+# off of.
+#
+
+#
+# Memory locations.
+#
+ .set STACK_OFF,0x6000 # Stack offset
+ .set LOAD_SEG,0x0700 # Load segment
+ .set LOAD_SIZE,2048 # Load size
+ .set DAUA,0x0584 # DA/UA
+
+ .set MEM_PAGE_SIZE,0x1000 # memory page size, 4k
+ .set MEM_ARG,0x900 # Arguments at start
+ .set MEM_ARG_BTX,0xa100 # Where we move them to so the
+ # BTX client can see them
+ .set MEM_ARG_SIZE,0x18 # Size of the arguments
+ .set MEM_BTX_ADDRESS,0x9000 # where BTX lives
+ .set MEM_BTX_ENTRY,0x9010 # where BTX starts to execute
+ .set MEM_BTX_OFFSET,MEM_PAGE_SIZE # offset of BTX in the loader
+ .set MEM_BTX_CLIENT,0xa000 # where BTX clients live
+#
+# PC98 machine type from sys/pc98/pc98/pc98_machdep.h
+#
+ .set MEM_SYS, 0xa100 # System common area segment
+ .set PC98_MACHINE_TYPE, 0x0620 # PC98 machine type
+ .set EPSON_ID, 0x0624 # EPSON machine id
+
+ .set M_NEC_PC98, 0x0001
+ .set M_EPSON_PC98, 0x0002
+ .set M_NOT_H98, 0x0010
+ .set M_H98, 0x0020
+ .set M_NOTE, 0x0040
+ .set M_NORMAL, 0x1000
+ .set M_8M, 0x8000
+#
+# Signature Constants
+#
+ .set SIG1_OFF,0x1fe # Signature offset
+ .set SIG2_OFF,0x7fe # Signature offset
+#
+# a.out header fields
+#
+ .set AOUT_TEXT,0x04 # text segment size
+ .set AOUT_DATA,0x08 # data segment size
+ .set AOUT_BSS,0x0c # zero'd BSS size
+ .set AOUT_SYMBOLS,0x10 # symbol table
+ .set AOUT_ENTRY,0x14 # entry point
+ .set AOUT_HEADER,MEM_PAGE_SIZE # size of the a.out header
+#
+# Segment selectors.
+#
+ .set SEL_SDATA,0x8 # Supervisor data
+ .set SEL_RDATA,0x10 # Real mode data
+ .set SEL_SCODE,0x18 # PM-32 code
+ .set SEL_SCODE16,0x20 # PM-16 code
+#
+# BTX constants
+#
+ .set INT_SYS,0x30 # BTX syscall interrupt
+#
+# Constants for reading from the CD.
+#
+ .set ERROR_TIMEOUT,0x90 # BIOS timeout on read
+ .set NUM_RETRIES,3 # Num times to retry
+ .set SECTOR_SIZE,0x800 # size of a sector
+ .set SECTOR_SHIFT,11 # number of place to shift
+ .set BUFFER_LEN,0x100 # number of sectors in buffer
+ .set MAX_READ,0xf800 # max we can read at a time
+ .set MAX_READ_SEC,MAX_READ >> SECTOR_SHIFT
+ .set MEM_READ_BUFFER,0x9000 # buffer to read from CD
+ .set MEM_VOLDESC,MEM_READ_BUFFER # volume descriptor
+ .set MEM_DIR,MEM_VOLDESC+SECTOR_SIZE # Lookup buffer
+ .set VOLDESC_LBA,0x10 # LBA of vol descriptor
+ .set VD_PRIMARY,1 # Primary VD
+ .set VD_END,255 # VD Terminator
+ .set VD_ROOTDIR,156 # Offset of Root Dir Record
+ .set DIR_LEN,0 # Offset of Dir Record length
+ .set DIR_EA_LEN,1 # Offset of EA length
+ .set DIR_EXTENT,2 # Offset of 64-bit LBA
+ .set DIR_SIZE,10 # Offset of 64-bit length
+ .set DIR_NAMELEN,32 # Offset of 8-bit name len
+ .set DIR_NAME,33 # Offset of dir name
+
+#
+# Program start.
+#
+ .code16
+ .globl start
+
+start: jmp main
+
+ .org 4
+ .ascii "IPL1 "
+
+main: cld
+
+ /* Setup the stack */
+ xor %ax,%ax
+ mov %ax,%ss
+ mov $STACK_OFF,%sp
+
+ push %ecx
+
+ /* Setup graphic screen */
+ mov $0x42,%ah # 640x400
+ mov $0xc0,%ch
+ int $0x18
+ mov $0x40,%ah # graph on
+ int $0x18
+
+ /* Setup text screen */
+ mov $0x0a00,%ax # 80x25
+ int $0x18
+ mov $0x0c,%ah # text on
+ int $0x18
+ mov $0x13,%ah # cursor home
+ xor %dx,%dx
+ int $0x18
+ mov $0x11,%ah # cursor on
+ int $0x18
+
+ /* Setup keyboard */
+ mov $0x03,%ah
+ int $0x18
+
+ /* Transfer PC-9801 system common area */
+ xor %ax,%ax
+ mov %ax,%si
+ mov %ax,%ds
+ mov %ax,%di
+ mov $MEM_SYS,%ax
+ mov %ax,%es
+ mov $0x0600,%cx
+ rep
+ movsb
+
+ /* Transfer EPSON machine type */
+ mov $0xfd00,%ax
+ mov %ax,%ds
+ mov (0x804),%eax
+ and $0x00ffffff,%eax
+ mov %eax,%es:(EPSON_ID)
+
+ /* Set machine type to PC98_SYSTEM_PARAMETER */
+ call machine_check
+
+ /* Load cdboot */
+ xor %ax,%ax
+ mov %ax,%ds
+ mov $0x06,%ah /* Read data */
+ mov (DAUA),%al /* Read drive */
+ pop %ecx /* cylinder */
+ xor %dx,%dx /* head / sector */
+ mov $LOAD_SEG,%bx /* Load address */
+ mov %bx,%es
+ xor %bp,%bp
+ mov $LOAD_SIZE,%bx /* Load size */
+ int $0x1b
+ mov $msg_readerr,%si
+ jc error
+
+ /* Jump to cdboot */
+ ljmp $LOAD_SEG,$cdboot
+
+#
+# Set machine type to PC98_SYSTEM_PARAMETER.
+#
+machine_check: xor %edx,%edx
+ mov %dx,%ds
+ mov $MEM_SYS,%ax
+ mov %ax,%es
+
+ /* Wait V-SYNC */
+vsync.1: inb $0x60,%al
+ test $0x20,%al
+ jnz vsync.1
+vsync.2: inb $0x60,%al
+ test $0x20,%al
+ jz vsync.2
+
+ /* ANK 'A' font */
+ xor %al,%al
+ outb %al,$0xa1
+ mov $0x41,%al
+ outb %al,$0xa3
+
+ /* Get 'A' font from CG window */
+ push %ds
+ mov $0xa400,%ax
+ mov %ax,%ds
+ xor %eax,%eax
+ xor %bx,%bx
+ mov $4,%cx
+font.1: add (%bx),%eax
+ add $4,%bx
+ loop font.1
+ pop %ds
+ cmp $0x6efc58fc,%eax
+ jnz m_epson
+
+m_pc98: or $M_NEC_PC98,%edx
+ mov $0x0458,%bx
+ mov (%bx),%al
+ test $0x80,%al
+ jz m_not_h98
+ or $M_H98,%edx
+ jmp 1f
+m_epson: or $M_EPSON_PC98,%edx
+m_not_h98: or $M_NOT_H98,%edx
+
+1: inb $0x42,%al
+ test $0x20,%al
+ jz 1f
+ or $M_8M,%edx
+
+1: mov $0x0400,%bx
+ mov (%bx),%al
+ test $0x80,%al
+ jz 1f
+ or $M_NOTE,%edx
+
+1: mov $PC98_MACHINE_TYPE,%bx
+ mov %edx,%es:(%bx)
+ ret
+
+#
+# Print out the error message at [SI], wait for a keypress, and then
+# reboot the machine.
+#
+error: call putstr
+ mov $msg_keypress,%si
+ call putstr
+ xor %ax,%ax # Get keypress
+ int $0x18
+ xor %ax,%ax # CPU reset
+ outb %al,$0xf0
+halt: hlt
+ jmp halt # Spin
+
+#
+# Display a null-terminated string at [SI].
+#
+# Trashes: AX, BX, CX, DX, SI, DI
+#
+putstr: push %ds
+ push %es
+ mov %cs,%ax
+ mov %ax,%ds
+ mov $0xa000,%ax
+ mov %ax,%es
+ mov cursor,%di
+ mov $0x00e1,%bx # Attribute
+ mov $160,%cx
+putstr.0: lodsb
+ testb %al,%al
+ jz putstr.done
+ cmp $0x0d,%al
+ jz putstr.cr
+ cmp $0x0a,%al
+ jz putstr.lf
+ mov %bl,%es:0x2000(%di)
+ stosb
+ inc %di
+ jmp putstr.move
+putstr.cr: xor %dx,%dx
+ mov %di,%ax
+ div %cx
+ sub %dx,%di
+ jmp putstr.move
+putstr.lf: add %cx,%di
+putstr.move: mov %di,%dx
+ mov $0x13,%ah # Move cursor
+ int $0x18
+ jmp putstr.0
+putstr.done: mov %di,cursor
+ pop %es
+ pop %ds
+ ret
+
+#
+# Display a single char at [AL], but don't move a cursor.
+#
+putc: push %es
+ push %di
+ push %bx
+ mov $0xa000,%bx
+ mov %bx,%es
+ mov cursor,%di
+ mov $0xe1,%bl # Attribute
+ mov %bl,%es:0x2000(%di)
+ stosb
+ pop %bx
+ pop %di
+ pop %es
+ ret
+
+msg_readerr: .asciz "Read Error\r\n"
+msg_keypress: .asciz "\r\nPress any key to reboot\r\n"
+
+/* Boot signature */
+
+ .org SIG1_OFF,0x90
+
+ .word 0xaa55 # Magic number
+
+#
+# cdboot
+#
+cdboot: mov %cs,%ax
+ mov %ax,%ds
+ xor %ax,%ax
+ mov %ax,%es
+ mov %es:(DAUA),%al # Save BIOS boot device
+ mov %al,drive
+ mov %cx,cylinder # Save BIOS boot cylinder
+
+ mov $msg_welcome,%si # %ds:(%si) -> welcome message
+ call putstr # display the welcome message
+#
+# Setup the arguments that the loader is expecting from boot[12]
+#
+ mov $msg_bootinfo,%si # %ds:(%si) -> boot args message
+ call putstr # display the message
+ mov $MEM_ARG,%bx # %ds:(%bx) -> boot args
+ mov %bx,%di # %es:(%di) -> boot args
+ xor %eax,%eax # zero %eax
+ mov $(MEM_ARG_SIZE/4),%cx # Size of arguments in 32-bit
+ # dwords
+ rep # Clear the arguments
+ stosl # to zero
+ mov drive,%dl # Store BIOS boot device
+ mov %dl,%es:0x4(%bx) # in kargs->bootdev
+ or $KARGS_FLAGS_CD,%es:0x8(%bx) # kargs->bootflags |=
+ # KARGS_FLAGS_CD
+#
+# Load Volume Descriptor
+#
+ mov $VOLDESC_LBA,%eax # Set LBA of first VD
+load_vd: push %eax # Save %eax
+ mov $1,%dh # One sector
+ mov $MEM_VOLDESC,%ebx # Destination
+ call read # Read it in
+ cmpb $VD_PRIMARY,%es:(%bx) # Primary VD?
+ je have_vd # Yes
+ pop %eax # Prepare to
+ inc %eax # try next
+ cmpb $VD_END,%es:(%bx) # Last VD?
+ jne load_vd # No, read next
+ mov $msg_novd,%si # No VD
+ jmp error # Halt
+have_vd: # Have Primary VD
+#
+# Try to look up the loader binary using the paths in the loader_paths
+# array.
+#
+ mov $loader_paths,%si # Point to start of array
+lookup_path: push %si # Save file name pointer
+ call lookup # Try to find file
+ pop %di # Restore file name pointer
+ jnc lookup_found # Found this file
+ push %es
+ mov %cs,%ax
+ mov %ax,%es
+ xor %al,%al # Look for next
+ mov $0xffff,%cx # path name by
+ repnz # scanning for
+ scasb # nul char
+ pop %es
+ mov %di,%si # Point %si at next path
+ mov (%si),%al # Get first char of next path
+ or %al,%al # Is it double nul?
+ jnz lookup_path # No, try it.
+ mov $msg_failed,%si # Failed message
+ jmp error # Halt
+lookup_found: # Found a loader file
+#
+# Load the binary into the buffer. Due to real mode addressing limitations
+# we have to read it in 64k chunks.
+#
+ mov %es:DIR_SIZE(%bx),%eax # Read file length
+ add $SECTOR_SIZE-1,%eax # Convert length to sectors
+ shr $SECTOR_SHIFT,%eax
+ cmp $BUFFER_LEN,%eax
+ jbe load_sizeok
+ mov $msg_load2big,%si # Error message
+ jmp error
+load_sizeok: movzbw %al,%cx # Num sectors to read
+ mov %es:DIR_EXTENT(%bx),%eax # Load extent
+ xor %edx,%edx
+ mov %es:DIR_EA_LEN(%bx),%dl
+ add %edx,%eax # Skip extended
+ mov $MEM_READ_BUFFER,%ebx # Read into the buffer
+load_loop: mov %cl,%dh
+ cmp $MAX_READ_SEC,%cl # Truncate to max read size
+ jbe load_notrunc
+ mov $MAX_READ_SEC,%dh
+load_notrunc: sub %dh,%cl # Update count
+ push %eax # Save
+ call read # Read it in
+ pop %eax # Restore
+ add $MAX_READ_SEC,%eax # Update LBA
+ add $MAX_READ,%ebx # Update dest addr
+ jcxz load_done # Done?
+ jmp load_loop # Keep going
+load_done:
+#
+# Turn on the A20 address line
+#
+ xor %ax,%ax # Turn A20 on
+ outb %al,$0xf2
+ mov $0x02,%al
+ outb %al,$0xf6
+#
+# Relocate the loader and BTX using a very lazy protected mode
+#
+ mov $msg_relocate,%si # Display the
+ call putstr # relocation message
+ mov %es:(MEM_READ_BUFFER+AOUT_ENTRY),%edi # %edi is the destination
+ mov $(MEM_READ_BUFFER+AOUT_HEADER),%esi # %esi is
+ # the start of the text
+ # segment
+ mov %es:(MEM_READ_BUFFER+AOUT_TEXT),%ecx # %ecx = length of the text
+ # segment
+ push %edi # Save entry point for later
+ lgdt gdtdesc # setup our own gdt
+ cli # turn off interrupts
+ mov %cr0,%eax # Turn on
+ or $0x1,%al # protected
+ mov %eax,%cr0 # mode
+ ljmp $SEL_SCODE,$pm_start # long jump to clear the
+ # instruction pre-fetch queue
+ .code32
+pm_start: mov $SEL_SDATA,%ax # Initialize
+ mov %ax,%ds # %ds and
+ mov %ax,%es # %es to a flat selector
+ rep # Relocate the
+ movsb # text segment
+ add $(MEM_PAGE_SIZE - 1),%edi # pad %edi out to a new page
+ and $~(MEM_PAGE_SIZE - 1),%edi # for the data segment
+ mov MEM_READ_BUFFER+AOUT_DATA,%ecx # size of the data segment
+ rep # Relocate the
+ movsb # data segment
+ mov MEM_READ_BUFFER+AOUT_BSS,%ecx # size of the bss
+ xor %eax,%eax # zero %eax
+ add $3,%cl # round %ecx up to
+ shr $2,%ecx # a multiple of 4
+ rep # zero the
+ stosl # bss
+ mov MEM_READ_BUFFER+AOUT_ENTRY,%esi # %esi -> relocated loader
+ add $MEM_BTX_OFFSET,%esi # %esi -> BTX in the loader
+ mov $MEM_BTX_ADDRESS,%edi # %edi -> where BTX needs to go
+ movzwl 0xa(%esi),%ecx # %ecx -> length of BTX
+ rep # Relocate
+ movsb # BTX
+ ljmp $SEL_SCODE16,$pm_16 # Jump to 16-bit PM
+ .code16
+pm_16: mov $SEL_RDATA,%ax # Initialize
+ mov %ax,%ds # %ds and
+ mov %ax,%es # %es to a real mode selector
+ mov %cr0,%eax # Turn off
+ and $~0x1,%al # protected
+ mov %eax,%cr0 # mode
+ ljmp $LOAD_SEG,$pm_end # Long jump to clear the
+ # instruction pre-fetch queue
+pm_end: sti # Turn interrupts back on now
+#
+# Copy the BTX client to MEM_BTX_CLIENT
+#
+ mov %cs,%ax
+ mov %ax,%ds
+ xor %ax,%ax
+ mov %ax,%es
+ mov $MEM_BTX_CLIENT,%di # Prepare to relocate
+ mov $btx_client,%si # the simple btx client
+ mov $(btx_client_end-btx_client),%cx # length of btx client
+ rep # Relocate the
+ movsb # simple BTX client
+#
+# Copy the boot[12] args to where the BTX client can see them
+#
+ xor %ax,%ax
+ mov %ax,%ds
+ mov $MEM_ARG,%si # where the args are at now
+ mov $MEM_ARG_BTX,%di # where the args are moving to
+ mov $(MEM_ARG_SIZE/4),%cx # size of the arguments in longs
+ rep # Relocate
+ movsl # the words
+#
+# Save the entry point so the client can get to it later on
+#
+ pop %eax # Restore saved entry point
+ stosl # and add it to the end of
+ # the arguments
+#
+# Now we just start up BTX and let it do the rest
+#
+ mov $msg_jump,%si # Display the
+ call putstr # jump message
+ ljmp $0,$MEM_BTX_ENTRY # Jump to the BTX entry point
+
+#
+# Lookup the file in the path at [SI] from the root directory.
+#
+# Trashes: All but BX
+# Returns: CF = 0 (success), BX = pointer to record
+# CF = 1 (not found)
+#
+lookup: mov $VD_ROOTDIR+MEM_VOLDESC,%bx # Root directory record
+ push %bx
+ push %si
+ mov $msg_lookup,%si # Display lookup message
+ call putstr
+ pop %si
+ push %si
+ call putstr
+ mov $msg_lookup2,%si
+ call putstr
+ pop %si
+ pop %bx
+lookup_dir: lodsb # Get first char of path
+ cmp $0,%al # Are we done?
+ je lookup_done # Yes
+ cmp $'/',%al # Skip path separator.
+ je lookup_dir
+ dec %si # Undo lodsb side effect
+ call find_file # Lookup first path item
+ jnc lookup_dir # Try next component
+ mov $msg_lookupfail,%si # Not found message
+ push %bx
+ call putstr
+ pop %bx
+ stc # Set carry
+ ret
+lookup_done: mov $msg_lookupok,%si # Success message
+ push %bx
+ call putstr
+ pop %bx
+ clc # Clear carry
+ ret
+
+#
+# Lookup file at [SI] in directory whose record is at [BX].
+#
+# Trashes: All but returns
+# Returns: CF = 0 (success), BX = pointer to record, SI = next path item
+# CF = 1 (not found), SI = preserved
+#
+find_file: mov %es:DIR_EXTENT(%bx),%eax # Load extent
+ xor %edx,%edx
+ mov %es:DIR_EA_LEN(%bx),%dl
+ add %edx,%eax # Skip extended attributes
+ mov %eax,rec_lba # Save LBA
+ mov %es:DIR_SIZE(%bx),%eax # Save size
+ mov %eax,rec_size
+ xor %cl,%cl # Zero length
+ push %si # Save
+ff.namelen: inc %cl # Update length
+ lodsb # Read char
+ cmp $0,%al # Nul?
+ je ff.namedone # Yes
+ cmp $'/',%al # Path separator?
+ jnz ff.namelen # No, keep going
+ff.namedone: dec %cl # Adjust length and save
+ mov %cl,name_len
+ pop %si # Restore
+ff.load: mov rec_lba,%eax # Load LBA
+ mov $MEM_DIR,%ebx # Address buffer
+ mov $1,%dh # One sector
+ call read # Read directory block
+ incl rec_lba # Update LBA to next block
+ff.scan: mov %ebx,%edx # Check for EOF
+ sub $MEM_DIR,%edx
+ cmp %edx,rec_size
+ ja ff.scan.1
+ stc # EOF reached
+ ret
+ff.scan.1: cmpb $0,%es:DIR_LEN(%bx) # Last record in block?
+ je ff.nextblock
+ push %si # Save
+ movzbw %es:DIR_NAMELEN(%bx),%si # Find end of string
+ff.checkver: cmpb $'0',%es:DIR_NAME-1(%bx,%si) # Less than '0'?
+ jb ff.checkver.1
+ cmpb $'9',%es:DIR_NAME-1(%bx,%si) # Greater than '9'?
+ ja ff.checkver.1
+ dec %si # Next char
+ jnz ff.checkver
+ jmp ff.checklen # All numbers in name, so
+ # no version
+ff.checkver.1: movzbw %es:DIR_NAMELEN(%bx),%cx
+ cmp %cx,%si # Did we find any digits?
+ je ff.checkdot # No
+ cmpb $';',%es:DIR_NAME-1(%bx,%si) # Check for semicolon
+ jne ff.checkver.2
+ dec %si # Skip semicolon
+ mov %si,%cx
+ mov %cl,%es:DIR_NAMELEN(%bx) # Adjust length
+ jmp ff.checkdot
+ff.checkver.2: mov %cx,%si # Restore %si to end of string
+ff.checkdot: cmpb $'.',%es:DIR_NAME-1(%bx,%si) # Trailing dot?
+ jne ff.checklen # No
+ decb %es:DIR_NAMELEN(%bx) # Adjust length
+ff.checklen: pop %si # Restore
+ movzbw name_len,%cx # Load length of name
+ cmp %cl,%es:DIR_NAMELEN(%bx) # Does length match?
+ je ff.checkname # Yes, check name
+ff.nextrec: add %es:DIR_LEN(%bx),%bl # Next record
+ adc $0,%bh
+ jmp ff.scan
+ff.nextblock: subl $SECTOR_SIZE,rec_size # Adjust size
+ jnc ff.load # If subtract ok, keep going
+ ret # End of file, so not found
+ff.checkname: lea DIR_NAME(%bx),%di # Address name in record
+ push %si # Save
+ repe cmpsb # Compare name
+ je ff.match # We have a winner!
+ pop %si # Restore
+ jmp ff.nextrec # Keep looking.
+ff.match: add $2,%sp # Discard saved %si
+ clc # Clear carry
+ ret
+
+#
+# Load DH sectors starting at LBA EAX into [EBX].
+#
+# Trashes: EAX
+#
+read: push %es # Save
+ push %bp
+ push %dx
+ push %cx
+ push %ebx
+ mov %bx,%bp # Set destination address
+ and $0x000f,%bp
+ shr $4,%ebx
+ mov %bx,%es
+ xor %bx,%bx # Set read bytes
+ mov %dh,%bl
+ shl $SECTOR_SHIFT,%bx # 2048 bytes/sec
+ mov %ax,%cx # Set LBA
+ shr $16,%eax
+ mov %ax,%dx
+read.retry: mov $0x06,%ah # BIOS device read
+ mov drive,%al
+ and $0x7f,%al
+ call twiddle # Entertain the user
+ int $0x1b # Call BIOS
+ jc read.fail # Worked?
+ pop %ebx # Restore
+ pop %cx
+ pop %dx
+ pop %bp
+ pop %es
+ ret # Return
+read.fail: cmp $ERROR_TIMEOUT,%ah # Timeout?
+ je read.retry # Yes, Retry.
+read.error: mov %ah,%al # Save error
+ mov $hex_error,%di # Format it
+ call hex8 # as hex
+ mov $msg_badread,%si # Display Read error message
+ jmp error
+
+#
+# Output the "twiddle"
+#
+twiddle: push %ax # Save
+ push %bx # Save
+ mov twiddle_index,%al # Load index
+ mov $twiddle_chars,%bx # Address table
+ inc %al # Next
+ and $3,%al # char
+ mov %al,twiddle_index # Save index for next call
+ xlat # Get char
+ call putc # Output it
+ pop %bx # Restore
+ pop %ax # Restore
+ ret
+
+#
+# Convert AL to hex, saving the result to [EDI].
+#
+hex8: pushl %eax # Save
+ shrb $0x4,%al # Do upper
+ call hex8.1 # 4
+ popl %eax # Restore
+hex8.1: andb $0xf,%al # Get lower 4
+ cmpb $0xa,%al # Convert
+ sbbb $0x69,%al # to hex
+ das # digit
+ orb $0x20,%al # To lower case
+ mov %al,(%di) # Save char
+ inc %di
+ ret # (Recursive)
+
+#
+# BTX client to start btxldr
+#
+ .code32
+btx_client: mov $(MEM_ARG_BTX-MEM_BTX_CLIENT+MEM_ARG_SIZE-4), %esi
+ # %ds:(%esi) -> end
+ # of boot[12] args
+ mov $(MEM_ARG_SIZE/4),%ecx # Number of words to push
+ std # Go backwards
+push_arg: lodsl # Read argument
+ push %eax # Push it onto the stack
+ loop push_arg # Push all of the arguments
+ cld # In case anyone depends on this
+ pushl MEM_ARG_BTX-MEM_BTX_CLIENT+MEM_ARG_SIZE # Entry point of
+ # the loader
+ push %eax # Emulate a near call
+ mov $0x1,%eax # 'exec' system call
+ int $INT_SYS # BTX system call
+btx_client_end:
+ .code16
+
+ .p2align 4
+#
+# Global descriptor table.
+#
+gdt: .word 0x0,0x0,0x0,0x0 # Null entry
+ .word 0xffff,0x0000,0x9200,0x00cf # SEL_SDATA
+ .word 0xffff,0x0000,0x9200,0x0000 # SEL_RDATA
+ .word 0xffff,LOAD_SEG<<4,0x9a00,0x00cf # SEL_SCODE (32-bit)
+ .word 0xffff,LOAD_SEG<<4,0x9a00,0x008f # SEL_SCODE16 (16-bit)
+gdt.1:
+#
+# Pseudo-descriptors.
+#
+gdtdesc: .word gdt.1-gdt-1 # Limit
+ .long LOAD_SEG<<4 + gdt # Base
+
+#
+# BOOT device
+#
+drive: .byte 0
+cylinder: .word 0
+
+#
+# State for searching dir
+#
+rec_lba: .long 0x0 # LBA (adjusted for EA)
+rec_size: .long 0x0 # File size
+name_len: .byte 0x0 # Length of current name
+
+cursor: .word 0
+twiddle_index: .byte 0x0
+
+msg_welcome: .asciz "CD Loader 1.2\r\n\n"
+msg_bootinfo: .asciz "Building the boot loader arguments\r\n"
+msg_relocate: .asciz "Relocating the loader and the BTX\r\n"
+msg_jump: .asciz "Starting the BTX loader\r\n"
+msg_badread: .ascii "Read Error: 0x"
+hex_error: .asciz "00\r\n"
+msg_novd: .asciz "Could not find Primary Volume Descriptor\r\n"
+msg_lookup: .asciz "Looking up "
+msg_lookup2: .asciz "... "
+msg_lookupok: .asciz "Found\r\n"
+msg_lookupfail: .asciz "File not found\r\n"
+msg_load2big: .asciz "File too big\r\n"
+msg_failed: .asciz "Boot failed\r\n"
+twiddle_chars: .ascii "|/-\\"
+loader_paths: .asciz "/BOOT.PC98/LOADER"
+ .asciz "/boot.pc98/loader"
+ .asciz "/BOOT/LOADER"
+ .asciz "/boot/loader"
+ .byte 0
+
+/* Boot signature */
+
+ .org SIG2_OFF,0x90
+
+ .word 0xaa55 # Magic number
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/pc98/cdboot/cdboot.s
--- a/head/sys/boot/pc98/cdboot/cdboot.s Wed Jul 25 16:42:35 2012 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,811 +0,0 @@
-#
-# Copyright (c) 2006 TAKAHASHI Yoshihiro <nyan at FreeBSD.org>
-# Copyright (c) 2001 John Baldwin <jhb at 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.
-# 3. Neither the name of the author nor the names of any co-contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-#
-
-# $FreeBSD$
-
-#
-# Basically, we first create a set of boot arguments to pass to the loaded
-# binary. Then we attempt to load /boot/loader from the CD we were booted
-# off of.
-#
-
-#
-# Memory locations.
-#
- .set STACK_OFF,0x6000 # Stack offset
- .set LOAD_SEG,0x0700 # Load segment
- .set LOAD_SIZE,2048 # Load size
- .set DAUA,0x0584 # DA/UA
-
- .set MEM_PAGE_SIZE,0x1000 # memory page size, 4k
- .set MEM_ARG,0x900 # Arguments at start
- .set MEM_ARG_BTX,0xa100 # Where we move them to so the
- # BTX client can see them
- .set MEM_ARG_SIZE,0x18 # Size of the arguments
- .set MEM_BTX_ADDRESS,0x9000 # where BTX lives
- .set MEM_BTX_ENTRY,0x9010 # where BTX starts to execute
- .set MEM_BTX_OFFSET,MEM_PAGE_SIZE # offset of BTX in the loader
- .set MEM_BTX_CLIENT,0xa000 # where BTX clients live
-#
-# PC98 machine type from sys/pc98/pc98/pc98_machdep.h
-#
- .set MEM_SYS, 0xa100 # System common area segment
- .set PC98_MACHINE_TYPE, 0x0620 # PC98 machine type
- .set EPSON_ID, 0x0624 # EPSON machine id
-
- .set M_NEC_PC98, 0x0001
- .set M_EPSON_PC98, 0x0002
- .set M_NOT_H98, 0x0010
- .set M_H98, 0x0020
- .set M_NOTE, 0x0040
- .set M_NORMAL, 0x1000
- .set M_8M, 0x8000
-#
-# Signature Constants
-#
- .set SIG1_OFF,0x1fe # Signature offset
- .set SIG2_OFF,0x7fe # Signature offset
-#
-# a.out header fields
-#
- .set AOUT_TEXT,0x04 # text segment size
- .set AOUT_DATA,0x08 # data segment size
- .set AOUT_BSS,0x0c # zero'd BSS size
- .set AOUT_SYMBOLS,0x10 # symbol table
- .set AOUT_ENTRY,0x14 # entry point
- .set AOUT_HEADER,MEM_PAGE_SIZE # size of the a.out header
-#
-# Flags for kargs->bootflags
-#
- .set KARGS_FLAGS_CD,0x1 # flag to indicate booting from
- # CD loader
-#
-# Segment selectors.
-#
- .set SEL_SDATA,0x8 # Supervisor data
- .set SEL_RDATA,0x10 # Real mode data
- .set SEL_SCODE,0x18 # PM-32 code
- .set SEL_SCODE16,0x20 # PM-16 code
-#
-# BTX constants
-#
- .set INT_SYS,0x30 # BTX syscall interrupt
-#
-# Constants for reading from the CD.
-#
- .set ERROR_TIMEOUT,0x90 # BIOS timeout on read
- .set NUM_RETRIES,3 # Num times to retry
- .set SECTOR_SIZE,0x800 # size of a sector
- .set SECTOR_SHIFT,11 # number of place to shift
- .set BUFFER_LEN,0x100 # number of sectors in buffer
- .set MAX_READ,0xf800 # max we can read at a time
- .set MAX_READ_SEC,MAX_READ >> SECTOR_SHIFT
- .set MEM_READ_BUFFER,0x9000 # buffer to read from CD
- .set MEM_VOLDESC,MEM_READ_BUFFER # volume descriptor
- .set MEM_DIR,MEM_VOLDESC+SECTOR_SIZE # Lookup buffer
- .set VOLDESC_LBA,0x10 # LBA of vol descriptor
- .set VD_PRIMARY,1 # Primary VD
- .set VD_END,255 # VD Terminator
- .set VD_ROOTDIR,156 # Offset of Root Dir Record
- .set DIR_LEN,0 # Offset of Dir Record length
- .set DIR_EA_LEN,1 # Offset of EA length
- .set DIR_EXTENT,2 # Offset of 64-bit LBA
- .set DIR_SIZE,10 # Offset of 64-bit length
- .set DIR_NAMELEN,32 # Offset of 8-bit name len
- .set DIR_NAME,33 # Offset of dir name
-
-#
-# Program start.
-#
- .code16
- .globl start
-
-start: jmp main
-
- .org 4
- .ascii "IPL1 "
-
-main: cld
-
- /* Setup the stack */
- xor %ax,%ax
- mov %ax,%ss
- mov $STACK_OFF,%sp
-
- push %ecx
-
- /* Setup graphic screen */
- mov $0x42,%ah # 640x400
- mov $0xc0,%ch
- int $0x18
- mov $0x40,%ah # graph on
- int $0x18
-
- /* Setup text screen */
- mov $0x0a00,%ax # 80x25
- int $0x18
- mov $0x0c,%ah # text on
- int $0x18
- mov $0x13,%ah # cursor home
- xor %dx,%dx
- int $0x18
- mov $0x11,%ah # cursor on
- int $0x18
-
- /* Setup keyboard */
- mov $0x03,%ah
- int $0x18
-
- /* Transfer PC-9801 system common area */
- xor %ax,%ax
- mov %ax,%si
- mov %ax,%ds
- mov %ax,%di
- mov $MEM_SYS,%ax
- mov %ax,%es
- mov $0x0600,%cx
- rep
- movsb
-
- /* Transfer EPSON machine type */
- mov $0xfd00,%ax
- mov %ax,%ds
- mov (0x804),%eax
- and $0x00ffffff,%eax
- mov %eax,%es:(EPSON_ID)
-
- /* Set machine type to PC98_SYSTEM_PARAMETER */
- call machine_check
-
- /* Load cdboot */
- xor %ax,%ax
- mov %ax,%ds
- mov $0x06,%ah /* Read data */
- mov (DAUA),%al /* Read drive */
- pop %ecx /* cylinder */
- xor %dx,%dx /* head / sector */
- mov $LOAD_SEG,%bx /* Load address */
- mov %bx,%es
- xor %bp,%bp
- mov $LOAD_SIZE,%bx /* Load size */
- int $0x1b
- mov $msg_readerr,%si
- jc error
-
- /* Jump to cdboot */
- ljmp $LOAD_SEG,$cdboot
-
-#
-# Set machine type to PC98_SYSTEM_PARAMETER.
-#
-machine_check: xor %edx,%edx
- mov %dx,%ds
- mov $MEM_SYS,%ax
- mov %ax,%es
-
- /* Wait V-SYNC */
-vsync.1: inb $0x60,%al
- test $0x20,%al
- jnz vsync.1
-vsync.2: inb $0x60,%al
- test $0x20,%al
- jz vsync.2
-
- /* ANK 'A' font */
- xor %al,%al
- outb %al,$0xa1
- mov $0x41,%al
- outb %al,$0xa3
-
- /* Get 'A' font from CG window */
- push %ds
- mov $0xa400,%ax
- mov %ax,%ds
- xor %eax,%eax
- xor %bx,%bx
- mov $4,%cx
-font.1: add (%bx),%eax
- add $4,%bx
- loop font.1
- pop %ds
- cmp $0x6efc58fc,%eax
- jnz m_epson
-
-m_pc98: or $M_NEC_PC98,%edx
- mov $0x0458,%bx
- mov (%bx),%al
- test $0x80,%al
- jz m_not_h98
- or $M_H98,%edx
- jmp 1f
-m_epson: or $M_EPSON_PC98,%edx
-m_not_h98: or $M_NOT_H98,%edx
-
-1: inb $0x42,%al
- test $0x20,%al
- jz 1f
- or $M_8M,%edx
-
-1: mov $0x0400,%bx
- mov (%bx),%al
- test $0x80,%al
- jz 1f
- or $M_NOTE,%edx
-
-1: mov $PC98_MACHINE_TYPE,%bx
- mov %edx,%es:(%bx)
- ret
-
-#
-# Print out the error message at [SI], wait for a keypress, and then
-# reboot the machine.
-#
-error: call putstr
- mov $msg_keypress,%si
- call putstr
- xor %ax,%ax # Get keypress
- int $0x18
- xor %ax,%ax # CPU reset
- outb %al,$0xf0
-halt: hlt
- jmp halt # Spin
-
-#
-# Display a null-terminated string at [SI].
-#
-# Trashes: AX, BX, CX, DX, SI, DI
-#
-putstr: push %ds
- push %es
- mov %cs,%ax
- mov %ax,%ds
- mov $0xa000,%ax
- mov %ax,%es
- mov cursor,%di
- mov $0x00e1,%bx # Attribute
- mov $160,%cx
-putstr.0: lodsb
- testb %al,%al
- jz putstr.done
- cmp $0x0d,%al
- jz putstr.cr
- cmp $0x0a,%al
- jz putstr.lf
- mov %bl,%es:0x2000(%di)
- stosb
- inc %di
- jmp putstr.move
-putstr.cr: xor %dx,%dx
- mov %di,%ax
- div %cx
- sub %dx,%di
- jmp putstr.move
-putstr.lf: add %cx,%di
-putstr.move: mov %di,%dx
- mov $0x13,%ah # Move cursor
- int $0x18
- jmp putstr.0
-putstr.done: mov %di,cursor
- pop %es
- pop %ds
- ret
-
-#
-# Display a single char at [AL], but don't move a cursor.
-#
-putc: push %es
- push %di
- push %bx
- mov $0xa000,%bx
- mov %bx,%es
- mov cursor,%di
- mov $0xe1,%bl # Attribute
- mov %bl,%es:0x2000(%di)
- stosb
- pop %bx
- pop %di
- pop %es
- ret
-
-msg_readerr: .asciz "Read Error\r\n"
-msg_keypress: .asciz "\r\nPress any key to reboot\r\n"
-
-/* Boot signature */
-
- .org SIG1_OFF,0x90
-
- .word 0xaa55 # Magic number
-
-#
-# cdboot
-#
-cdboot: mov %cs,%ax
- mov %ax,%ds
- xor %ax,%ax
- mov %ax,%es
- mov %es:(DAUA),%al # Save BIOS boot device
- mov %al,drive
- mov %cx,cylinder # Save BIOS boot cylinder
-
- mov $msg_welcome,%si # %ds:(%si) -> welcome message
- call putstr # display the welcome message
-#
-# Setup the arguments that the loader is expecting from boot[12]
-#
- mov $msg_bootinfo,%si # %ds:(%si) -> boot args message
- call putstr # display the message
- mov $MEM_ARG,%bx # %ds:(%bx) -> boot args
- mov %bx,%di # %es:(%di) -> boot args
- xor %eax,%eax # zero %eax
- mov $(MEM_ARG_SIZE/4),%cx # Size of arguments in 32-bit
- # dwords
- rep # Clear the arguments
- stosl # to zero
- mov drive,%dl # Store BIOS boot device
- mov %dl,%es:0x4(%bx) # in kargs->bootdev
- or $KARGS_FLAGS_CD,%es:0x8(%bx) # kargs->bootflags |=
- # KARGS_FLAGS_CD
-#
-# Load Volume Descriptor
-#
- mov $VOLDESC_LBA,%eax # Set LBA of first VD
-load_vd: push %eax # Save %eax
- mov $1,%dh # One sector
- mov $MEM_VOLDESC,%ebx # Destination
- call read # Read it in
- cmpb $VD_PRIMARY,%es:(%bx) # Primary VD?
- je have_vd # Yes
- pop %eax # Prepare to
- inc %eax # try next
- cmpb $VD_END,%es:(%bx) # Last VD?
- jne load_vd # No, read next
- mov $msg_novd,%si # No VD
- jmp error # Halt
-have_vd: # Have Primary VD
-#
-# Try to look up the loader binary using the paths in the loader_paths
-# array.
-#
- mov $loader_paths,%si # Point to start of array
-lookup_path: push %si # Save file name pointer
- call lookup # Try to find file
- pop %di # Restore file name pointer
- jnc lookup_found # Found this file
- push %es
- mov %cs,%ax
- mov %ax,%es
- xor %al,%al # Look for next
- mov $0xffff,%cx # path name by
- repnz # scanning for
- scasb # nul char
- pop %es
- mov %di,%si # Point %si at next path
- mov (%si),%al # Get first char of next path
- or %al,%al # Is it double nul?
- jnz lookup_path # No, try it.
- mov $msg_failed,%si # Failed message
- jmp error # Halt
-lookup_found: # Found a loader file
-#
-# Load the binary into the buffer. Due to real mode addressing limitations
-# we have to read it in 64k chunks.
-#
- mov %es:DIR_SIZE(%bx),%eax # Read file length
- add $SECTOR_SIZE-1,%eax # Convert length to sectors
- shr $SECTOR_SHIFT,%eax
- cmp $BUFFER_LEN,%eax
- jbe load_sizeok
- mov $msg_load2big,%si # Error message
- jmp error
-load_sizeok: movzbw %al,%cx # Num sectors to read
- mov %es:DIR_EXTENT(%bx),%eax # Load extent
- xor %edx,%edx
- mov %es:DIR_EA_LEN(%bx),%dl
- add %edx,%eax # Skip extended
- mov $MEM_READ_BUFFER,%ebx # Read into the buffer
-load_loop: mov %cl,%dh
- cmp $MAX_READ_SEC,%cl # Truncate to max read size
- jbe load_notrunc
- mov $MAX_READ_SEC,%dh
-load_notrunc: sub %dh,%cl # Update count
- push %eax # Save
- call read # Read it in
- pop %eax # Restore
- add $MAX_READ_SEC,%eax # Update LBA
- add $MAX_READ,%ebx # Update dest addr
- jcxz load_done # Done?
- jmp load_loop # Keep going
-load_done:
-#
-# Turn on the A20 address line
-#
- xor %ax,%ax # Turn A20 on
- outb %al,$0xf2
- mov $0x02,%al
- outb %al,$0xf6
-#
-# Relocate the loader and BTX using a very lazy protected mode
-#
- mov $msg_relocate,%si # Display the
- call putstr # relocation message
- mov %es:(MEM_READ_BUFFER+AOUT_ENTRY),%edi # %edi is the destination
- mov $(MEM_READ_BUFFER+AOUT_HEADER),%esi # %esi is
- # the start of the text
- # segment
- mov %es:(MEM_READ_BUFFER+AOUT_TEXT),%ecx # %ecx = length of the text
- # segment
- push %edi # Save entry point for later
- lgdt gdtdesc # setup our own gdt
- cli # turn off interrupts
- mov %cr0,%eax # Turn on
- or $0x1,%al # protected
- mov %eax,%cr0 # mode
- ljmp $SEL_SCODE,$pm_start # long jump to clear the
- # instruction pre-fetch queue
- .code32
-pm_start: mov $SEL_SDATA,%ax # Initialize
- mov %ax,%ds # %ds and
- mov %ax,%es # %es to a flat selector
- rep # Relocate the
- movsb # text segment
- add $(MEM_PAGE_SIZE - 1),%edi # pad %edi out to a new page
- and $~(MEM_PAGE_SIZE - 1),%edi # for the data segment
- mov MEM_READ_BUFFER+AOUT_DATA,%ecx # size of the data segment
- rep # Relocate the
- movsb # data segment
- mov MEM_READ_BUFFER+AOUT_BSS,%ecx # size of the bss
- xor %eax,%eax # zero %eax
- add $3,%cl # round %ecx up to
- shr $2,%ecx # a multiple of 4
- rep # zero the
- stosl # bss
- mov MEM_READ_BUFFER+AOUT_ENTRY,%esi # %esi -> relocated loader
- add $MEM_BTX_OFFSET,%esi # %esi -> BTX in the loader
- mov $MEM_BTX_ADDRESS,%edi # %edi -> where BTX needs to go
- movzwl 0xa(%esi),%ecx # %ecx -> length of BTX
- rep # Relocate
- movsb # BTX
- ljmp $SEL_SCODE16,$pm_16 # Jump to 16-bit PM
- .code16
-pm_16: mov $SEL_RDATA,%ax # Initialize
- mov %ax,%ds # %ds and
- mov %ax,%es # %es to a real mode selector
- mov %cr0,%eax # Turn off
- and $~0x1,%al # protected
- mov %eax,%cr0 # mode
- ljmp $LOAD_SEG,$pm_end # Long jump to clear the
- # instruction pre-fetch queue
-pm_end: sti # Turn interrupts back on now
-#
-# Copy the BTX client to MEM_BTX_CLIENT
-#
- mov %cs,%ax
- mov %ax,%ds
- xor %ax,%ax
- mov %ax,%es
- mov $MEM_BTX_CLIENT,%di # Prepare to relocate
- mov $btx_client,%si # the simple btx client
- mov $(btx_client_end-btx_client),%cx # length of btx client
- rep # Relocate the
- movsb # simple BTX client
-#
-# Copy the boot[12] args to where the BTX client can see them
-#
- xor %ax,%ax
- mov %ax,%ds
- mov $MEM_ARG,%si # where the args are at now
- mov $MEM_ARG_BTX,%di # where the args are moving to
- mov $(MEM_ARG_SIZE/4),%cx # size of the arguments in longs
- rep # Relocate
- movsl # the words
-#
-# Save the entry point so the client can get to it later on
-#
- pop %eax # Restore saved entry point
- stosl # and add it to the end of
- # the arguments
-#
-# Now we just start up BTX and let it do the rest
-#
- mov $msg_jump,%si # Display the
- call putstr # jump message
- ljmp $0,$MEM_BTX_ENTRY # Jump to the BTX entry point
-
-#
-# Lookup the file in the path at [SI] from the root directory.
-#
-# Trashes: All but BX
-# Returns: CF = 0 (success), BX = pointer to record
-# CF = 1 (not found)
-#
-lookup: mov $VD_ROOTDIR+MEM_VOLDESC,%bx # Root directory record
- push %bx
- push %si
- mov $msg_lookup,%si # Display lookup message
- call putstr
- pop %si
- push %si
- call putstr
- mov $msg_lookup2,%si
- call putstr
- pop %si
- pop %bx
-lookup_dir: lodsb # Get first char of path
- cmp $0,%al # Are we done?
- je lookup_done # Yes
- cmp $'/',%al # Skip path separator.
- je lookup_dir
- dec %si # Undo lodsb side effect
- call find_file # Lookup first path item
- jnc lookup_dir # Try next component
- mov $msg_lookupfail,%si # Not found message
- push %bx
- call putstr
- pop %bx
- stc # Set carry
- ret
-lookup_done: mov $msg_lookupok,%si # Success message
- push %bx
- call putstr
- pop %bx
- clc # Clear carry
- ret
-
-#
-# Lookup file at [SI] in directory whose record is at [BX].
-#
-# Trashes: All but returns
-# Returns: CF = 0 (success), BX = pointer to record, SI = next path item
-# CF = 1 (not found), SI = preserved
-#
-find_file: mov %es:DIR_EXTENT(%bx),%eax # Load extent
- xor %edx,%edx
- mov %es:DIR_EA_LEN(%bx),%dl
- add %edx,%eax # Skip extended attributes
- mov %eax,rec_lba # Save LBA
- mov %es:DIR_SIZE(%bx),%eax # Save size
- mov %eax,rec_size
- xor %cl,%cl # Zero length
- push %si # Save
-ff.namelen: inc %cl # Update length
- lodsb # Read char
- cmp $0,%al # Nul?
- je ff.namedone # Yes
- cmp $'/',%al # Path separator?
- jnz ff.namelen # No, keep going
-ff.namedone: dec %cl # Adjust length and save
- mov %cl,name_len
- pop %si # Restore
-ff.load: mov rec_lba,%eax # Load LBA
- mov $MEM_DIR,%ebx # Address buffer
- mov $1,%dh # One sector
- call read # Read directory block
- incl rec_lba # Update LBA to next block
-ff.scan: mov %ebx,%edx # Check for EOF
- sub $MEM_DIR,%edx
- cmp %edx,rec_size
- ja ff.scan.1
- stc # EOF reached
- ret
-ff.scan.1: cmpb $0,%es:DIR_LEN(%bx) # Last record in block?
- je ff.nextblock
- push %si # Save
- movzbw %es:DIR_NAMELEN(%bx),%si # Find end of string
-ff.checkver: cmpb $'0',%es:DIR_NAME-1(%bx,%si) # Less than '0'?
- jb ff.checkver.1
- cmpb $'9',%es:DIR_NAME-1(%bx,%si) # Greater than '9'?
- ja ff.checkver.1
- dec %si # Next char
- jnz ff.checkver
- jmp ff.checklen # All numbers in name, so
- # no version
-ff.checkver.1: movzbw %es:DIR_NAMELEN(%bx),%cx
- cmp %cx,%si # Did we find any digits?
- je ff.checkdot # No
- cmpb $';',%es:DIR_NAME-1(%bx,%si) # Check for semicolon
- jne ff.checkver.2
- dec %si # Skip semicolon
- mov %si,%cx
- mov %cl,%es:DIR_NAMELEN(%bx) # Adjust length
- jmp ff.checkdot
-ff.checkver.2: mov %cx,%si # Restore %si to end of string
-ff.checkdot: cmpb $'.',%es:DIR_NAME-1(%bx,%si) # Trailing dot?
- jne ff.checklen # No
- decb %es:DIR_NAMELEN(%bx) # Adjust length
-ff.checklen: pop %si # Restore
- movzbw name_len,%cx # Load length of name
- cmp %cl,%es:DIR_NAMELEN(%bx) # Does length match?
- je ff.checkname # Yes, check name
-ff.nextrec: add %es:DIR_LEN(%bx),%bl # Next record
- adc $0,%bh
- jmp ff.scan
-ff.nextblock: subl $SECTOR_SIZE,rec_size # Adjust size
- jnc ff.load # If subtract ok, keep going
- ret # End of file, so not found
-ff.checkname: lea DIR_NAME(%bx),%di # Address name in record
- push %si # Save
- repe cmpsb # Compare name
- je ff.match # We have a winner!
- pop %si # Restore
- jmp ff.nextrec # Keep looking.
-ff.match: add $2,%sp # Discard saved %si
- clc # Clear carry
- ret
-
-#
-# Load DH sectors starting at LBA EAX into [EBX].
-#
-# Trashes: EAX
-#
-read: push %es # Save
- push %bp
- push %dx
- push %cx
- push %ebx
- mov %bx,%bp # Set destination address
- and $0x000f,%bp
- shr $4,%ebx
- mov %bx,%es
- xor %bx,%bx # Set read bytes
- mov %dh,%bl
- shl $SECTOR_SHIFT,%bx # 2048 bytes/sec
- mov %ax,%cx # Set LBA
- shr $16,%eax
- mov %ax,%dx
-read.retry: mov $0x06,%ah # BIOS device read
- mov drive,%al
- and $0x7f,%al
- call twiddle # Entertain the user
- int $0x1b # Call BIOS
- jc read.fail # Worked?
- pop %ebx # Restore
- pop %cx
- pop %dx
- pop %bp
- pop %es
- ret # Return
-read.fail: cmp $ERROR_TIMEOUT,%ah # Timeout?
- je read.retry # Yes, Retry.
-read.error: mov %ah,%al # Save error
- mov $hex_error,%di # Format it
- call hex8 # as hex
- mov $msg_badread,%si # Display Read error message
- jmp error
-
-#
-# Output the "twiddle"
-#
-twiddle: push %ax # Save
- push %bx # Save
- mov twiddle_index,%al # Load index
- mov $twiddle_chars,%bx # Address table
- inc %al # Next
- and $3,%al # char
- mov %al,twiddle_index # Save index for next call
- xlat # Get char
- call putc # Output it
- pop %bx # Restore
- pop %ax # Restore
- ret
-
-#
-# Convert AL to hex, saving the result to [EDI].
-#
-hex8: pushl %eax # Save
- shrb $0x4,%al # Do upper
- call hex8.1 # 4
- popl %eax # Restore
-hex8.1: andb $0xf,%al # Get lower 4
- cmpb $0xa,%al # Convert
- sbbb $0x69,%al # to hex
- das # digit
- orb $0x20,%al # To lower case
- mov %al,(%di) # Save char
- inc %di
- ret # (Recursive)
-
-#
-# BTX client to start btxldr
-#
- .code32
-btx_client: mov $(MEM_ARG_BTX-MEM_BTX_CLIENT+MEM_ARG_SIZE-4), %esi
- # %ds:(%esi) -> end
- # of boot[12] args
- mov $(MEM_ARG_SIZE/4),%ecx # Number of words to push
- std # Go backwards
-push_arg: lodsl # Read argument
- push %eax # Push it onto the stack
- loop push_arg # Push all of the arguments
- cld # In case anyone depends on this
- pushl MEM_ARG_BTX-MEM_BTX_CLIENT+MEM_ARG_SIZE # Entry point of
- # the loader
- push %eax # Emulate a near call
- mov $0x1,%eax # 'exec' system call
- int $INT_SYS # BTX system call
-btx_client_end:
- .code16
-
- .p2align 4
-#
-# Global descriptor table.
-#
-gdt: .word 0x0,0x0,0x0,0x0 # Null entry
- .word 0xffff,0x0000,0x9200,0x00cf # SEL_SDATA
- .word 0xffff,0x0000,0x9200,0x0000 # SEL_RDATA
- .word 0xffff,LOAD_SEG<<4,0x9a00,0x00cf # SEL_SCODE (32-bit)
- .word 0xffff,LOAD_SEG<<4,0x9a00,0x008f # SEL_SCODE16 (16-bit)
-gdt.1:
-#
-# Pseudo-descriptors.
-#
-gdtdesc: .word gdt.1-gdt-1 # Limit
- .long LOAD_SEG<<4 + gdt # Base
-
-#
-# BOOT device
-#
-drive: .byte 0
-cylinder: .word 0
-
-#
-# State for searching dir
-#
-rec_lba: .long 0x0 # LBA (adjusted for EA)
-rec_size: .long 0x0 # File size
-name_len: .byte 0x0 # Length of current name
-
-cursor: .word 0
-twiddle_index: .byte 0x0
-
-msg_welcome: .asciz "CD Loader 1.2\r\n\n"
-msg_bootinfo: .asciz "Building the boot loader arguments\r\n"
-msg_relocate: .asciz "Relocating the loader and the BTX\r\n"
-msg_jump: .asciz "Starting the BTX loader\r\n"
-msg_badread: .ascii "Read Error: 0x"
-hex_error: .asciz "00\r\n"
-msg_novd: .asciz "Could not find Primary Volume Descriptor\r\n"
-msg_lookup: .asciz "Looking up "
-msg_lookup2: .asciz "... "
-msg_lookupok: .asciz "Found\r\n"
-msg_lookupfail: .asciz "File not found\r\n"
-msg_load2big: .asciz "File too big\r\n"
-msg_failed: .asciz "Boot failed\r\n"
-twiddle_chars: .ascii "|/-\\"
-loader_paths: .asciz "/BOOT.PC98/LOADER"
- .asciz "/boot.pc98/loader"
- .asciz "/BOOT/LOADER"
- .asciz "/boot/loader"
- .byte 0
-
-/* Boot signature */
-
- .org SIG2_OFF,0x90
-
- .word 0xaa55 # Magic number
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/pc98/libpc98/Makefile
--- a/head/sys/boot/pc98/libpc98/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/pc98/libpc98/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-# $FreeBSD$
+# $FreeBSD: head/sys/boot/pc98/libpc98/Makefile 235395 2012-05-13 11:34:05Z avg $
#
LIB= pc98
INTERNALLIB=
@@ -10,6 +10,8 @@
comconsole.c devicename.c elf32_freebsd.c \
i386_copy.c i386_module.c nullconsole.c pc98_sys.c pxe.c pxetramp.s \
time.c vidconsole.c
+.PATH: ${.CURDIR}/../../zfs
+SRCS+= devicename_stubs.c
# Enable PXE TFTP or NFS support, not both.
.if defined(LOADER_TFTP_SUPPORT)
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/pc98/libpc98/biosdisk.c
--- a/head/sys/boot/pc98/libpc98/biosdisk.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/pc98/libpc98/biosdisk.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/boot/pc98/libpc98/biosdisk.c 235155 2012-05-09 08:05:50Z avg $");
/*
* BIOS disk device handling.
@@ -52,7 +52,6 @@
#define BIOS_NUMDRIVES 0x475
#define BIOSDISK_SECSIZE 512
#define BUFSIZE (1 * BIOSDISK_SECSIZE)
-#define MAXBDDEV MAXDEV
#define DT_ATAPI 0x10 /* disk type for ATAPI floppies */
#define WDMAJOR 0 /* major numbers for devices we frontend for */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/pc98/loader/main.c
--- a/head/sys/boot/pc98/loader/main.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/pc98/loader/main.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/boot/pc98/loader/main.c 226746 2011-10-25 19:45:12Z jhb $");
+__FBSDID("$FreeBSD: head/sys/boot/pc98/loader/main.c 235264 2012-05-11 09:46:17Z avg $");
/*
* MD bootstrap main() and assorted miscellaneous
@@ -33,29 +33,25 @@
*/
#include <stand.h>
+#include <stddef.h>
#include <string.h>
#include <machine/bootinfo.h>
#include <sys/param.h>
#include <sys/reboot.h>
#include "bootstrap.h"
+#include "common/bootargs.h"
#include "libi386/libi386.h"
#include "libpc98/libpc98.h"
#include "btxv86.h"
-#define KARGS_FLAGS_CD 0x1
-#define KARGS_FLAGS_PXE 0x2
+CTASSERT(sizeof(struct bootargs) == BOOTARGS_SIZE);
+CTASSERT(offsetof(struct bootargs, bootinfo) == BA_BOOTINFO);
+CTASSERT(offsetof(struct bootargs, bootflags) == BA_BOOTFLAGS);
+CTASSERT(offsetof(struct bootinfo, bi_size) == BI_SIZE);
/* Arguments passed in from the boot1/boot2 loader */
-static struct
-{
- u_int32_t howto;
- u_int32_t bootdev;
- u_int32_t bootflags;
- u_int32_t pxeinfo;
- u_int32_t res2;
- u_int32_t bootinfo;
-} *kargs;
+static struct bootargs *kargs;
static u_int32_t initial_howto;
static u_int32_t initial_bootdev;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/powerpc/boot1.chrp/boot1.c
--- a/head/sys/boot/powerpc/boot1.chrp/boot1.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/powerpc/boot1.chrp/boot1.c Wed Jul 25 16:45:04 2012 +0300
@@ -16,7 +16,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/boot/powerpc/boot1.chrp/boot1.c 231810 2012-02-16 03:27:38Z nwhitehorn $");
+__FBSDID("$FreeBSD: head/sys/boot/powerpc/boot1.chrp/boot1.c 235988 2012-05-25 09:36:39Z gleb $");
#include <sys/param.h>
#include <sys/dirent.h>
@@ -45,7 +45,6 @@
static ofwh_t bootdev;
static struct fs fs;
-static ino_t inomap;
static char blkbuf[BSIZEMAX];
static unsigned int fsblks;
@@ -492,7 +491,7 @@
Elf32_Ehdr eh;
Elf32_Phdr ph;
caddr_t p;
- ino_t ino;
+ ufs_ino_t ino;
int i;
if ((ino = lookup(fname)) == 0) {
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/sparc64/Makefile
--- a/head/sys/boot/sparc64/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/sparc64/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,5 +1,5 @@
-# $FreeBSD$
+# $FreeBSD: head/sys/boot/sparc64/Makefile 234898 2012-05-01 17:16:01Z marius $
-SUBDIR= boot1 loader
+SUBDIR= boot1 loader zfsboot zfsloader
.include <bsd.subdir.mk>
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/sparc64/boot1/Makefile
--- a/head/sys/boot/sparc64/boot1/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/sparc64/boot1/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,24 +1,25 @@
-# $FreeBSD$
+# $FreeBSD: head/sys/boot/sparc64/boot1/Makefile 235207 2012-05-09 19:08:54Z marius $
PROG= boot1.elf
INTERNALPROG=
NO_MAN=
-FILES= boot1
+FILES?= boot1
SRCS= _start.s boot1.c
+CLEANFILES=${FILES} boot1.aout
BOOTBLOCKBASE= 0x4000
-CFLAGS= -mcmodel=medlow -Os -I${.CURDIR}/../../common
+CFLAGS+=-mcmodel=medlow -Os -I${.CURDIR}/../../common
LDFLAGS=-Ttext ${BOOTBLOCKBASE} -Wl,-N
# Construct boot1. sunlabel expects it to contain zeroed-out space for the
# label, and to be of the correct size.
-boot1: boot1.aout
+${FILES}: boot1.aout
+ @set -- `ls -l boot1.aout`; x=$$((7680-$$5)); \
+ echo "$$x bytes available"; test $$x -ge 0
dd if=/dev/zero of=${.TARGET} bs=512 count=16
dd if=boot1.aout of=${.TARGET} bs=512 oseek=1 conv=notrunc
-CLEANFILES= boot1.aout
-
boot1.aout: boot1.elf
elf2aout -o ${.TARGET} ${.ALLSRC}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/sparc64/boot1/boot1.c
--- a/head/sys/boot/sparc64/boot1/boot1.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/sparc64/boot1/boot1.c Wed Jul 25 16:45:04 2012 +0300
@@ -16,15 +16,17 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/boot/sparc64/boot1/boot1.c 235988 2012-05-25 09:36:39Z gleb $");
#include <sys/param.h>
#include <sys/dirent.h>
+
#include <machine/elf.h>
#include <machine/stdarg.h>
-#define _PATH_LOADER "/boot/loader"
-#define _PATH_KERNEL "/boot/kernel/kernel"
+#define _PATH_LOADER "/boot/loader"
+#define _PATH_KERNEL "/boot/kernel/kernel"
+#define READ_BUF_SIZE 8192
typedef int putc_func_t(char c, void *arg);
typedef int32_t ofwh_t;
@@ -45,17 +47,21 @@
static uint32_t fs_off;
int main(int ac, char **av);
+static void exit(int) __dead2;
+static void usage(void);
-static void exit(int) __dead2;
+#ifdef ZFSBOOT
+static void loadzfs(void);
+static int zbread(char *buf, off_t off, size_t bytes);
+#else
static void load(const char *);
-static int dskread(void *, u_int64_t, int);
-
-static void usage(void);
+#endif
static void bcopy(const void *src, void *dst, size_t len);
static void bzero(void *b, size_t len);
static int mount(const char *device);
+static int dskread(void *buf, u_int64_t lba, int nblk);
static void panic(const char *fmt, ...) __dead2;
static int printf(const char *fmt, ...);
@@ -312,8 +318,6 @@
return ((u_char)*s1 - (u_char)*s2);
}
-#include "ufsread.c"
-
int
main(int ac, char **av)
{
@@ -335,14 +339,22 @@
}
}
- printf(" \n>> FreeBSD/sparc64 boot block\n"
- " Boot path: %s\n"
- " Boot loader: %s\n", bootpath, path);
+#ifdef ZFSBOOT
+ printf(" \n>> FreeBSD/sparc64 ZFS boot block\n Boot path: %s\n",
+ bootpath);
+#else
+ printf(" \n>> FreeBSD/sparc64 boot block\n Boot path: %s\n"
+ " Boot loader: %s\n", "", bootpath, path);
+#endif
if (mount(bootpath) == -1)
panic("mount");
+#ifdef ZFSBOOT
+ loadzfs();
+#else
load(path);
+#endif
return (1);
}
@@ -361,31 +373,92 @@
ofw_exit();
}
-static struct dmadat __dmadat;
+#ifdef ZFSBOOT
+
+#define VDEV_BOOT_OFFSET (2 * 256 * 1024)
+static char zbuf[READ_BUF_SIZE];
static int
-mount(const char *device)
+zbread(char *buf, off_t off, size_t bytes)
{
+ size_t len;
+ off_t poff;
+ off_t soff;
+ char *p;
+ unsigned int nb;
+ unsigned int lb;
- dmadat = &__dmadat;
- if ((bootdev = ofw_open(device)) == -1) {
- printf("mount: can't open device\n");
- return (-1);
+ p = buf;
+ soff = VDEV_BOOT_OFFSET + off;
+ lb = (soff + bytes + DEV_BSIZE - 1) / DEV_BSIZE;
+ poff = soff;
+ while (poff < soff + bytes) {
+ nb = lb - poff / DEV_BSIZE;
+ if (nb > READ_BUF_SIZE / DEV_BSIZE)
+ nb = READ_BUF_SIZE / DEV_BSIZE;
+ if (dskread(zbuf, poff / DEV_BSIZE, nb))
+ break;
+ if ((poff / DEV_BSIZE + nb) * DEV_BSIZE > soff + bytes)
+ len = soff + bytes - poff;
+ else
+ len = (poff / DEV_BSIZE + nb) * DEV_BSIZE - poff;
+ memcpy(p, zbuf + poff % DEV_BSIZE, len);
+ p += len;
+ poff += len;
}
- if (fsread(0, NULL, 0)) {
- printf("mount: can't read superblock\n");
- return (-1);
+ return (poff - soff);
+}
+
+static void
+loadzfs(void)
+{
+ Elf64_Ehdr eh;
+ Elf64_Phdr ph;
+ caddr_t p;
+ int i;
+
+ if (zbread((char *)&eh, 0, sizeof(eh)) != sizeof(eh)) {
+ printf("Can't read elf header\n");
+ return;
}
- return (0);
+ if (!IS_ELF(eh)) {
+ printf("Not an ELF file\n");
+ return;
+ }
+ for (i = 0; i < eh.e_phnum; i++) {
+ fs_off = eh.e_phoff + i * eh.e_phentsize;
+ if (zbread((char *)&ph, fs_off, sizeof(ph)) != sizeof(ph)) {
+ printf("Can't read program header %d\n", i);
+ return;
+ }
+ if (ph.p_type != PT_LOAD)
+ continue;
+ fs_off = ph.p_offset;
+ p = (caddr_t)ph.p_vaddr;
+ if (zbread(p, fs_off, ph.p_filesz) != ph.p_filesz) {
+ printf("Can't read content of section %d\n", i);
+ return;
+ }
+ if (ph.p_filesz != ph.p_memsz)
+ bzero(p + ph.p_filesz, ph.p_memsz - ph.p_filesz);
+ }
+ ofw_close(bootdev);
+ (*(void (*)(int, int, int, int, ofwfp_t))eh.e_entry)(0, 0, 0, 0, ofw);
}
+#else
+
+#include "ufsread.c"
+
+static struct dmadat __dmadat;
+
static void
load(const char *fname)
{
Elf64_Ehdr eh;
Elf64_Phdr ph;
caddr_t p;
- ino_t ino;
+ ufs_ino_t ino;
int i;
if ((ino = lookup(fname)) == 0) {
@@ -421,6 +494,26 @@
(*(void (*)(int, int, int, int, ofwfp_t))eh.e_entry)(0, 0, 0, 0, ofw);
}
+#endif /* ZFSBOOT */
+
+static int
+mount(const char *device)
+{
+
+ if ((bootdev = ofw_open(device)) == -1) {
+ printf("mount: can't open device\n");
+ return (-1);
+ }
+#ifndef ZFSBOOT
+ dmadat = &__dmadat;
+ if (fsread(0, NULL, 0)) {
+ printf("mount: can't read superblock\n");
+ return (-1);
+ }
+#endif
+ return (0);
+}
+
static int
dskread(void *buf, u_int64_t lba, int nblk)
{
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/sparc64/loader/Makefile
--- a/head/sys/boot/sparc64/loader/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/sparc64/loader/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,10 +1,10 @@
-# $FreeBSD: head/sys/boot/sparc64/loader/Makefile 222472 2011-05-30 04:23:33Z julian $
+# $FreeBSD: head/sys/boot/sparc64/loader/Makefile 235364 2012-05-12 20:27:33Z avg $
.include <bsd.own.mk>
MK_SSP= no
-PROG= loader
-NEWVERSWHAT= "bootstrap loader" sparc64
+PROG?= loader
+NEWVERSWHAT?= "bootstrap loader" sparc64
INSTALLFLAGS= -b
# Architecture-specific loader code
@@ -13,12 +13,17 @@
LOADER_DISK_SUPPORT?= yes
LOADER_UFS_SUPPORT?= yes
LOADER_CD9660_SUPPORT?= yes
+LOADER_ZFS_SUPPORT?= no
LOADER_NET_SUPPORT?= yes
LOADER_NFS_SUPPORT?= yes
LOADER_TFTP_SUPPORT?= yes
LOADER_GZIP_SUPPORT?= yes
LOADER_BZIP2_SUPPORT?= no
+LOADER_DEBUG?= no
+.if ${LOADER_DEBUG} == "yes"
+CFLAGS+= -DLOADER_DEBUG
+.endif
.if ${LOADER_DISK_SUPPORT} == "yes"
CFLAGS+= -DLOADER_DISK_SUPPORT
.endif
@@ -28,6 +33,12 @@
.if ${LOADER_CD9660_SUPPORT} == "yes"
CFLAGS+= -DLOADER_CD9660_SUPPORT
.endif
+.if ${LOADER_ZFS_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_ZFS_SUPPORT
+CFLAGS+= -I${.CURDIR}/../../zfs
+CFLAGS+= -I${.CURDIR}/../../../cddl/boot/zfs
+LIBZFSBOOT= ${.OBJDIR}/../../zfs/libzfsboot.a
+.endif
.if ${LOADER_GZIP_SUPPORT} == "yes"
CFLAGS+= -DLOADER_GZIP_SUPPORT
.endif
@@ -47,7 +58,8 @@
.if ${MK_FORTH} != "no"
# Enable BootForth
BOOT_FORTH= yes
-CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/sparc64
+CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl
+CFLAGS+= -I${.CURDIR}/../../ficl/sparc64
LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
.endif
@@ -72,11 +84,12 @@
# where to get libstand from
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/
-DPADD= ${LIBFICL} ${LIBOFW} ${LIBSTAND}
-LDADD= ${LIBFICL} ${LIBOFW} -lstand
+DPADD= ${LIBFICL} ${LIBZFSBOOT} ${LIBOFW} ${LIBSTAND}
+LDADD= ${LIBFICL} ${LIBZFSBOOT} ${LIBOFW} -lstand
-vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
- sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
+vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/../loader/version
+ sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/../loader/version \
+ ${NEWVERSWHAT}
loader.help: help.common help.sparc64
cat ${.ALLSRC} | \
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/sparc64/loader/main.c
--- a/head/sys/boot/sparc64/loader/main.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/sparc64/loader/main.c Wed Jul 25 16:45:04 2012 +0300
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/boot/sparc64/loader/main.c 223719 2011-07-02 11:14:54Z marius $");
+__FBSDID("$FreeBSD: head/sys/boot/sparc64/loader/main.c 236581 2012-06-04 20:56:40Z marius $");
/*
* FreeBSD/sparc64 kernel loader - machine dependent part
@@ -51,6 +51,10 @@
#include <sys/linker.h>
#include <sys/queue.h>
#include <sys/types.h>
+#ifdef LOADER_ZFS_SUPPORT
+#include <sys/vtoc.h>
+#include "../zfs/libzfs.h"
+#endif
#include <vm/vm.h>
#include <machine/asi.h>
@@ -71,11 +75,7 @@
#include "libofw.h"
#include "dev_net.h"
-#ifndef CTASSERT
-#define CTASSERT(x) _CTASSERT(x, __LINE__)
-#define _CTASSERT(x, y) __CTASSERT(x, y)
-#define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1]
-#endif
+#define MAXDEV 31
extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
@@ -141,6 +141,7 @@
static vm_offset_t curkva = 0;
static vm_offset_t heapva;
+static char bootpath[64];
static phandle_t root;
/*
@@ -154,6 +155,9 @@
#ifdef LOADER_NET_SUPPORT
&netdev,
#endif
+#ifdef LOADER_ZFS_SUPPORT
+ &zfs_dev,
+#endif
0
};
struct arch_switch archsw;
@@ -166,6 +170,7 @@
&sparc64_elf,
0
};
+
struct fs_ops *file_system[] = {
#ifdef LOADER_UFS_SUPPORT
&ufs_fsops,
@@ -173,6 +178,9 @@
#ifdef LOADER_CD9660_SUPPORT
&cd9660_fsops,
#endif
+#ifdef LOADER_ZFS_SUPPORT
+ &zfs_fsops,
+#endif
#ifdef LOADER_ZIP_SUPPORT
&zipfs_fsops,
#endif
@@ -721,10 +729,58 @@
panic("%s: can't allocate TLB store", __func__);
}
+#ifdef LOADER_ZFS_SUPPORT
+static void
+sparc64_zfs_probe(void)
+{
+ struct vtoc8 vtoc;
+ struct zfs_devdesc zfs_currdev;
+ char devname[32];
+ uint64_t guid;
+ int fd, part, unit;
+
+ /* Get the GUID of the ZFS pool on the boot device. */
+ guid = 0;
+ zfs_probe_dev(bootpath, &guid);
+
+ for (unit = 0; unit < MAXDEV; unit++) {
+ /* Find freebsd-zfs slices in the VTOC. */
+ sprintf(devname, "disk%d:", unit);
+ fd = open(devname, O_RDONLY);
+ if (fd == -1)
+ continue;
+ lseek(fd, 0, SEEK_SET);
+ if (read(fd, &vtoc, sizeof(vtoc)) != sizeof(vtoc)) {
+ close(fd);
+ continue;
+ }
+ close(fd);
+
+ for (part = 0; part < 8; part++) {
+ if (part == 2 || vtoc.part[part].tag !=
+ VTOC_TAG_FREEBSD_ZFS)
+ continue;
+ sprintf(devname, "disk%d:%c", unit, part + 'a');
+ if (zfs_probe_dev(devname, NULL) == ENXIO)
+ break;
+ }
+ }
+
+ if (guid != 0) {
+ zfs_currdev.pool_guid = guid;
+ zfs_currdev.root_guid = 0;
+ zfs_currdev.d_dev = &zfs_dev;
+ zfs_currdev.d_type = zfs_currdev.d_dev->dv_type;
+ (void)strncpy(bootpath, zfs_fmtdev(&zfs_currdev),
+ sizeof(bootpath) - 1);
+ bootpath[sizeof(bootpath) - 1] = '\0';
+ }
+}
+#endif /* LOADER_ZFS_SUPPORT */
+
int
main(int (*openfirm)(void *))
{
- char bootpath[64];
char compatible[32];
struct devsw **dp;
@@ -738,6 +794,9 @@
archsw.arch_copyout = ofw_copyout;
archsw.arch_readin = sparc64_readin;
archsw.arch_autoload = sparc64_autoload;
+#ifdef LOADER_ZFS_SUPPORT
+ archsw.arch_zfs_probe = sparc64_zfs_probe;
+#endif
if (init_heap() == (vm_offset_t)-1)
OF_exit();
@@ -756,14 +815,6 @@
mmu_ops->tlb_init();
/*
- * Initialize devices.
- */
- for (dp = devsw; *dp != 0; dp++) {
- if ((*dp)->dv_init != 0)
- (*dp)->dv_init();
- }
-
- /*
* Set up the current device.
*/
OF_getprop(chosen, "bootpath", bootpath, sizeof(bootpath));
@@ -780,11 +831,23 @@
* needs to be altered.
*/
if (bootpath[strlen(bootpath) - 2] == ':' &&
- bootpath[strlen(bootpath) - 1] == 'f') {
+ bootpath[strlen(bootpath) - 1] == 'f' &&
+ strstr(bootpath, "cdrom") != NULL) {
bootpath[strlen(bootpath) - 1] = 'a';
printf("Boot path set to %s\n", bootpath);
}
+ /*
+ * Initialize devices.
+ */
+ for (dp = devsw; *dp != 0; dp++)
+ if ((*dp)->dv_init != 0)
+ (*dp)->dv_init();
+
+ /*
+ * Now that sparc64_zfs_probe() might have altered bootpath,
+ * export it.
+ */
env_setenv("currdev", EV_VOLATILE, bootpath,
ofw_setcurrdev, env_nounset);
env_setenv("loaddev", EV_VOLATILE, bootpath,
@@ -800,6 +863,18 @@
return (1);
}
+COMMAND_SET(heap, "heap", "show heap usage", command_heap);
+
+static int
+command_heap(int argc, char *argv[])
+{
+
+ mallocstats();
+ printf("heap base at %p, top at %p, upper limit at %p\n", heapva,
+ sbrk(0), heapva + HEAPSZ);
+ return(CMD_OK);
+}
+
COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
static int
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/sparc64/zfsboot/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/boot/sparc64/zfsboot/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,9 @@
+# $FreeBSD: head/sys/boot/sparc64/zfsboot/Makefile 235207 2012-05-09 19:08:54Z marius $
+
+.PATH: ${.CURDIR}/../boot1
+
+PROGNAME= zfsboot
+CFLAGS+= -DZFSBOOT
+FILES= zfsboot
+
+.include "${.CURDIR}/../boot1/Makefile"
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/sparc64/zfsloader/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/boot/sparc64/zfsloader/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,9 @@
+# $FreeBSD: head/sys/boot/sparc64/zfsloader/Makefile 234898 2012-05-01 17:16:01Z marius $
+
+.PATH: ${.CURDIR}/../loader
+
+PROG= zfsloader
+NEWVERSWHAT= "ZFS enabled bootstrap loader" sparc64
+LOADER_ZFS_SUPPORT=yes
+
+.include "${.CURDIR}/../loader/Makefile"
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/uboot/common/metadata.c
--- a/head/sys/boot/uboot/common/metadata.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/uboot/common/metadata.c Wed Jul 25 16:45:04 2012 +0300
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/boot/uboot/common/metadata.c 233230 2012-03-20 13:08:57Z raj $");
+__FBSDID("$FreeBSD: head/sys/boot/uboot/common/metadata.c 235529 2012-05-17 04:04:48Z kientzle $");
#include <stand.h>
#include <sys/param.h>
@@ -42,7 +42,7 @@
#include "glue.h"
#if defined(LOADER_FDT_SUPPORT)
-extern int fdt_fixup(void);
+extern vm_offset_t fdt_fixup(void);
#endif
/*
@@ -72,6 +72,7 @@
md_getboothowto(char *kargs)
{
char *cp;
+ char *p;
int howto;
int active;
int i;
@@ -132,10 +133,12 @@
if (getenv(howto_names[i].ev) != NULL)
howto |= howto_names[i].mask;
}
- if (!strcmp(getenv("console"), "comconsole"))
- howto |= RB_SERIAL;
- if (!strcmp(getenv("console"), "nullconsole"))
- howto |= RB_MUTE;
+ if ((p = getenv("console"))) {
+ if (!strcmp(p, "comconsole"))
+ howto |= RB_SERIAL;
+ if (!strcmp(p, "nullconsole"))
+ howto |= RB_MUTE;
+ }
return(howto);
}
@@ -334,7 +337,7 @@
#if defined(LOADER_FDT_SUPPORT)
/* Handle device tree blob */
dtbp = fdt_fixup();
- if (dtbp != (vm_offset_t)NULL)
+ if (dtbp != 0)
file_addmetadata(kfp, MODINFOMD_DTBP, sizeof dtbp, &dtbp);
else
pager_output("WARNING! Trying to fire up the kernel, but no "
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/uboot/lib/api_public.h
--- a/head/sys/boot/uboot/lib/api_public.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/uboot/lib/api_public.h Wed Jul 25 16:45:04 2012 +0300
@@ -48,7 +48,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/boot/uboot/lib/api_public.h 235609 2012-05-18 14:41:14Z gber $
*
* This file needs to be kept in sync with U-Boot reference:
* http://www.denx.de/cgi-bin/gitweb.cgi?p=u-boot.git;a=blob;f=include/api_public.h
@@ -132,6 +132,7 @@
#define DT_STOR_SCSI 0x0020
#define DT_STOR_USB 0x0040
#define DT_STOR_MMC 0x0080
+#define DT_STOR_NAND 0x0100
#define DEV_STA_CLOSED 0x0000 /* invalid, closed */
#define DEV_STA_OPEN 0x0001 /* open i.e. active */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/uboot/lib/copy.c
--- a/head/sys/boot/uboot/lib/copy.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/uboot/lib/copy.c Wed Jul 25 16:45:04 2012 +0300
@@ -26,35 +26,67 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/boot/uboot/lib/copy.c 235694 2012-05-20 18:07:35Z kientzle $");
#include <stand.h>
+#include <stdint.h>
+
+#include "api_public.h"
+#include "glue.h"
/*
* MD primitives supporting placement of module data
- *
- * XXX should check load address/size against memory top.
*/
+void *
+uboot_vm_translate(vm_offset_t o) {
+ struct sys_info *si;
+ static uintptr_t start = 0;
+ static size_t size = 0;
+ int i;
+
+ if (size == 0) {
+ if ((si = ub_get_sys_info()) == NULL)
+ panic("could not retrieve system info");
+
+ /* Find start/size of largest DRAM block. */
+ for (i = 0; i < si->mr_no; i++) {
+ if (si->mr[i].flags == MR_ATTR_DRAM
+ && si->mr[i].size > size) {
+ start = si->mr[i].start;
+ size = si->mr[i].size;
+ }
+ }
+
+ if (size <= 0)
+ panic("No suitable DRAM?\n");
+ /*
+ printf("Loading into memory region 0x%08X-0x%08X (%d MiB)\n",
+ start, start + size, size / 1024 / 1024);
+ */
+ }
+ if (o > size)
+ panic("Address 0x%08jX bigger than size 0x%08X\n",
+ (intmax_t)o, size);
+ return (void *)(start + o);
+}
+
ssize_t
uboot_copyin(const void *src, vm_offset_t dest, const size_t len)
{
-
- bcopy(src, (void *)dest, len);
+ bcopy(src, uboot_vm_translate(dest), len);
return (len);
}
ssize_t
uboot_copyout(const vm_offset_t src, void *dest, const size_t len)
{
-
- bcopy((void *)src, dest, len);
+ bcopy(uboot_vm_translate(src), dest, len);
return (len);
}
ssize_t
uboot_readin(const int fd, vm_offset_t dest, const size_t len)
{
-
- return (read(fd, (void *) dest, len));
+ return (read(fd, uboot_vm_translate(dest), len));
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/uboot/lib/devicename.c
--- a/head/sys/boot/uboot/lib/devicename.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/uboot/lib/devicename.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/boot/uboot/lib/devicename.c 234860 2012-05-01 05:04:49Z kientzle $");
#include <sys/disklabel.h>
@@ -131,6 +131,10 @@
*(cp + 1) != ':') {
pnum = strtol(cp + 1, &cp, 10);
ptype = PTYPE_GPT;
+ } else if (*cp == 's' && *(cp + 1) &&
+ *(cp + 1) != ':') {
+ pnum = strtol(cp + 1, &cp, 10);
+ ptype = PTYPE_MBR;
} else {
pnum = *cp - 'a';
ptype = PTYPE_BSDLABEL;
@@ -218,6 +222,9 @@
else if (dev->d_kind.disk.ptype == PTYPE_GPT)
cp += sprintf(cp, "p%i",
dev->d_kind.disk.pnum);
+ else if (dev->d_kind.disk.ptype == PTYPE_MBR)
+ cp += sprintf(cp, "s%i",
+ dev->d_kind.disk.pnum);
}
strcat(cp, ":");
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/uboot/lib/disk.c
--- a/head/sys/boot/uboot/lib/disk.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/uboot/lib/disk.c Wed Jul 25 16:45:04 2012 +0300
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/boot/uboot/lib/disk.c 234860 2012-05-01 05:04:49Z kientzle $");
#include <sys/param.h>
#include <sys/endian.h>
@@ -398,6 +398,94 @@
}
static int
+stor_open_mbr(struct open_dev *od, struct uboot_devdesc *dev)
+{
+ char *buf = NULL;
+ struct dos_partition *dp;
+ int err, i, part;
+
+ od->od_nparts = 0;
+ od->od_partitions = NULL;
+
+ /* Block size must be at least 512 bytes. */
+ if (od->od_bsize < 512)
+ return (ENXIO);
+
+ /* Read MBR */
+ buf = malloc(od->od_bsize);
+ if (!buf) {
+ stor_printf("could not allocate memory for MBR\n");
+ return (ENOMEM);
+ }
+ err = stor_readdev(dev, 0, 1, buf);
+ if (err) {
+ stor_printf("MBR read error=%d\n", err);
+ err = EIO;
+ goto out;
+ }
+
+ /* Check the slice table magic. */
+ if (le16toh(*((uint16_t *)(buf + DOSMAGICOFFSET))) != DOSMAGIC) {
+ err = ENXIO;
+ goto out;
+ }
+
+ /* Save information about partitions. */
+ dp = (struct dos_partition *)(buf + DOSPARTOFF);
+ od->od_partitions = calloc(NDOSPART, sizeof(struct gpt_part));
+ if (!od->od_partitions) {
+ stor_printf("could not allocate memory for MBR partitions\n");
+ err = ENOMEM;
+ goto out;
+ }
+
+ part = 0;
+ for (i = 0; i < NDOSPART; i++) {
+ u_int32_t start = le32dec(&dp[i].dp_start);
+ u_int32_t size = le32dec(&dp[i].dp_size);
+ uuid_t *u = NULL;
+
+ /* Map MBR partition types to GPT partition types. */
+ switch (dp[i].dp_typ) {
+ case DOSPTYP_386BSD:
+ u = &freebsd_ufs;
+ break;
+ /* XXX Other types XXX */
+ }
+
+ if (u) {
+ od->od_partitions[part].gp_type = *u;
+ od->od_partitions[part].gp_index = i + 1;
+ od->od_partitions[part].gp_start = start;
+ od->od_partitions[part].gp_end = start + size;
+ part += 1;
+ }
+ }
+ od->od_nparts = part;
+
+ if (od->od_nparts == 0) {
+ err = EINVAL;
+ goto out;
+ }
+
+ dev->d_disk.ptype = PTYPE_MBR;
+
+ /* XXX Be smarter here? XXX */
+ if (dev->d_disk.pnum == 0)
+ dev->d_disk.pnum = od->od_partitions[0].gp_index;
+
+ for (i = 0; i < od->od_nparts; i++)
+ if (od->od_partitions[i].gp_index == dev->d_disk.pnum)
+ od->od_bstart = od->od_partitions[i].gp_start;
+
+out:
+ if (err && od->od_partitions)
+ free(od->od_partitions);
+ free(buf);
+ return (err);
+}
+
+static int
stor_open_bsdlabel(struct open_dev *od, struct uboot_devdesc *dev)
{
char *buf;
@@ -443,7 +531,7 @@
lbasize_t real_size;
int err, handle;
- debugf("reading size=%d @ 0x%08x\n", size, (uint32_t)buf);
+ debugf("reading blk=%d size=%d @ 0x%08x\n", (int)blk, size, (uint32_t)buf);
handle = stor_info[dev->d_unit];
err = ub_dev_read(handle, buf, size, blk, &real_size);
@@ -495,7 +583,10 @@
od->od_bsize = di->di_stor.block_size;
od->od_bstart = 0;
- if ((err = stor_open_gpt(od, dev)) != 0)
+ err = stor_open_gpt(od, dev);
+ if (err != 0)
+ err = stor_open_mbr(od, dev);
+ if (err != 0)
err = stor_open_bsdlabel(od, dev);
if (err != 0)
@@ -517,6 +608,8 @@
od = (struct open_dev *)dev->d_disk.data;
if (dev->d_disk.ptype == PTYPE_GPT && od->od_nparts != 0)
free(od->od_partitions);
+ if (dev->d_disk.ptype == PTYPE_MBR && od->od_nparts != 0)
+ free(od->od_partitions);
free(od);
dev->d_disk.data = NULL;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/uboot/lib/elf_freebsd.c
--- a/head/sys/boot/uboot/lib/elf_freebsd.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/uboot/lib/elf_freebsd.c Wed Jul 25 16:45:04 2012 +0300
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/boot/uboot/lib/elf_freebsd.c 235694 2012-05-20 18:07:35Z kientzle $");
#include <sys/param.h>
#include <sys/linker.h>
@@ -38,6 +38,7 @@
#include <stand.h>
#include "bootstrap.h"
+#include "libuboot.h"
extern vm_offset_t md_load(char *, vm_offset_t *);
@@ -69,6 +70,7 @@
vm_offset_t mdp;
Elf_Ehdr *e;
int error;
+ void (*entry)(void *);
if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
return (EFTYPE);
@@ -78,11 +80,12 @@
if ((error = md_load(fp->f_args, &mdp)) != 0)
return (error);
- printf("Kernel entry at 0x%x ...\n", e->e_entry);
+ entry = uboot_vm_translate(e->e_entry);
+ printf("Kernel entry at 0x%x...\n", (unsigned)entry);
dev_cleanup();
- (*(void (*)())e->e_entry)((void *)mdp);
+ (*entry)((void *)mdp);
panic("exec returned");
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/uboot/lib/glue.c
--- a/head/sys/boot/uboot/lib/glue.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/uboot/lib/glue.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/boot/uboot/lib/glue.c 233287 2012-03-21 20:53:47Z marius $");
+__FBSDID("$FreeBSD: head/sys/boot/uboot/lib/glue.c 235609 2012-05-18 14:41:14Z gber $");
#include <sys/types.h>
@@ -407,6 +407,9 @@
if (type & DT_STOR_MMC)
return ("MMC");
+ if (type & DT_STOR_NAND)
+ return ("NAND");
+
return ("Unknown");
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/uboot/lib/libuboot.h
--- a/head/sys/boot/uboot/lib/libuboot.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/uboot/lib/libuboot.h Wed Jul 25 16:45:04 2012 +0300
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/boot/uboot/lib/libuboot.h 235694 2012-05-20 18:07:35Z kientzle $
*/
struct uboot_devdesc
@@ -45,6 +45,7 @@
#define PTYPE_BSDLABEL 1
#define PTYPE_GPT 2
+#define PTYPE_MBR 3
/*
* Default network packet alignment in memory
@@ -59,6 +60,7 @@
extern struct netif_driver uboot_net;
extern struct devsw uboot_storage;
+void *uboot_vm_translate(vm_offset_t);
ssize_t uboot_copyin(const void *src, vm_offset_t dest, const size_t len);
ssize_t uboot_copyout(const vm_offset_t src, void *dest, const size_t len);
ssize_t uboot_readin(const int fd, vm_offset_t dest, const size_t len);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/userboot/libstand/Makefile
--- a/head/sys/boot/userboot/libstand/Makefile Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/userboot/libstand/Makefile Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-# $FreeBSD: head/sys/boot/userboot/libstand/Makefile 229368 2012-01-03 07:14:01Z ed $
+# $FreeBSD: head/sys/boot/userboot/libstand/Makefile 237410 2012-06-21 21:47:08Z delphij $
# Originally from $NetBSD: Makefile,v 1.21 1997/10/26 22:08:38 lukem Exp $
#
# Notes:
@@ -42,7 +42,7 @@
.endif
# standalone components and stuff we have modified locally
-SRCS+= zutil.h __main.c assert.c bcd.c bswap.c environment.c getopt.c gets.c \
+SRCS+= gzguts.h zutil.h __main.c assert.c bcd.c bswap.c environment.c getopt.c gets.c \
globals.c pager.c printf.c strdup.c strerror.c strtol.c random.c \
sbrk.c twiddle.c zalloc.c zalloc_malloc.c
@@ -125,23 +125,28 @@
# decompression functionality from libz
.PATH: ${.CURDIR}/../../../../lib/libz
CFLAGS+=-DHAVE_MEMCPY -I${.CURDIR}/../../../../lib/libz
-SRCS+= adler32.c crc32.c libstand_zutil.h
+SRCS+= adler32.c crc32.c libstand_zutil.h libstand_gzguts.h
.for file in infback.c inffast.c inflate.c inftrees.c zutil.c
SRCS+= _${file}
CLEANFILES+= _${file}
_${file}: ${file}
- sed "s|zutil\.h|libstand_zutil.h|" ${.ALLSRC} > ${.TARGET}
+ sed -e "s|zutil\.h|libstand_zutil.h|" \
+ -e "s|gzguts\.h|libstand_gzguts.h|" ${.ALLSRC} > ${.TARGET}
.endfor
# depend on stand.h being able to be included multiple times
-CLEANFILES+= libstand_zutil.h
-libstand_zutil.h: zutil.h
- sed -e 's|<stddef.h>|"stand.h"|' \
+.for file in zutil.h gzguts.h
+CLEANFILES+= libstand_${file}
+libstand_${file}: ${file}
+ sed -e 's|<fcntl.h>|"stand.h"|' \
+ -e 's|<stddef.h>|"stand.h"|' \
-e 's|<string.h>|"stand.h"|' \
+ -e 's|<stdio.h>|"stand.h"|' \
-e 's|<stdlib.h>|"stand.h"|' \
${.ALLSRC} > ${.TARGET}
+.endfor
# io routines
SRCS+= closeall.c dev.c ioctl.c nullfs.c stat.c \
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/zfs/devicename_stubs.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/boot/zfs/devicename_stubs.c Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2012 Andriy Gapon <avg at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: head/sys/boot/zfs/devicename_stubs.c 235329 2012-05-12 09:03:30Z avg $");
+
+#include <stand.h>
+#include "libzfs.h"
+
+__attribute__((weak))
+int
+zfs_parsedev(struct zfs_devdesc *dev, const char *devspec, const char **path)
+{
+ return (EINVAL);
+}
+
+__attribute__((weak))
+char *
+zfs_fmtdev(void *vdev)
+{
+ static char buf[128];
+
+ return (buf);
+}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/zfs/libzfs.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/boot/zfs/libzfs.h Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 2012 Andriy Gapon <avg at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: head/sys/boot/zfs/libzfs.h 235329 2012-05-12 09:03:30Z avg $
+ */
+
+#ifndef _BOOT_LIBZFS_H_
+#define _BOOT_LIBZFS_H_
+
+#define ZFS_MAXNAMELEN 256
+
+/*
+ * ZFS fully-qualified device descriptor.
+ * Note, this must match the 'struct devdesc' declaration in bootstrap.h.
+ * Arch-specific device descriptors should be binary compatible with this
+ * structure if they are to support ZFS.
+ */
+struct zfs_devdesc
+{
+ struct devsw *d_dev;
+ int d_type;
+ int d_unit;
+ void *d_opendata;
+ uint64_t pool_guid;
+ uint64_t root_guid;
+};
+
+struct zfs_boot_args
+{
+ uint32_t size;
+ uint32_t reserved;
+ uint64_t pool;
+ uint64_t root;
+};
+
+int zfs_parsedev(struct zfs_devdesc *dev, const char *devspec,
+ const char **path);
+char *zfs_fmtdev(void *vdev);
+int zfs_probe_dev(const char *devname, uint64_t *pool_guid);
+
+extern struct devsw zfs_dev;
+extern struct fs_ops zfs_fsops;
+
+#endif /*_BOOT_LIBZFS_H_*/
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/zfs/zfs.c
--- a/head/sys/boot/zfs/zfs.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/zfs/zfs.c Wed Jul 25 16:45:04 2012 +0300
@@ -23,11 +23,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/boot/zfs/zfs.c 235394 2012-05-13 10:54:43Z avg $
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/boot/zfs/zfs.c 235394 2012-05-13 10:54:43Z avg $");
/*
* Stand-alone file reading package.
@@ -43,10 +43,10 @@
#include <stand.h>
#include <bootstrap.h>
+#include "libzfs.h"
+
#include "zfsimpl.c"
-#define MAXBDDEV 31
-
static int zfs_open(const char *path, struct open_file *f);
static int zfs_write(struct open_file *f, void *buf, size_t size, size_t *resid);
static int zfs_close(struct open_file *f);
@@ -85,35 +85,20 @@
static int
zfs_open(const char *upath, struct open_file *f)
{
- spa_t *spa = (spa_t *) f->f_devdata;
+ struct zfsmount *mount = (struct zfsmount *)f->f_devdata;
struct file *fp;
int rc;
if (f->f_dev != &zfs_dev)
return (EINVAL);
- rc = zfs_mount_pool(spa);
- if (rc)
- return (rc);
-
/* allocate file system specific data structure */
fp = malloc(sizeof(struct file));
bzero(fp, sizeof(struct file));
f->f_fsdata = (void *)fp;
- if (spa->spa_root_objset.os_type != DMU_OST_ZFS) {
- printf("Unexpected object set type %llu\n",
- spa->spa_root_objset.os_type);
- rc = EIO;
- goto out;
- }
-
- rc = zfs_lookup(spa, upath, &fp->f_dnode);
- if (rc)
- goto out;
-
+ rc = zfs_lookup(mount, upath, &fp->f_dnode);
fp->f_seekp = 0;
-out:
if (rc) {
f->f_fsdata = NULL;
free(fp);
@@ -142,7 +127,7 @@
static int
zfs_read(struct open_file *f, void *start, size_t size, size_t *resid /* out */)
{
- spa_t *spa = (spa_t *) f->f_devdata;
+ const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa;
struct file *fp = (struct file *)f->f_fsdata;
struct stat sb;
size_t n;
@@ -216,7 +201,7 @@
static int
zfs_stat(struct open_file *f, struct stat *sb)
{
- spa_t *spa = (spa_t *) f->f_devdata;
+ const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa;
struct file *fp = (struct file *)f->f_fsdata;
return (zfs_dnode_stat(spa, &fp->f_dnode, sb));
@@ -225,7 +210,7 @@
static int
zfs_readdir(struct open_file *f, struct dirent *d)
{
- spa_t *spa = (spa_t *) f->f_devdata;
+ const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa;
struct file *fp = (struct file *)f->f_fsdata;
mzap_ent_phys_t mze;
struct stat sb;
@@ -381,64 +366,31 @@
}
}
-/*
- * Convert a pool guid to a 'unit number' suitable for use with zfs_dev_open.
- */
+static int
+zfs_dev_init(void)
+{
+ zfs_init();
+ if (archsw.arch_zfs_probe == NULL)
+ return (ENXIO);
+ archsw.arch_zfs_probe();
+ return (0);
+}
+
int
-zfs_guid_to_unit(uint64_t guid)
+zfs_probe_dev(const char *devname, uint64_t *pool_guid)
{
spa_t *spa;
- int unit;
+ int fd;
+ int ret;
- unit = 0;
- STAILQ_FOREACH(spa, &zfs_pools, spa_link) {
- if (spa->spa_guid == guid)
- return unit;
- unit++;
- }
- return (-1);
-}
-
-static int
-zfs_dev_init(void)
-{
- char devname[512];
- int unit, slice;
- int fd;
-
- /*
- * Open all the disks we can find and see if we can reconstruct
- * ZFS pools from them. Bogusly assumes that the disks are named
- * diskN, diskNpM or diskNsM.
- */
- zfs_init();
- for (unit = 0; unit < MAXBDDEV; unit++) {
- sprintf(devname, "disk%d:", unit);
- fd = open(devname, O_RDONLY);
- if (fd == -1)
- continue;
-
- /*
- * If we find a vdev, the zfs code will eat the fd, otherwise
- * we close it.
- */
- if (vdev_probe(vdev_read, (void*) (uintptr_t) fd, 0))
- close(fd);
-
- for (slice = 1; slice <= 128; slice++) {
- sprintf(devname, "disk%dp%d:", unit, slice);
- fd = open(devname, O_RDONLY);
- if (fd == -1) {
- sprintf(devname, "disk%ds%d:", unit, slice);
- fd = open(devname, O_RDONLY);
- if (fd == -1)
- continue;
- }
- if (vdev_probe(vdev_read, (void*) (uintptr_t) fd, 0))
- close(fd);
- }
- }
-
+ fd = open(devname, O_RDONLY);
+ if (fd == -1)
+ return (ENXIO);
+ ret = vdev_probe(vdev_read, (void *)(uintptr_t)fd, &spa);
+ if (ret != 0)
+ close(fd);
+ else if (pool_guid != NULL)
+ *pool_guid = spa->spa_guid;
return (0);
}
@@ -450,54 +402,52 @@
{
spa_t *spa;
char line[80];
- int unit;
if (verbose) {
spa_all_status();
return;
}
- unit = 0;
STAILQ_FOREACH(spa, &zfs_pools, spa_link) {
- sprintf(line, " zfs%d: %s\n", unit, spa->spa_name);
+ sprintf(line, " zfs:%s\n", spa->spa_name);
pager_output(line);
- unit++;
}
}
/*
* Attempt to open the pool described by (dev) for use by (f).
*/
-static int
+static int
zfs_dev_open(struct open_file *f, ...)
{
va_list args;
- struct devdesc *dev;
- int unit, i;
+ struct zfs_devdesc *dev;
+ struct zfsmount *mount;
spa_t *spa;
+ int rv;
va_start(args, f);
- dev = va_arg(args, struct devdesc*);
+ dev = va_arg(args, struct zfs_devdesc *);
va_end(args);
- /*
- * We mostly ignore the stuff that devopen sends us. For now,
- * use the unit to find a pool - later we will override the
- * devname parsing so that we can name a pool and a fs within
- * the pool.
- */
- unit = dev->d_unit;
-
- i = 0;
- STAILQ_FOREACH(spa, &zfs_pools, spa_link) {
- if (i == unit)
- break;
- i++;
+ spa = spa_find_by_guid(dev->pool_guid);
+ if (!spa)
+ return (ENXIO);
+ rv = zfs_spa_init(spa);
+ if (rv != 0)
+ return (rv);
+ mount = malloc(sizeof(*mount));
+ rv = zfs_mount(spa, dev->root_guid, mount);
+ if (rv != 0) {
+ free(mount);
+ return (rv);
}
- if (!spa) {
- return (ENXIO);
+ if (mount->objset.os_type != DMU_OST_ZFS) {
+ printf("Unexpected object set type %ju\n",
+ (uintmax_t)mount->objset.os_type);
+ free(mount);
+ return (EIO);
}
-
- f->f_devdata = spa;
+ f->f_devdata = mount;
free(dev);
return (0);
}
@@ -506,6 +456,7 @@
zfs_dev_close(struct open_file *f)
{
+ free(f->f_devdata);
f->f_devdata = NULL;
return (0);
}
@@ -518,13 +469,102 @@
}
struct devsw zfs_dev = {
- .dv_name = "zfs",
- .dv_type = DEVT_ZFS,
+ .dv_name = "zfs",
+ .dv_type = DEVT_ZFS,
.dv_init = zfs_dev_init,
- .dv_strategy = zfs_dev_strategy,
- .dv_open = zfs_dev_open,
- .dv_close = zfs_dev_close,
+ .dv_strategy = zfs_dev_strategy,
+ .dv_open = zfs_dev_open,
+ .dv_close = zfs_dev_close,
.dv_ioctl = noioctl,
.dv_print = zfs_dev_print,
.dv_cleanup = NULL
};
+
+int
+zfs_parsedev(struct zfs_devdesc *dev, const char *devspec, const char **path)
+{
+ static char rootname[ZFS_MAXNAMELEN];
+ static char poolname[ZFS_MAXNAMELEN];
+ spa_t *spa;
+ const char *end;
+ const char *np;
+ const char *sep;
+ int rv;
+
+ np = devspec;
+ if (*np != ':')
+ return (EINVAL);
+ np++;
+ end = strchr(np, ':');
+ if (end == NULL)
+ return (EINVAL);
+ sep = strchr(np, '/');
+ if (sep == NULL || sep >= end)
+ sep = end;
+ memcpy(poolname, np, sep - np);
+ poolname[sep - np] = '\0';
+ if (sep < end) {
+ sep++;
+ memcpy(rootname, sep, end - sep);
+ rootname[end - sep] = '\0';
+ }
+ else
+ rootname[0] = '\0';
+
+ spa = spa_find_by_name(poolname);
+ if (!spa)
+ return (ENXIO);
+ rv = zfs_spa_init(spa);
+ if (rv != 0)
+ return (rv);
+ dev->pool_guid = spa->spa_guid;
+ if (rootname[0] != '\0') {
+ rv = zfs_lookup_dataset(spa, rootname, &dev->root_guid);
+ if (rv != 0)
+ return (rv);
+ } else
+ dev->root_guid = 0;
+ if (path != NULL)
+ *path = (*end == '\0') ? end : end + 1;
+ dev->d_dev = &zfs_dev;
+ dev->d_type = zfs_dev.dv_type;
+ return (0);
+}
+
+char *
+zfs_fmtdev(void *vdev)
+{
+ static char rootname[ZFS_MAXNAMELEN];
+ static char buf[2 * ZFS_MAXNAMELEN + 8];
+ struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev;
+ spa_t *spa;
+
+ buf[0] = '\0';
+ if (dev->d_type != DEVT_ZFS)
+ return (buf);
+
+ spa = spa_find_by_guid(dev->pool_guid);
+ if (spa == NULL) {
+ printf("ZFS: can't find pool by guid\n");
+ return (buf);
+ }
+ if (zfs_spa_init(spa) != 0) {
+ printf("ZFS: can't init pool\n");
+ return (buf);
+ }
+ if (dev->root_guid == 0 && zfs_get_root(spa, &dev->root_guid)) {
+ printf("ZFS: can't find root filesystem\n");
+ return (buf);
+ }
+ if (zfs_rlookup(spa, dev->root_guid, rootname)) {
+ printf("ZFS: can't find filesystem by guid\n");
+ return (buf);
+ }
+
+ if (rootname[0] == '\0')
+ sprintf(buf, "%s:%s:", dev->d_dev->dv_name, spa->spa_name);
+ else
+ sprintf(buf, "%s:%s/%s:", dev->d_dev->dv_name, spa->spa_name,
+ rootname);
+ return (buf);
+}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/boot/zfs/zfsimpl.c
--- a/head/sys/boot/zfs/zfsimpl.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/boot/zfs/zfsimpl.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,22 +25,37 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/boot/zfs/zfsimpl.c 228266 2011-12-04 21:29:56Z avg $");
+__FBSDID("$FreeBSD: head/sys/boot/zfs/zfsimpl.c 237001 2012-06-13 08:00:32Z mm $");
/*
* Stand-alone ZFS file reader.
*/
#include <sys/stat.h>
+#include <sys/stdint.h>
#include "zfsimpl.h"
#include "zfssubr.c"
+
+struct zfsmount {
+ const spa_t *spa;
+ objset_phys_t objset;
+ uint64_t rootobj;
+};
+
/*
* List of all vdevs, chained through v_alllink.
*/
static vdev_list_t zfs_vdevs;
+ /*
+ * List of ZFS features supported for read
+ */
+static const char *features_for_read[] = {
+ NULL
+};
+
/*
* List of all pools, chained through spa_link.
*/
@@ -55,7 +70,7 @@
#define TEMP_SIZE (1024 * 1024)
-static int zio_read(spa_t *spa, const blkptr_t *bp, void *buf);
+static int zio_read(const spa_t *spa, const blkptr_t *bp, void *buf);
static void
zfs_init(void)
@@ -190,6 +205,57 @@
return (EIO);
}
+static int
+nvlist_check_features_for_read(const unsigned char *nvlist)
+{
+ const unsigned char *p, *pair;
+ int junk;
+ int encoded_size, decoded_size;
+ int rc;
+
+ rc = 0;
+
+ p = nvlist;
+ xdr_int(&p, &junk);
+ xdr_int(&p, &junk);
+
+ pair = p;
+ xdr_int(&p, &encoded_size);
+ xdr_int(&p, &decoded_size);
+ while (encoded_size && decoded_size) {
+ int namelen, pairtype;
+ const char *pairname;
+ int i, found;
+
+ found = 0;
+
+ xdr_int(&p, &namelen);
+ pairname = (const char*) p;
+ p += roundup(namelen, 4);
+ xdr_int(&p, &pairtype);
+
+ for (i = 0; features_for_read[i] != NULL; i++) {
+ if (!memcmp(pairname, features_for_read[i], namelen)) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ printf("ZFS: unsupported feature: %s\n", pairname);
+ rc = EIO;
+ }
+
+ p = pair + encoded_size;
+
+ pair = p;
+ xdr_int(&p, &encoded_size);
+ xdr_int(&p, &decoded_size);
+ }
+
+ return (rc);
+}
+
/*
* Return the next nvlist in an nvlist array.
*/
@@ -283,7 +349,7 @@
case DATA_TYPE_UINT64: {
uint64_t val;
xdr_uint64_t(&p, &val);
- printf(" = 0x%llx\n", val);
+ printf(" = 0x%jx\n", (uintmax_t)val);
break;
}
@@ -343,7 +409,7 @@
psize = size;
}
- /*printf("ZFS: reading %d bytes at 0x%llx to %p\n", psize, offset, buf);*/
+ /*printf("ZFS: reading %d bytes at 0x%jx to %p\n", psize, (uintmax_t)offset, buf);*/
rc = vdev->v_phys_read(vdev, vdev->v_read_priv, offset, buf, psize);
if (rc)
return (rc);
@@ -626,8 +692,6 @@
return (0);
}
-#ifdef BOOT2
-
static spa_t *
spa_find_by_name(const char *name)
{
@@ -640,8 +704,6 @@
return (0);
}
-#endif
-
static spa_t *
spa_create(uint64_t guid)
{
@@ -784,6 +846,7 @@
uint64_t is_log;
const char *pool_name;
const unsigned char *vdevs;
+ const unsigned char *features;
int i, rc, is_newer;
char *upbuf;
const struct uberblock *up;
@@ -818,12 +881,19 @@
return (EIO);
}
- if (val > SPA_VERSION) {
+ if (!SPA_VERSION_IS_SUPPORTED(val)) {
printf("ZFS: unsupported ZFS version %u (should be %u)\n",
(unsigned) val, (unsigned) SPA_VERSION);
return (EIO);
}
+ /* Check ZFS features for read */
+ if (nvlist_find(nvlist,
+ ZPOOL_CONFIG_FEATURES_FOR_READ,
+ DATA_TYPE_NVLIST, 0, &features) == 0
+ && nvlist_check_features_for_read(features) != 0)
+ return (EIO);
+
if (nvlist_find(nvlist,
ZPOOL_CONFIG_POOL_STATE,
DATA_TYPE_UINT64, 0, &val)) {
@@ -977,7 +1047,7 @@
}
static int
-zio_read_gang(spa_t *spa, const blkptr_t *bp, void *buf)
+zio_read_gang(const spa_t *spa, const blkptr_t *bp, void *buf)
{
blkptr_t gbh_bp;
zio_gbh_phys_t zio_gb;
@@ -1014,7 +1084,7 @@
}
static int
-zio_read(spa_t *spa, const blkptr_t *bp, void *buf)
+zio_read(const spa_t *spa, const blkptr_t *bp, void *buf)
{
int cpfunc = BP_GET_COMPRESS(bp);
uint64_t align, size;
@@ -1074,7 +1144,7 @@
}
static int
-dnode_read(spa_t *spa, const dnode_phys_t *dnode, off_t offset, void *buf, size_t buflen)
+dnode_read(const spa_t *spa, const dnode_phys_t *dnode, off_t offset, void *buf, size_t buflen)
{
int ibshift = dnode->dn_indblkshift - SPA_BLKPTRSHIFT;
int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
@@ -1137,7 +1207,7 @@
* scratch buffer contains the directory contents.
*/
static int
-mzap_lookup(spa_t *spa, const dnode_phys_t *dnode, const char *name, uint64_t *value)
+mzap_lookup(const dnode_phys_t *dnode, const char *name, uint64_t *value)
{
const mzap_phys_t *mz;
const mzap_ent_phys_t *mze;
@@ -1218,7 +1288,7 @@
* buffer contains the directory header.
*/
static int
-fzap_lookup(spa_t *spa, const dnode_phys_t *dnode, const char *name, uint64_t *value)
+fzap_lookup(const spa_t *spa, const dnode_phys_t *dnode, const char *name, uint64_t *value)
{
int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
zap_phys_t zh = *(zap_phys_t *) zap_scratch;
@@ -1296,7 +1366,7 @@
* Lookup a name in a zap object and return its value as a uint64_t.
*/
static int
-zap_lookup(spa_t *spa, const dnode_phys_t *dnode, const char *name, uint64_t *value)
+zap_lookup(const spa_t *spa, const dnode_phys_t *dnode, const char *name, uint64_t *value)
{
int rc;
uint64_t zap_type;
@@ -1308,7 +1378,7 @@
zap_type = *(uint64_t *) zap_scratch;
if (zap_type == ZBT_MICRO)
- return mzap_lookup(spa, dnode, name, value);
+ return mzap_lookup(dnode, name, value);
else if (zap_type == ZBT_HEADER)
return fzap_lookup(spa, dnode, name, value);
printf("ZFS: invalid zap_type=%d\n", (int)zap_type);
@@ -1322,7 +1392,7 @@
* the directory contents.
*/
static int
-mzap_list(spa_t *spa, const dnode_phys_t *dnode)
+mzap_list(const dnode_phys_t *dnode)
{
const mzap_phys_t *mz;
const mzap_ent_phys_t *mze;
@@ -1340,7 +1410,7 @@
for (i = 0; i < chunks; i++) {
mze = &mz->mz_chunk[i];
if (mze->mze_name[0])
- //printf("%-32s 0x%llx\n", mze->mze_name, mze->mze_value);
+ //printf("%-32s 0x%jx\n", mze->mze_name, (uintmax_t)mze->mze_value);
printf("%s\n", mze->mze_name);
}
@@ -1352,7 +1422,7 @@
* the directory header.
*/
static int
-fzap_list(spa_t *spa, const dnode_phys_t *dnode)
+fzap_list(const spa_t *spa, const dnode_phys_t *dnode)
{
int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
zap_phys_t zh = *(zap_phys_t *) zap_scratch;
@@ -1391,7 +1461,7 @@
namelen = zc->l_entry.le_name_length;
if (namelen > sizeof(name))
namelen = sizeof(name);
-
+
/*
* Paste the name back together.
*/
@@ -1414,7 +1484,7 @@
*/
value = fzap_leaf_value(&zl, zc);
- printf("%s 0x%llx\n", name, value);
+ printf("%s 0x%jx\n", name, (uintmax_t)value);
}
}
@@ -1425,7 +1495,7 @@
* List a zap directory.
*/
static int
-zap_list(spa_t *spa, const dnode_phys_t *dnode)
+zap_list(const spa_t *spa, const dnode_phys_t *dnode)
{
uint64_t zap_type;
size_t size = dnode->dn_datablkszsec * 512;
@@ -1435,7 +1505,7 @@
zap_type = *(uint64_t *) zap_scratch;
if (zap_type == ZBT_MICRO)
- return mzap_list(spa, dnode);
+ return mzap_list(dnode);
else
return fzap_list(spa, dnode);
}
@@ -1443,7 +1513,7 @@
#endif
static int
-objset_get_dnode(spa_t *spa, const objset_phys_t *os, uint64_t objnum, dnode_phys_t *dnode)
+objset_get_dnode(const spa_t *spa, const objset_phys_t *os, uint64_t objnum, dnode_phys_t *dnode)
{
off_t offset;
@@ -1452,24 +1522,278 @@
dnode, sizeof(dnode_phys_t));
}
+static int
+mzap_rlookup(const spa_t *spa, const dnode_phys_t *dnode, char *name, uint64_t value)
+{
+ const mzap_phys_t *mz;
+ const mzap_ent_phys_t *mze;
+ size_t size;
+ int chunks, i;
+
+ /*
+ * Microzap objects use exactly one block. Read the whole
+ * thing.
+ */
+ size = dnode->dn_datablkszsec * 512;
+
+ mz = (const mzap_phys_t *) zap_scratch;
+ chunks = size / MZAP_ENT_LEN - 1;
+
+ for (i = 0; i < chunks; i++) {
+ mze = &mz->mz_chunk[i];
+ if (value == mze->mze_value) {
+ strcpy(name, mze->mze_name);
+ return (0);
+ }
+ }
+
+ return (ENOENT);
+}
+
+static void
+fzap_name_copy(const zap_leaf_t *zl, const zap_leaf_chunk_t *zc, char *name)
+{
+ size_t namelen;
+ const zap_leaf_chunk_t *nc;
+ char *p;
+
+ namelen = zc->l_entry.le_name_length;
+
+ nc = &ZAP_LEAF_CHUNK(zl, zc->l_entry.le_name_chunk);
+ p = name;
+ while (namelen > 0) {
+ size_t len;
+ len = namelen;
+ if (len > ZAP_LEAF_ARRAY_BYTES)
+ len = ZAP_LEAF_ARRAY_BYTES;
+ memcpy(p, nc->l_array.la_array, len);
+ p += len;
+ namelen -= len;
+ nc = &ZAP_LEAF_CHUNK(zl, nc->l_array.la_next);
+ }
+
+ *p = '\0';
+}
+
+static int
+fzap_rlookup(const spa_t *spa, const dnode_phys_t *dnode, char *name, uint64_t value)
+{
+ int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
+ zap_phys_t zh = *(zap_phys_t *) zap_scratch;
+ fat_zap_t z;
+ uint64_t *ptrtbl;
+ uint64_t hash;
+ int rc;
+
+ if (zh.zap_magic != ZAP_MAGIC)
+ return (EIO);
+
+ z.zap_block_shift = ilog2(bsize);
+ z.zap_phys = (zap_phys_t *) zap_scratch;
+
+ /*
+ * Figure out where the pointer table is and read it in if necessary.
+ */
+ if (zh.zap_ptrtbl.zt_blk) {
+ rc = dnode_read(spa, dnode, zh.zap_ptrtbl.zt_blk * bsize,
+ zap_scratch, bsize);
+ if (rc)
+ return (rc);
+ ptrtbl = (uint64_t *) zap_scratch;
+ } else {
+ ptrtbl = &ZAP_EMBEDDED_PTRTBL_ENT(&z, 0);
+ }
+
+ hash = zap_hash(zh.zap_salt, name);
+
+ zap_leaf_t zl;
+ zl.l_bs = z.zap_block_shift;
+
+ off_t off = ptrtbl[hash >> (64 - zh.zap_ptrtbl.zt_shift)] << zl.l_bs;
+ zap_leaf_chunk_t *zc;
+
+ rc = dnode_read(spa, dnode, off, zap_scratch, bsize);
+ if (rc)
+ return (rc);
+
+ zl.l_phys = (zap_leaf_phys_t *) zap_scratch;
+
+ /*
+ * Make sure this chunk matches our hash.
+ */
+ if (zl.l_phys->l_hdr.lh_prefix_len > 0
+ && zl.l_phys->l_hdr.lh_prefix
+ != hash >> (64 - zl.l_phys->l_hdr.lh_prefix_len))
+ return (ENOENT);
+
+ /*
+ * Hash within the chunk to find our entry.
+ */
+ int shift = (64 - ZAP_LEAF_HASH_SHIFT(&zl) - zl.l_phys->l_hdr.lh_prefix_len);
+ int h = (hash >> shift) & ((1 << ZAP_LEAF_HASH_SHIFT(&zl)) - 1);
+ h = zl.l_phys->l_hash[h];
+ if (h == 0xffff)
+ return (ENOENT);
+ zc = &ZAP_LEAF_CHUNK(&zl, h);
+ while (zc->l_entry.le_hash != hash) {
+ if (zc->l_entry.le_next == 0xffff) {
+ zc = 0;
+ break;
+ }
+ zc = &ZAP_LEAF_CHUNK(&zl, zc->l_entry.le_next);
+ }
+ if (fzap_leaf_value(&zl, zc) == value) {
+ fzap_name_copy(&zl, zc, name);
+ return (0);
+ }
+
+ return (ENOENT);
+}
+
+static int
+zap_rlookup(const spa_t *spa, const dnode_phys_t *dnode, char *name, uint64_t value)
+{
+ int rc;
+ uint64_t zap_type;
+ size_t size = dnode->dn_datablkszsec * 512;
+
+ rc = dnode_read(spa, dnode, 0, zap_scratch, size);
+ if (rc)
+ return (rc);
+
+ zap_type = *(uint64_t *) zap_scratch;
+ if (zap_type == ZBT_MICRO)
+ return mzap_rlookup(spa, dnode, name, value);
+ else
+ return fzap_rlookup(spa, dnode, name, value);
+}
+
+static int
+zfs_rlookup(const spa_t *spa, uint64_t objnum, char *result)
+{
+ char name[256];
+ char component[256];
+ uint64_t dir_obj, parent_obj, child_dir_zapobj;
+ dnode_phys_t child_dir_zap, dataset, dir, parent;
+ dsl_dir_phys_t *dd;
+ dsl_dataset_phys_t *ds;
+ char *p;
+ int len;
+
+ p = &name[sizeof(name) - 1];
+ *p = '\0';
+
+ if (objset_get_dnode(spa, &spa->spa_mos, objnum, &dataset)) {
+ printf("ZFS: can't find dataset %ju\n", (uintmax_t)objnum);
+ return (EIO);
+ }
+ ds = (dsl_dataset_phys_t *)&dataset.dn_bonus;
+ dir_obj = ds->ds_dir_obj;
+
+ for (;;) {
+ if (objset_get_dnode(spa, &spa->spa_mos, dir_obj, &dir) != 0)
+ return (EIO);
+ dd = (dsl_dir_phys_t *)&dir.dn_bonus;
+
+ /* Actual loop condition. */
+ parent_obj = dd->dd_parent_obj;
+ if (parent_obj == 0)
+ break;
+
+ if (objset_get_dnode(spa, &spa->spa_mos, parent_obj, &parent) != 0)
+ return (EIO);
+ dd = (dsl_dir_phys_t *)&parent.dn_bonus;
+ child_dir_zapobj = dd->dd_child_dir_zapobj;
+ if (objset_get_dnode(spa, &spa->spa_mos, child_dir_zapobj, &child_dir_zap) != 0)
+ return (EIO);
+ if (zap_rlookup(spa, &child_dir_zap, component, dir_obj) != 0)
+ return (EIO);
+
+ len = strlen(component);
+ p -= len;
+ memcpy(p, component, len);
+ --p;
+ *p = '/';
+
+ /* Actual loop iteration. */
+ dir_obj = parent_obj;
+ }
+
+ if (*p != '\0')
+ ++p;
+ strcpy(result, p);
+
+ return (0);
+}
+
+static int
+zfs_lookup_dataset(const spa_t *spa, const char *name, uint64_t *objnum)
+{
+ char element[256];
+ uint64_t dir_obj, child_dir_zapobj;
+ dnode_phys_t child_dir_zap, dir;
+ dsl_dir_phys_t *dd;
+ const char *p, *q;
+
+ if (objset_get_dnode(spa, &spa->spa_mos, DMU_POOL_DIRECTORY_OBJECT, &dir))
+ return (EIO);
+ if (zap_lookup(spa, &dir, DMU_POOL_ROOT_DATASET, &dir_obj))
+ return (EIO);
+
+ p = name;
+ for (;;) {
+ if (objset_get_dnode(spa, &spa->spa_mos, dir_obj, &dir))
+ return (EIO);
+ dd = (dsl_dir_phys_t *)&dir.dn_bonus;
+
+ while (*p == '/')
+ p++;
+ /* Actual loop condition #1. */
+ if (*p == '\0')
+ break;
+
+ q = strchr(p, '/');
+ if (q) {
+ memcpy(element, p, q - p);
+ element[q - p] = '\0';
+ p = q + 1;
+ } else {
+ strcpy(element, p);
+ p += strlen(p);
+ }
+
+ child_dir_zapobj = dd->dd_child_dir_zapobj;
+ if (objset_get_dnode(spa, &spa->spa_mos, child_dir_zapobj, &child_dir_zap) != 0)
+ return (EIO);
+
+ /* Actual loop condition #2. */
+ if (zap_lookup(spa, &child_dir_zap, element, &dir_obj) != 0)
+ return (ENOENT);
+ }
+
+ *objnum = dd->dd_head_dataset_obj;
+ return (0);
+}
+
/*
* Find the object set given the object number of its dataset object
* and return its details in *objset
*/
static int
-zfs_mount_dataset(spa_t *spa, uint64_t objnum, objset_phys_t *objset)
+zfs_mount_dataset(const spa_t *spa, uint64_t objnum, objset_phys_t *objset)
{
dnode_phys_t dataset;
dsl_dataset_phys_t *ds;
if (objset_get_dnode(spa, &spa->spa_mos, objnum, &dataset)) {
- printf("ZFS: can't find dataset %llu\n", objnum);
+ printf("ZFS: can't find dataset %ju\n", (uintmax_t)objnum);
return (EIO);
}
ds = (dsl_dataset_phys_t *) &dataset.dn_bonus;
if (zio_read(spa, &ds->ds_bp, objset)) {
- printf("ZFS: can't read object set for dataset %llu\n", objnum);
+ printf("ZFS: can't read object set for dataset %ju\n",
+ (uintmax_t)objnum);
return (EIO);
}
@@ -1481,11 +1805,13 @@
* dataset if there is none and return its details in *objset
*/
static int
-zfs_mount_root(spa_t *spa, objset_phys_t *objset)
+zfs_get_root(const spa_t *spa, uint64_t *objid)
{
dnode_phys_t dir, propdir;
uint64_t props, bootfs, root;
+ *objid = 0;
+
/*
* Start with the MOS directory object.
*/
@@ -1501,8 +1827,10 @@
&& objset_get_dnode(spa, &spa->spa_mos, props, &propdir) == 0
&& zap_lookup(spa, &propdir, "bootfs", &bootfs) == 0
&& bootfs != 0)
- return zfs_mount_dataset(spa, bootfs, objset);
-
+ {
+ *objid = bootfs;
+ return (0);
+ }
/*
* Lookup the root dataset directory
*/
@@ -1517,34 +1845,50 @@
* to find the dataset object and from that the object set itself.
*/
dsl_dir_phys_t *dd = (dsl_dir_phys_t *) &dir.dn_bonus;
- return zfs_mount_dataset(spa, dd->dd_head_dataset_obj, objset);
+ *objid = dd->dd_head_dataset_obj;
+ return (0);
}
static int
-zfs_mount_pool(spa_t *spa)
+zfs_mount(const spa_t *spa, uint64_t rootobj, struct zfsmount *mount)
{
+ mount->spa = spa;
+
/*
- * Find the MOS and work our way in from there.
+ * Find the root object set if not explicitly provided
*/
- if (zio_read(spa, &spa->spa_uberblock.ub_rootbp, &spa->spa_mos)) {
- printf("ZFS: can't read MOS\n");
+ if (rootobj == 0 && zfs_get_root(spa, &rootobj)) {
+ printf("ZFS: can't find root filesystem\n");
return (EIO);
}
- /*
- * Find the root object set
- */
- if (zfs_mount_root(spa, &spa->spa_root_objset)) {
- printf("Can't find root filesystem - giving up\n");
+ if (zfs_mount_dataset(spa, rootobj, &mount->objset)) {
+ printf("ZFS: can't open root filesystem\n");
return (EIO);
}
+ mount->rootobj = rootobj;
+
return (0);
}
static int
-zfs_dnode_stat(spa_t *spa, dnode_phys_t *dn, struct stat *sb)
+zfs_spa_init(spa_t *spa)
+{
+
+ if (spa->spa_inited)
+ return (0);
+ if (zio_read(spa, &spa->spa_uberblock.ub_rootbp, &spa->spa_mos)) {
+ printf("ZFS: can't read MOS of pool %s\n", spa->spa_name);
+ return (EIO);
+ }
+ spa->spa_inited = 1;
+ return (0);
+}
+
+static int
+zfs_dnode_stat(const spa_t *spa, dnode_phys_t *dn, struct stat *sb)
{
if (dn->dn_bonustype != DMU_OT_SA) {
@@ -1599,10 +1943,11 @@
* Lookup a file and return its dnode.
*/
static int
-zfs_lookup(spa_t *spa, const char *upath, dnode_phys_t *dnode)
+zfs_lookup(const struct zfsmount *mount, const char *upath, dnode_phys_t *dnode)
{
int rc;
uint64_t objnum, rootnum, parentnum;
+ const spa_t *spa;
dnode_phys_t dn;
const char *p, *q;
char element[256];
@@ -1610,16 +1955,17 @@
int symlinks_followed = 0;
struct stat sb;
- if (spa->spa_root_objset.os_type != DMU_OST_ZFS) {
- printf("ZFS: unexpected object set type %llu\n",
- spa->spa_root_objset.os_type);
+ spa = mount->spa;
+ if (mount->objset.os_type != DMU_OST_ZFS) {
+ printf("ZFS: unexpected object set type %ju\n",
+ (uintmax_t)mount->objset.os_type);
return (EIO);
}
/*
* Get the root directory dnode.
*/
- rc = objset_get_dnode(spa, &spa->spa_root_objset, MASTER_NODE_OBJ, &dn);
+ rc = objset_get_dnode(spa, &mount->objset, MASTER_NODE_OBJ, &dn);
if (rc)
return (rc);
@@ -1627,7 +1973,7 @@
if (rc)
return (rc);
- rc = objset_get_dnode(spa, &spa->spa_root_objset, rootnum, &dn);
+ rc = objset_get_dnode(spa, &mount->objset, rootnum, &dn);
if (rc)
return (rc);
@@ -1660,7 +2006,7 @@
return (rc);
objnum = ZFS_DIRENT_OBJ(objnum);
- rc = objset_get_dnode(spa, &spa->spa_root_objset, objnum, &dn);
+ rc = objset_get_dnode(spa, &mount->objset, objnum, &dn);
if (rc)
return (rc);
@@ -1702,7 +2048,7 @@
objnum = rootnum;
else
objnum = parentnum;
- objset_get_dnode(spa, &spa->spa_root_objset, objnum, &dn);
+ objset_get_dnode(spa, &mount->objset, objnum, &dn);
}
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/ata/ata_all.c
--- a/head/sys/cam/ata/ata_all.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/ata/ata_all.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/ata/ata_all.c 223019 2011-06-12 18:52:39Z mav $");
+__FBSDID("$FreeBSD: head/sys/cam/ata/ata_all.c 238393 2012-07-12 10:09:34Z brueffer $");
#include <sys/param.h>
@@ -108,6 +108,16 @@
case 0x51: return ("CONFIGURE_STREAM");
case 0x60: return ("READ_FPDMA_QUEUED");
case 0x61: return ("WRITE_FPDMA_QUEUED");
+ case 0x67:
+ if (cmd->features == 0xec)
+ return ("SEP_ATTN IDENTIFY");
+ switch (cmd->lba_low) {
+ case 0x00: return ("SEP_ATTN READ BUFFER");
+ case 0x02: return ("SEP_ATTN RECEIVE DIAGNOSTIC RESULTS");
+ case 0x80: return ("SEP_ATTN WRITE BUFFER");
+ case 0x82: return ("SEP_ATTN SEND DIAGNOSTIC");
+ }
+ return ("SEP_ATTN");
case 0x70: return ("SEEK");
case 0x87: return ("CFA_TRANSLATE_SECTOR");
case 0x90: return ("EXECUTE_DEVICE_DIAGNOSTIC");
@@ -161,8 +171,8 @@
case 0xf2: return ("SECURITY_UNLOCK");
case 0xf3: return ("SECURITY_ERASE_PREPARE");
case 0xf4: return ("SECURITY_ERASE_UNIT");
- case 0xf5: return ("SECURITY_FREE_LOCK");
- case 0xf6: return ("SECURITY DISABLE PASSWORD");
+ case 0xf5: return ("SECURITY_FREEZE_LOCK");
+ case 0xf6: return ("SECURITY_DISABLE_PASSWORD");
case 0xf8: return ("READ_NATIVE_MAX_ADDRESS");
case 0xf9: return ("SET_MAX_ADDRESS");
}
@@ -286,6 +296,21 @@
printf(" device\n");
}
+void
+semb_print_ident(struct sep_identify_data *ident_data)
+{
+ char vendor[9], product[17], revision[5], fw[5], in[7], ins[5];
+
+ cam_strvis(vendor, ident_data->vendor_id, 8, sizeof(vendor));
+ cam_strvis(product, ident_data->product_id, 16, sizeof(product));
+ cam_strvis(revision, ident_data->product_rev, 4, sizeof(revision));
+ cam_strvis(fw, ident_data->firmware_rev, 4, sizeof(fw));
+ cam_strvis(in, ident_data->interface_id, 6, sizeof(in));
+ cam_strvis(ins, ident_data->interface_rev, 4, sizeof(ins));
+ printf("<%s %s %s %s> SEMB %s %s device\n",
+ vendor, product, revision, fw, in, ins);
+}
+
uint32_t
ata_logical_sector_size(struct ata_params *ident_data)
{
@@ -334,7 +359,7 @@
ataio->cmd.lba_low = lba;
ataio->cmd.lba_mid = lba >> 8;
ataio->cmd.lba_high = lba >> 16;
- ataio->cmd.device = 0x40 | ((lba >> 24) & 0x0f);
+ ataio->cmd.device = ATA_DEV_LBA | ((lba >> 24) & 0x0f);
ataio->cmd.sector_count = sector_count;
}
@@ -359,7 +384,7 @@
ataio->cmd.lba_low = lba;
ataio->cmd.lba_mid = lba >> 8;
ataio->cmd.lba_high = lba >> 16;
- ataio->cmd.device = 0x40;
+ ataio->cmd.device = ATA_DEV_LBA;
ataio->cmd.lba_low_exp = lba >> 24;
ataio->cmd.lba_mid_exp = lba >> 32;
ataio->cmd.lba_high_exp = lba >> 40;
@@ -379,7 +404,7 @@
ataio->cmd.lba_low = lba;
ataio->cmd.lba_mid = lba >> 8;
ataio->cmd.lba_high = lba >> 16;
- ataio->cmd.device = 0x40;
+ ataio->cmd.device = ATA_DEV_LBA;
ataio->cmd.lba_low_exp = lba >> 24;
ataio->cmd.lba_mid_exp = lba >> 32;
ataio->cmd.lba_high_exp = lba >> 40;
@@ -695,3 +720,86 @@
}
return (-1);
}
+
+void
+semb_receive_diagnostic_results(struct ccb_ataio *ataio,
+ u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*),
+ uint8_t tag_action, int pcv, uint8_t page_code,
+ uint8_t *data_ptr, uint16_t length, uint32_t timeout)
+{
+
+ length = min(length, 1020);
+ length = (length + 3) & ~3;
+ cam_fill_ataio(ataio,
+ retries,
+ cbfcnp,
+ /*flags*/CAM_DIR_IN,
+ tag_action,
+ data_ptr,
+ length,
+ timeout);
+ ata_28bit_cmd(ataio, ATA_SEP_ATTN,
+ pcv ? page_code : 0, 0x02, length / 4);
+}
+
+void
+semb_send_diagnostic(struct ccb_ataio *ataio,
+ u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *),
+ uint8_t tag_action, uint8_t *data_ptr, uint16_t length, uint32_t timeout)
+{
+
+ length = min(length, 1020);
+ length = (length + 3) & ~3;
+ cam_fill_ataio(ataio,
+ retries,
+ cbfcnp,
+ /*flags*/length ? CAM_DIR_OUT : CAM_DIR_NONE,
+ tag_action,
+ data_ptr,
+ length,
+ timeout);
+ ata_28bit_cmd(ataio, ATA_SEP_ATTN,
+ length > 0 ? data_ptr[0] : 0, 0x82, length / 4);
+}
+
+void
+semb_read_buffer(struct ccb_ataio *ataio,
+ u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*),
+ uint8_t tag_action, uint8_t page_code,
+ uint8_t *data_ptr, uint16_t length, uint32_t timeout)
+{
+
+ length = min(length, 1020);
+ length = (length + 3) & ~3;
+ cam_fill_ataio(ataio,
+ retries,
+ cbfcnp,
+ /*flags*/CAM_DIR_IN,
+ tag_action,
+ data_ptr,
+ length,
+ timeout);
+ ata_28bit_cmd(ataio, ATA_SEP_ATTN,
+ page_code, 0x00, length / 4);
+}
+
+void
+semb_write_buffer(struct ccb_ataio *ataio,
+ u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *),
+ uint8_t tag_action, uint8_t *data_ptr, uint16_t length, uint32_t timeout)
+{
+
+ length = min(length, 1020);
+ length = (length + 3) & ~3;
+ cam_fill_ataio(ataio,
+ retries,
+ cbfcnp,
+ /*flags*/length ? CAM_DIR_OUT : CAM_DIR_NONE,
+ tag_action,
+ data_ptr,
+ length,
+ timeout);
+ ata_28bit_cmd(ataio, ATA_SEP_ATTN,
+ length > 0 ? data_ptr[0] : 0, 0x80, length / 4);
+}
+
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/ata/ata_all.h
--- a/head/sys/cam/ata/ata_all.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/ata/ata_all.h Wed Jul 25 16:45:04 2012 +0300
@@ -23,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: head/sys/cam/ata/ata_all.h 220886 2011-04-20 13:27:50Z mav $
+ * $FreeBSD: head/sys/cam/ata/ata_all.h 235897 2012-05-24 11:07:39Z mav $
*/
#ifndef CAM_ATA_ALL_H
@@ -83,6 +83,20 @@
u_int8_t sector_count_exp;
};
+struct sep_identify_data {
+ uint8_t length; /* Enclosure descriptor length */
+ uint8_t subenc_id; /* Sub-enclosure identifier */
+ uint8_t logical_id[8]; /* Enclosure logical identifier (WWN) */
+ uint8_t vendor_id[8]; /* Vendor identification string */
+ uint8_t product_id[16]; /* Product identification string */
+ uint8_t product_rev[4]; /* Product revision string */
+ uint8_t channel_id; /* Channel identifier */
+ uint8_t firmware_rev[4];/* Firmware revision */
+ uint8_t interface_id[6];/* Interface spec ("S-E-S "/"SAF-TE")*/
+ uint8_t interface_rev[4];/* Interface spec revision */
+ uint8_t vend_spec[11]; /* Vendor specific information */
+};
+
int ata_version(int ver);
char * ata_op_string(struct ata_cmd *cmd);
@@ -126,4 +140,26 @@
int ata_identify_match(caddr_t identbuffer, caddr_t table_entry);
int ata_static_identify_match(caddr_t identbuffer, caddr_t table_entry);
+void semb_print_ident(struct sep_identify_data *ident_data);
+
+void semb_receive_diagnostic_results(struct ccb_ataio *ataio,
+ u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*),
+ uint8_t tag_action, int pcv, uint8_t page_code,
+ uint8_t *data_ptr, uint16_t allocation_length, uint32_t timeout);
+
+void semb_send_diagnostic(struct ccb_ataio *ataio,
+ u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *),
+ uint8_t tag_action, uint8_t *data_ptr, uint16_t param_list_length,
+ uint32_t timeout);
+
+void semb_read_buffer(struct ccb_ataio *ataio,
+ u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*),
+ uint8_t tag_action, uint8_t page_code,
+ uint8_t *data_ptr, uint16_t allocation_length, uint32_t timeout);
+
+void semb_write_buffer(struct ccb_ataio *ataio,
+ u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *),
+ uint8_t tag_action, uint8_t *data_ptr, uint16_t param_list_length,
+ uint32_t timeout);
+
#endif
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/ata/ata_da.c
--- a/head/sys/cam/ata/ata_da.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/ata/ata_da.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/ata/ata_da.c 234414 2012-04-18 08:55:26Z mav $");
+__FBSDID("$FreeBSD: head/sys/cam/ata/ata_da.c 238382 2012-07-11 23:22:09Z brueffer $");
#include "opt_ada.h"
#include "opt_ata.h"
@@ -368,9 +368,9 @@
SYSCTL_INT(_kern_cam_ada, OID_AUTO, default_timeout, CTLFLAG_RW,
&ada_default_timeout, 0, "Normal I/O timeout (in seconds)");
TUNABLE_INT("kern.cam.ada.default_timeout", &ada_default_timeout);
-SYSCTL_INT(_kern_cam_ada, OID_AUTO, ada_send_ordered, CTLFLAG_RW,
+SYSCTL_INT(_kern_cam_ada, OID_AUTO, send_ordered, CTLFLAG_RW,
&ada_send_ordered, 0, "Send Ordered Tags");
-TUNABLE_INT("kern.cam.ada.ada_send_ordered", &ada_send_ordered);
+TUNABLE_INT("kern.cam.ada.send_ordered", &ada_send_ordered);
SYSCTL_INT(_kern_cam_ada, OID_AUTO, spindown_shutdown, CTLFLAG_RW,
&ada_spindown_shutdown, 0, "Spin down upon shutdown");
TUNABLE_INT("kern.cam.ada.spindown_shutdown", &ada_spindown_shutdown);
@@ -436,9 +436,8 @@
softc = (struct ada_softc *)periph->softc;
softc->flags |= ADA_FLAG_OPEN;
- CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
- ("adaopen: disk=%s%d (unit %d)\n", dp->d_name, dp->d_unit,
- periph->unit_number));
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
+ ("adaopen\n"));
if ((softc->flags & ADA_FLAG_PACK_INVALID) != 0) {
/* Invalidate our pack information. */
@@ -469,6 +468,10 @@
}
softc = (struct ada_softc *)periph->softc;
+
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
+ ("adaclose\n"));
+
/* We only sync the cache if the drive is capable of it. */
if ((softc->flags & ADA_FLAG_CAN_FLUSHCACHE) != 0 &&
(softc->flags & ADA_FLAG_PACK_INVALID) == 0) {
@@ -487,7 +490,7 @@
ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE48, 0, 0, 0);
else
ata_28bit_cmd(&ccb->ataio, ATA_FLUSHCACHE, 0, 0, 0);
- cam_periph_runccb(ccb, /*error_routine*/NULL, /*cam_flags*/0,
+ cam_periph_runccb(ccb, adaerror, /*cam_flags*/0,
/*sense_flags*/0, softc->disk->d_devstat);
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
@@ -542,6 +545,8 @@
cam_periph_lock(periph);
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("adastrategy(%p)\n", bp));
+
/*
* If the device has been made invalid, error out
*/
@@ -579,6 +584,7 @@
struct disk *dp;
uint64_t lba;
uint16_t count;
+ int error = 0;
dp = arg;
periph = dp->d_drv1;
@@ -617,13 +623,16 @@
}
xpt_polled_action(&ccb);
- if ((ccb.ataio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
+ error = cam_periph_error(&ccb,
+ 0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
+ if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
+ cam_release_devq(ccb.ccb_h.path, /*relsim_flags*/0,
+ /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
+ if (error != 0)
printf("Aborting dump due to I/O error.\n");
- cam_periph_unlock(periph);
- return(EIO);
- }
+
cam_periph_unlock(periph);
- return(0);
+ return (error);
}
if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) {
@@ -631,7 +640,7 @@
ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
cam_fill_ataio(&ccb.ataio,
- 1,
+ 0,
adadone,
CAM_DIR_NONE,
0,
@@ -645,18 +654,16 @@
ata_28bit_cmd(&ccb.ataio, ATA_FLUSHCACHE, 0, 0, 0);
xpt_polled_action(&ccb);
- if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
+ error = cam_periph_error(&ccb,
+ 0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
+ if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
+ cam_release_devq(ccb.ccb_h.path, /*relsim_flags*/0,
+ /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
+ if (error != 0)
xpt_print(periph->path, "Synchronize cache failed\n");
-
- if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
- cam_release_devq(ccb.ccb_h.path,
- /*relsim_flags*/0,
- /*reduction*/0,
- /*timeout*/0,
- /*getcount_only*/0);
}
cam_periph_unlock(periph);
- return (0);
+ return (error);
}
static void
@@ -742,6 +749,7 @@
adaasync(void *callback_arg, u_int32_t code,
struct cam_path *path, void *arg)
{
+ struct ccb_getdev cgd;
struct cam_periph *periph;
struct ada_softc *softc;
@@ -776,11 +784,49 @@
"due to status 0x%x\n", status);
break;
}
+ case AC_GETDEV_CHANGED:
+ {
+ softc = (struct ada_softc *)periph->softc;
+ xpt_setup_ccb(&cgd.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
+ cgd.ccb_h.func_code = XPT_GDEV_TYPE;
+ xpt_action((union ccb *)&cgd);
+
+ if ((cgd.ident_data.capabilities1 & ATA_SUPPORT_DMA) &&
+ (cgd.inq_flags & SID_DMA))
+ softc->flags |= ADA_FLAG_CAN_DMA;
+ else
+ softc->flags &= ~ADA_FLAG_CAN_DMA;
+ if ((cgd.ident_data.satacapabilities & ATA_SUPPORT_NCQ) &&
+ (cgd.inq_flags & SID_DMA) && (cgd.inq_flags & SID_CmdQue))
+ softc->flags |= ADA_FLAG_CAN_NCQ;
+ else
+ softc->flags &= ~ADA_FLAG_CAN_NCQ;
+ if ((cgd.ident_data.support_dsm & ATA_SUPPORT_DSM_TRIM) &&
+ (cgd.inq_flags & SID_DMA))
+ softc->flags |= ADA_FLAG_CAN_TRIM;
+ else
+ softc->flags &= ~ADA_FLAG_CAN_TRIM;
+
+ cam_periph_async(periph, code, path, arg);
+ break;
+ }
+ case AC_ADVINFO_CHANGED:
+ {
+ uintptr_t buftype;
+
+ buftype = (uintptr_t)arg;
+ if (buftype == CDAI_TYPE_PHYS_PATH) {
+ struct ada_softc *softc;
+
+ softc = periph->softc;
+ disk_attr_changed(softc->disk, "GEOM::physpath",
+ M_NOWAIT);
+ }
+ break;
+ }
case AC_SENT_BDR:
case AC_BUS_RESET:
{
- struct ccb_getdev cgd;
-
softc = (struct ada_softc *)periph->softc;
cam_periph_async(periph, code, path, arg);
if (softc->state != ADA_STATE_NORMAL)
@@ -919,7 +965,7 @@
bioq_init(&softc->bio_queue);
bioq_init(&softc->trim_queue);
- if (cgd->ident_data.capabilities1 & ATA_SUPPORT_DMA &&
+ if ((cgd->ident_data.capabilities1 & ATA_SUPPORT_DMA) &&
(cgd->inq_flags & SID_DMA))
softc->flags |= ADA_FLAG_CAN_DMA;
if (cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48)
@@ -928,10 +974,11 @@
softc->flags |= ADA_FLAG_CAN_FLUSHCACHE;
if (cgd->ident_data.support.command1 & ATA_SUPPORT_POWERMGT)
softc->flags |= ADA_FLAG_CAN_POWERMGT;
- if (cgd->ident_data.satacapabilities & ATA_SUPPORT_NCQ &&
+ if ((cgd->ident_data.satacapabilities & ATA_SUPPORT_NCQ) &&
(cgd->inq_flags & SID_DMA) && (cgd->inq_flags & SID_CmdQue))
softc->flags |= ADA_FLAG_CAN_NCQ;
- if (cgd->ident_data.support_dsm & ATA_SUPPORT_DSM_TRIM) {
+ if ((cgd->ident_data.support_dsm & ATA_SUPPORT_DSM_TRIM) &&
+ (cgd->inq_flags & SID_DMA)) {
softc->flags |= ADA_FLAG_CAN_TRIM;
softc->trim_max_ranges = TRIM_MAX_RANGES;
if (cgd->ident_data.max_dsm_blocks != 0) {
@@ -1088,8 +1135,9 @@
* them and the only alternative would be to
* not attach the device on failure.
*/
- xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE,
- adaasync, periph, periph->path);
+ xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE |
+ AC_GETDEV_CHANGED | AC_ADVINFO_CHANGED,
+ adaasync, periph, periph->path);
/*
* Schedule a periodic event to occasionally send an
@@ -1126,6 +1174,8 @@
struct ada_softc *softc = (struct ada_softc *)periph->softc;
struct ccb_ataio *ataio = &start_ccb->ataio;
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("adastart\n"));
+
switch (softc->state) {
case ADA_STATE_NORMAL:
{
@@ -1134,7 +1184,7 @@
/* Execute immediate CCB if waiting. */
if (periph->immediate_priority <= periph->pinfo.priority) {
- CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
+ CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE,
("queuing for immediate ccb\n"));
start_ccb->ccb_h.ccb_state = ADA_CCB_WAITING;
SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
@@ -1426,6 +1476,9 @@
softc = (struct ada_softc *)periph->softc;
ataio = &done_ccb->ataio;
+
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("adadone\n"));
+
switch (ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK) {
case ADA_CCB_BUFFER_IO:
case ADA_CCB_TRIM:
@@ -1665,6 +1718,7 @@
{
struct cam_periph *periph;
struct ada_softc *softc;
+ int error;
TAILQ_FOREACH(periph, &adadriver.units, unit_links) {
union ccb ccb;
@@ -1688,7 +1742,7 @@
ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
cam_fill_ataio(&ccb.ataio,
- 1,
+ 0,
adadone,
CAM_DIR_NONE,
0,
@@ -1702,15 +1756,13 @@
ata_28bit_cmd(&ccb.ataio, ATA_FLUSHCACHE, 0, 0, 0);
xpt_polled_action(&ccb);
- if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
+ error = cam_periph_error(&ccb,
+ 0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
+ if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
+ cam_release_devq(ccb.ccb_h.path, /*relsim_flags*/0,
+ /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
+ if (error != 0)
xpt_print(periph->path, "Synchronize cache failed\n");
-
- if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
- cam_release_devq(ccb.ccb_h.path,
- /*relsim_flags*/0,
- /*reduction*/0,
- /*timeout*/0,
- /*getcount_only*/0);
cam_periph_unlock(periph);
}
}
@@ -1720,6 +1772,7 @@
{
struct cam_periph *periph;
struct ada_softc *softc;
+ int error;
TAILQ_FOREACH(periph, &adadriver.units, unit_links) {
union ccb ccb;
@@ -1744,7 +1797,7 @@
ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
cam_fill_ataio(&ccb.ataio,
- 1,
+ 0,
adadone,
CAM_DIR_NONE | flags,
0,
@@ -1755,15 +1808,13 @@
ata_28bit_cmd(&ccb.ataio, cmd, 0, 0, 0);
xpt_polled_action(&ccb);
- if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
+ error = cam_periph_error(&ccb,
+ 0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
+ if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
+ cam_release_devq(ccb.ccb_h.path, /*relsim_flags*/0,
+ /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
+ if (error != 0)
xpt_print(periph->path, "Spin-down disk failed\n");
-
- if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
- cam_release_devq(ccb.ccb_h.path,
- /*relsim_flags*/0,
- /*reduction*/0,
- /*timeout*/0,
- /*getcount_only*/0);
cam_periph_unlock(periph);
}
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/ata/ata_pmp.c
--- a/head/sys/cam/ata/ata_pmp.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/ata/ata_pmp.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/ata/ata_pmp.c 227309 2011-11-07 15:43:11Z ed $");
+__FBSDID("$FreeBSD: head/sys/cam/ata/ata_pmp.c 236602 2012-06-05 09:45:42Z mav $");
#include <sys/param.h>
@@ -126,8 +126,13 @@
#define PMP_DEFAULT_RETRY 1
#endif
+#ifndef PMP_DEFAULT_HIDE_SPECIAL
+#define PMP_DEFAULT_HIDE_SPECIAL 1
+#endif
+
static int pmp_retry_count = PMP_DEFAULT_RETRY;
static int pmp_default_timeout = PMP_DEFAULT_TIMEOUT;
+static int pmp_hide_special = PMP_DEFAULT_HIDE_SPECIAL;
static SYSCTL_NODE(_kern_cam, OID_AUTO, pmp, CTLFLAG_RD, 0,
"CAM Direct Access Disk driver");
@@ -137,6 +142,9 @@
SYSCTL_INT(_kern_cam_pmp, OID_AUTO, default_timeout, CTLFLAG_RW,
&pmp_default_timeout, 0, "Normal I/O timeout (in seconds)");
TUNABLE_INT("kern.cam.pmp.default_timeout", &pmp_default_timeout);
+SYSCTL_INT(_kern_cam_pmp, OID_AUTO, hide_special, CTLFLAG_RW,
+ &pmp_hide_special, 0, "Hide extra ports");
+TUNABLE_INT("kern.cam.pmp.hide_special", &pmp_hide_special);
static struct periph_driver pmpdriver =
{
@@ -421,7 +429,9 @@
softc = (struct pmp_softc *)periph->softc;
ataio = &start_ccb->ataio;
-
+
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("pmpstart\n"));
+
if (softc->restart) {
softc->restart = 0;
softc->state = min(softc->state, PMP_STATE_PRECONFIG);
@@ -552,7 +562,7 @@
softc = (struct pmp_softc *)periph->softc;
ataio = &done_ccb->ataio;
- CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("pmpdone\n"));
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("pmpdone\n"));
priority = done_ccb->ccb_h.pinfo.priority;
@@ -583,23 +593,33 @@
(ataio->res.lba_mid << 16) +
(ataio->res.lba_low << 8) +
ataio->res.sector_count;
- /* This PMP declares 6 ports, while only 5 of them are real.
- * Port 5 is enclosure management bridge port, which has implementation
- * problems, causing probe faults. Hide it for now. */
- if (softc->pm_pid == 0x37261095 && softc->pm_ports == 6)
- softc->pm_ports = 5;
- /* This PMP declares 7 ports, while only 5 of them are real.
- * Port 5 is some fake "Config Disk" with 640 sectors size,
- * port 6 is enclosure management bridge port.
- * Both fake ports has implementation problems, causing
- * probe faults. Hide them for now. */
- if (softc->pm_pid == 0x47261095 && softc->pm_ports == 7)
- softc->pm_ports = 5;
- /* These PMPs declare one more port then actually have,
- * for configuration purposes. Hide it for now. */
- if (softc->pm_pid == 0x57231095 || softc->pm_pid == 0x57331095 ||
- softc->pm_pid == 0x57341095 || softc->pm_pid == 0x57441095)
- softc->pm_ports--;
+ if (pmp_hide_special) {
+ /*
+ * This PMP declares 6 ports, while only 5 of them
+ * are real. Port 5 is a SEMB port, probing which
+ * causes timeouts if external SEP is not connected
+ * to PMP over I2C.
+ */
+ if (softc->pm_pid == 0x37261095 && softc->pm_ports == 6)
+ softc->pm_ports = 5;
+
+ /*
+ * This PMP declares 7 ports, while only 5 of them
+ * are real. Port 5 is a fake "Config Disk" with
+ * 640 sectors size. Port 6 is a SEMB port.
+ */
+ if (softc->pm_pid == 0x47261095 && softc->pm_ports == 7)
+ softc->pm_ports = 5;
+
+ /*
+ * These PMPs have extra configuration port.
+ */
+ if (softc->pm_pid == 0x57231095 ||
+ softc->pm_pid == 0x57331095 ||
+ softc->pm_pid == 0x57341095 ||
+ softc->pm_pid == 0x57441095)
+ softc->pm_ports--;
+ }
printf("%s%d: %d fan-out ports\n",
periph->periph_name, periph->unit_number,
softc->pm_ports);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/ata/ata_xpt.c
--- a/head/sys/cam/ata/ata_xpt.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/ata/ata_xpt.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/ata/ata_xpt.c 230912 2012-02-02 14:17:58Z mav $");
+__FBSDID("$FreeBSD: head/sys/cam/ata/ata_xpt.c 236814 2012-06-09 13:07:44Z mav $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -65,6 +65,7 @@
struct scsi_inquiry_pattern inq_pat;
u_int8_t quirks;
#define CAM_QUIRK_MAXTAGS 0x01
+ u_int mintags;
u_int maxtags;
};
@@ -93,6 +94,9 @@
PROBE_FULL_INQUIRY,
PROBE_PM_PID,
PROBE_PM_PRV,
+ PROBE_IDENTIFY_SES,
+ PROBE_IDENTIFY_SAFTE,
+ PROBE_DONE,
PROBE_INVALID
} probe_action;
@@ -110,6 +114,9 @@
"PROBE_FULL_INQUIRY",
"PROBE_PM_PID",
"PROBE_PM_PRV",
+ "PROBE_IDENTIFY_SES",
+ "PROBE_IDENTIFY_SAFTE",
+ "PROBE_DONE",
"PROBE_INVALID"
};
@@ -117,7 +124,7 @@
do { \
char **text; \
text = probe_action_text; \
- CAM_DEBUG((softc)->periph->path, CAM_DEBUG_INFO, \
+ CAM_DEBUG((softc)->periph->path, CAM_DEBUG_PROBE, \
("Probe %s to %s\n", text[(softc)->action], \
text[(newaction)])); \
(softc)->action = (newaction); \
@@ -149,7 +156,7 @@
T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
/*vendor*/"*", /*product*/"*", /*revision*/"*"
},
- /*quirks*/0, /*maxtags*/0
+ /*quirks*/0, /*mintags*/0, /*maxtags*/0
},
};
@@ -160,9 +167,7 @@
void *arg);
static void probeschedule(struct cam_periph *probe_periph);
static void probestart(struct cam_periph *periph, union ccb *start_ccb);
-//static void proberequestdefaultnegotiation(struct cam_periph *periph);
-//static int proberequestbackoff(struct cam_periph *periph,
-// struct cam_ed *device);
+static void proberequestdefaultnegotiation(struct cam_periph *periph);
static void probedone(struct cam_periph *periph, union ccb *done_ccb);
static void probecleanup(struct cam_periph *periph);
static void ata_find_quirk(struct cam_ed *device);
@@ -175,6 +180,7 @@
ata_alloc_device(struct cam_eb *bus, struct cam_et *target,
lun_id_t lun_id);
static void ata_device_transport(struct cam_path *path);
+static void ata_get_transfer_settings(struct ccb_trans_settings *cts);
static void ata_set_transfer_settings(struct ccb_trans_settings *cts,
struct cam_ed *device,
int async_update);
@@ -247,6 +253,8 @@
if (status != CAM_REQ_CMP) {
return (status);
}
+ CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe started\n"));
+
/*
* Ensure nobody slip in until probe finish.
*/
@@ -266,7 +274,8 @@
ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) ||
- periph->path->device->protocol == PROTO_SATAPM)
+ periph->path->device->protocol == PROTO_SATAPM ||
+ periph->path->device->protocol == PROTO_SEMB)
PROBE_SET_ACTION(softc, PROBE_RESET);
else
PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
@@ -300,7 +309,8 @@
if (softc->restart) {
softc->restart = 0;
if ((path->device->flags & CAM_DEV_UNCONFIGURED) ||
- path->device->protocol == PROTO_SATAPM)
+ path->device->protocol == PROTO_SATAPM ||
+ path->device->protocol == PROTO_SEMB)
softc->action = PROBE_RESET;
else
softc->action = PROBE_IDENTIFY;
@@ -406,6 +416,7 @@
path->device->inq_flags &= ~SID_DMA;
else
path->device->inq_flags |= SID_DMA;
+ xpt_async(AC_GETDEV_CHANGED, path, NULL);
cam_fill_ataio(ataio,
1,
probedone,
@@ -622,15 +633,36 @@
10 * 1000);
ata_pm_read_cmd(ataio, 1, 15);
break;
- case PROBE_INVALID:
- CAM_DEBUG(path, CAM_DEBUG_INFO,
- ("probestart: invalid action state\n"));
+ case PROBE_IDENTIFY_SES:
+ cam_fill_ataio(ataio,
+ 1,
+ probedone,
+ /*flags*/CAM_DIR_IN,
+ 0,
+ /*data_ptr*/(u_int8_t *)&softc->ident_data,
+ /*dxfer_len*/sizeof(softc->ident_data),
+ 30 * 1000);
+ ata_28bit_cmd(ataio, ATA_SEP_ATTN, 0xEC, 0x02,
+ sizeof(softc->ident_data) / 4);
+ break;
+ case PROBE_IDENTIFY_SAFTE:
+ cam_fill_ataio(ataio,
+ 1,
+ probedone,
+ /*flags*/CAM_DIR_IN,
+ 0,
+ /*data_ptr*/(u_int8_t *)&softc->ident_data,
+ /*dxfer_len*/sizeof(softc->ident_data),
+ 30 * 1000);
+ ata_28bit_cmd(ataio, ATA_SEP_ATTN, 0xEC, 0x00,
+ sizeof(softc->ident_data) / 4);
+ break;
default:
- break;
+ panic("probestart: invalid action state 0x%x\n", softc->action);
}
xpt_action(start_ccb);
}
-#if 0
+
static void
proberequestdefaultnegotiation(struct cam_periph *periph)
{
@@ -640,130 +672,29 @@
cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
cts.type = CTS_TYPE_USER_SETTINGS;
xpt_action((union ccb *)&cts);
- if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
+ if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
return;
- }
+ cts.xport_specific.valid = 0;
cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
cts.type = CTS_TYPE_CURRENT_SETTINGS;
xpt_action((union ccb *)&cts);
}
-/*
- * Backoff Negotiation Code- only pertinent for SPI devices.
- */
-static int
-proberequestbackoff(struct cam_periph *periph, struct cam_ed *device)
-{
- struct ccb_trans_settings cts;
- struct ccb_trans_settings_spi *spi;
-
- memset(&cts, 0, sizeof (cts));
- xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NONE);
- cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
- cts.type = CTS_TYPE_CURRENT_SETTINGS;
- xpt_action((union ccb *)&cts);
- if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
- if (bootverbose) {
- xpt_print(periph->path,
- "failed to get current device settings\n");
- }
- return (0);
- }
- if (cts.transport != XPORT_SPI) {
- if (bootverbose) {
- xpt_print(periph->path, "not SPI transport\n");
- }
- return (0);
- }
- spi = &cts.xport_specific.spi;
-
- /*
- * We cannot renegotiate sync rate if we don't have one.
- */
- if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0) {
- if (bootverbose) {
- xpt_print(periph->path, "no sync rate known\n");
- }
- return (0);
- }
-
- /*
- * We'll assert that we don't have to touch PPR options- the
- * SIM will see what we do with period and offset and adjust
- * the PPR options as appropriate.
- */
-
- /*
- * A sync rate with unknown or zero offset is nonsensical.
- * A sync period of zero means Async.
- */
- if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0
- || spi->sync_offset == 0 || spi->sync_period == 0) {
- if (bootverbose) {
- xpt_print(periph->path, "no sync rate available\n");
- }
- return (0);
- }
-
- if (device->flags & CAM_DEV_DV_HIT_BOTTOM) {
- CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
- ("hit async: giving up on DV\n"));
- return (0);
- }
-
-
- /*
- * Jump sync_period up by one, but stop at 5MHz and fall back to Async.
- * We don't try to remember 'last' settings to see if the SIM actually
- * gets into the speed we want to set. We check on the SIM telling
- * us that a requested speed is bad, but otherwise don't try and
- * check the speed due to the asynchronous and handshake nature
- * of speed setting.
- */
- spi->valid = CTS_SPI_VALID_SYNC_RATE | CTS_SPI_VALID_SYNC_OFFSET;
- for (;;) {
- spi->sync_period++;
- if (spi->sync_period >= 0xf) {
- spi->sync_period = 0;
- spi->sync_offset = 0;
- CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
- ("setting to async for DV\n"));
- /*
- * Once we hit async, we don't want to try
- * any more settings.
- */
- device->flags |= CAM_DEV_DV_HIT_BOTTOM;
- } else if (bootverbose) {
- CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
- ("DV: period 0x%x\n", spi->sync_period));
- printf("setting period to 0x%x\n", spi->sync_period);
- }
- cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
- cts.type = CTS_TYPE_CURRENT_SETTINGS;
- xpt_action((union ccb *)&cts);
- if ((cts.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
- break;
- }
- CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
- ("DV: failed to set period 0x%x\n", spi->sync_period));
- if (spi->sync_period == 0) {
- return (0);
- }
- }
- return (1);
-}
-#endif
static void
probedone(struct cam_periph *periph, union ccb *done_ccb)
{
struct ccb_trans_settings cts;
struct ata_params *ident_buf;
+ struct scsi_inquiry_data *inq_buf;
probe_softc *softc;
struct cam_path *path;
cam_status status;
u_int32_t priority;
u_int caps;
- int found = 1;
+ int changed = 1, found = 1;
+ static const uint8_t fake_device_id_hdr[8] =
+ {0, SVPD_DEVICE_ID, 0, 12,
+ SVPD_ID_CODESET_BINARY, SVPD_ID_TYPE_NAA, 0, 8};
CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probedone\n"));
@@ -771,14 +702,12 @@
path = done_ccb->ccb_h.path;
priority = done_ccb->ccb_h.pinfo.priority;
ident_buf = &path->device->ident_data;
+ inq_buf = &path->device->inq_data;
if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
- if (softc->restart) {
- if (bootverbose) {
- cam_error_print(done_ccb,
- CAM_ESF_ALL, CAM_EPF_ALL);
- }
- } else if (cam_periph_error(done_ccb, 0, 0, NULL) == ERESTART)
+ if (cam_periph_error(done_ccb,
+ 0, softc->restart ? (SF_NO_RECOVERY | SF_NO_RETRY) : 0,
+ NULL) == ERESTART)
return;
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
/* Don't wedge the queue */
@@ -819,6 +748,18 @@
} else if (softc->action == PROBE_SETDMAAA &&
status == CAM_ATA_STATUS_ERROR) {
goto noerror;
+
+ /*
+ * SES and SAF-TE SEPs have different IDENTIFY commands,
+ * but SATA specification doesn't tell how to identify them.
+ * Until better way found, just try another if first fail.
+ */
+ } else if (softc->action == PROBE_IDENTIFY_SES &&
+ status == CAM_ATA_STATUS_ERROR) {
+ PROBE_SET_ACTION(softc, PROBE_IDENTIFY_SAFTE);
+ xpt_release_ccb(done_ccb);
+ xpt_schedule(periph, priority);
+ return;
}
/*
@@ -833,6 +774,7 @@
*/
device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
xpt_async(AC_LOST_DEVICE, path, NULL);
+ PROBE_SET_ACTION(softc, PROBE_INVALID);
found = 0;
goto done;
}
@@ -844,8 +786,8 @@
{
int sign = (done_ccb->ataio.res.lba_high << 8) +
done_ccb->ataio.res.lba_mid;
- if (bootverbose)
- xpt_print(path, "SIGNATURE: %04x\n", sign);
+ CAM_DEBUG(path, CAM_DEBUG_PROBE,
+ ("SIGNATURE: %04x\n", sign));
if (sign == 0x0000 &&
done_ccb->ccb_h.target_id != 15) {
path->device->protocol = PROTO_ATA;
@@ -862,6 +804,10 @@
xpt_action((union ccb *)&cts);
path->device->protocol = PROTO_SATAPM;
PROBE_SET_ACTION(softc, PROBE_PM_PID);
+ } else if (sign == 0xc33c &&
+ done_ccb->ccb_h.target_id != 15) {
+ path->device->protocol = PROTO_SEMB;
+ PROBE_SET_ACTION(softc, PROBE_IDENTIFY_SES);
} else if (sign == 0xeb14 &&
done_ccb->ccb_h.target_id != 15) {
path->device->protocol = PROTO_SCSI;
@@ -881,7 +827,6 @@
{
struct ccb_pathinq cpi;
int16_t *ptr;
- int changed = 1;
ident_buf = &softc->ident_data;
for (ptr = (int16_t *)ident_buf;
@@ -936,6 +881,11 @@
path->device->serial_num = NULL;
path->device->serial_num_len = 0;
}
+ if (path->device->device_id != NULL) {
+ free(path->device->device_id, M_CAMXPT);
+ path->device->device_id = NULL;
+ path->device->device_id_len = 0;
+ }
path->device->serial_num =
(u_int8_t *)malloc((sizeof(ident_buf->serial) + 1),
M_CAMXPT, M_NOWAIT);
@@ -948,11 +898,25 @@
path->device->serial_num_len =
strlen(path->device->serial_num);
}
+ if (ident_buf->enabled.extension &
+ ATA_SUPPORT_64BITWWN) {
+ path->device->device_id =
+ malloc(16, M_CAMXPT, M_NOWAIT);
+ if (path->device->device_id != NULL) {
+ path->device->device_id_len = 16;
+ bcopy(&fake_device_id_hdr,
+ path->device->device_id, 8);
+ bcopy(ident_buf->wwn,
+ path->device->device_id + 8, 8);
+ }
+ }
path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
+ xpt_async(AC_GETDEV_CHANGED, path, NULL);
}
if (ident_buf->satacapabilities & ATA_SUPPORT_NCQ) {
- path->device->mintags = path->device->maxtags =
+ path->device->mintags = 2;
+ path->device->maxtags =
ATA_QUEUE_LEN(ident_buf->queue) + 1;
}
ata_find_quirk(path->device);
@@ -973,11 +937,11 @@
cts.xport_specific.sata.tags = path->device->maxtags;
cts.xport_specific.sata.valid = CTS_SATA_VALID_TAGS;
xpt_action((union ccb *)&cts);
- /* Reconfigure queues for tagged queueing. */
- xpt_start_tags(path);
}
}
ata_device_transport(path);
+ if (changed)
+ proberequestdefaultnegotiation(periph);
PROBE_SET_ACTION(softc, PROBE_SETMODE);
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
@@ -1088,15 +1052,14 @@
xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
done_ccb);
}
+ PROBE_SET_ACTION(softc, PROBE_DONE);
break;
case PROBE_INQUIRY:
case PROBE_FULL_INQUIRY:
{
- struct scsi_inquiry_data *inq_buf;
u_int8_t periph_qual, len;
path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID;
- inq_buf = &path->device->inq_data;
periph_qual = SID_QUAL(inq_buf);
@@ -1131,6 +1094,7 @@
xpt_action(done_ccb);
xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path, done_ccb);
}
+ PROBE_SET_ACTION(softc, PROBE_DONE);
break;
}
case PROBE_PM_PID:
@@ -1156,6 +1120,9 @@
snprintf(ident_buf->revision, sizeof(ident_buf->revision),
"%04x", softc->pm_prv);
path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
+ ata_device_transport(path);
+ if (periph->path->device->flags & CAM_DEV_UNCONFIGURED)
+ proberequestdefaultnegotiation(periph);
/* Set supported bits. */
bzero(&cts, sizeof(cts));
xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
@@ -1199,12 +1166,56 @@
xpt_action(done_ccb);
xpt_async(AC_SCSI_AEN, done_ccb->ccb_h.path, done_ccb);
}
+ PROBE_SET_ACTION(softc, PROBE_DONE);
break;
- case PROBE_INVALID:
- CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_INFO,
- ("probedone: invalid action state\n"));
+ case PROBE_IDENTIFY_SES:
+ case PROBE_IDENTIFY_SAFTE:
+ if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) {
+ /* Check that it is the same device. */
+ if (bcmp(&softc->ident_data, ident_buf, 53)) {
+ /* Device changed. */
+ xpt_async(AC_LOST_DEVICE, path, NULL);
+ } else {
+ bcopy(&softc->ident_data, ident_buf, sizeof(struct ata_params));
+ changed = 0;
+ }
+ }
+ if (changed) {
+ bcopy(&softc->ident_data, ident_buf, sizeof(struct ata_params));
+ /* Clean up from previous instance of this device */
+ if (path->device->device_id != NULL) {
+ free(path->device->device_id, M_CAMXPT);
+ path->device->device_id = NULL;
+ path->device->device_id_len = 0;
+ }
+ path->device->device_id =
+ malloc(16, M_CAMXPT, M_NOWAIT);
+ if (path->device->device_id != NULL) {
+ path->device->device_id_len = 16;
+ bcopy(&fake_device_id_hdr,
+ path->device->device_id, 8);
+ bcopy(((uint8_t*)ident_buf) + 2,
+ path->device->device_id + 8, 8);
+ }
+
+ path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
+ }
+ ata_device_transport(path);
+ if (changed)
+ proberequestdefaultnegotiation(periph);
+
+ if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
+ path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+ xpt_acquire_device(path->device);
+ done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
+ xpt_action(done_ccb);
+ xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
+ done_ccb);
+ }
+ PROBE_SET_ACTION(softc, PROBE_DONE);
+ break;
default:
- break;
+ panic("probedone: invalid action state 0x%x\n", softc->action);
}
done:
if (softc->restart) {
@@ -1214,15 +1225,16 @@
return;
}
xpt_release_ccb(done_ccb);
+ CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe completed\n"));
while ((done_ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs))) {
TAILQ_REMOVE(&softc->request_ccbs,
&done_ccb->ccb_h, periph_links.tqe);
done_ccb->ccb_h.status = found ? CAM_REQ_CMP : CAM_REQ_CMP_ERR;
xpt_done(done_ccb);
}
+ cam_periph_invalidate(periph);
cam_release_devq(periph->path,
RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_XPT + 1, FALSE);
- cam_periph_invalidate(periph);
cam_periph_release_locked(periph);
}
@@ -1248,8 +1260,10 @@
quirk = (struct ata_quirk_entry *)match;
device->quirk = quirk;
- if (quirk->quirks & CAM_QUIRK_MAXTAGS)
- device->mintags = device->maxtags = quirk->maxtags;
+ if (quirk->quirks & CAM_QUIRK_MAXTAGS) {
+ device->mintags = quirk->mintags;
+ device->maxtags = quirk->maxtags;
+ }
}
typedef struct {
@@ -1473,12 +1487,17 @@
}
if ((old_periph = cam_periph_find(path, "aprobe")) != NULL) {
- probe_softc *softc;
+ if ((old_periph->flags & CAM_PERIPH_INVALID) == 0) {
+ probe_softc *softc;
- softc = (probe_softc *)old_periph->softc;
- TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h,
- periph_links.tqe);
- softc->restart = 1;
+ softc = (probe_softc *)old_periph->softc;
+ TAILQ_INSERT_TAIL(&softc->request_ccbs,
+ &request_ccb->ccb_h, periph_links.tqe);
+ softc->restart = 1;
+ } else {
+ request_ccb->ccb_h.status = CAM_REQ_CMP_ERR;
+ xpt_done(request_ccb);
+ }
} else {
status = cam_periph_alloc(proberegister, NULL, probecleanup,
probestart, "aprobe",
@@ -1624,10 +1643,20 @@
device = start_ccb->ccb_h.path->device;
cdai = &start_ccb->cdai;
switch(cdai->buftype) {
+ case CDAI_TYPE_SCSI_DEVID:
+ if (cdai->flags & CDAI_FLAG_STORE)
+ return;
+ cdai->provsiz = device->device_id_len;
+ if (device->device_id_len == 0)
+ break;
+ amt = device->device_id_len;
+ if (cdai->provsiz > cdai->bufsiz)
+ amt = cdai->bufsiz;
+ memcpy(cdai->buf, device->device_id, amt);
+ break;
case CDAI_TYPE_SERIAL_NUM:
if (cdai->flags & CDAI_FLAG_STORE)
- break;
- start_ccb->ccb_h.status = CAM_REQ_CMP;
+ return;
cdai->provsiz = device->serial_num_len;
if (device->serial_num_len == 0)
break;
@@ -1636,8 +1665,45 @@
amt = cdai->bufsiz;
memcpy(cdai->buf, device->serial_num, amt);
break;
+ case CDAI_TYPE_PHYS_PATH:
+ if (cdai->flags & CDAI_FLAG_STORE) {
+ if (device->physpath != NULL)
+ free(device->physpath, M_CAMXPT);
+ device->physpath_len = cdai->bufsiz;
+ /* Clear existing buffer if zero length */
+ if (cdai->bufsiz == 0)
+ break;
+ device->physpath = malloc(cdai->bufsiz, M_CAMXPT, M_NOWAIT);
+ if (device->physpath == NULL) {
+ start_ccb->ccb_h.status = CAM_REQ_ABORTED;
+ return;
+ }
+ memcpy(device->physpath, cdai->buf, cdai->bufsiz);
+ } else {
+ cdai->provsiz = device->physpath_len;
+ if (device->physpath_len == 0)
+ break;
+ amt = device->physpath_len;
+ if (cdai->provsiz > cdai->bufsiz)
+ amt = cdai->bufsiz;
+ memcpy(cdai->buf, device->physpath, amt);
+ }
+ break;
default:
- break;
+ return;
+ }
+ start_ccb->ccb_h.status = CAM_REQ_CMP;
+
+ if (cdai->flags & CDAI_FLAG_STORE) {
+ int owned;
+
+ owned = mtx_owned(start_ccb->ccb_h.path->bus->sim->mtx);
+ if (owned == 0)
+ mtx_lock(start_ccb->ccb_h.path->bus->sim->mtx);
+ xpt_async(AC_ADVINFO_CHANGED, start_ccb->ccb_h.path,
+ (void *)(uintptr_t)cdai->buftype);
+ if (owned == 0)
+ mtx_unlock(start_ccb->ccb_h.path->bus->sim->mtx);
}
}
@@ -1664,10 +1730,7 @@
break;
case XPT_GET_TRAN_SETTINGS:
{
- struct cam_sim *sim;
-
- sim = start_ccb->ccb_h.path->bus->sim;
- (*(sim->sim_action))(sim, start_ccb);
+ ata_get_transfer_settings(&start_ccb->cts);
break;
}
case XPT_SCSI_IO:
@@ -1706,14 +1769,60 @@
}
static void
+ata_get_transfer_settings(struct ccb_trans_settings *cts)
+{
+ struct ccb_trans_settings_ata *ata;
+ struct ccb_trans_settings_scsi *scsi;
+ struct cam_ed *device;
+ struct cam_sim *sim;
+
+ device = cts->ccb_h.path->device;
+ sim = cts->ccb_h.path->bus->sim;
+ (*(sim->sim_action))(sim, (union ccb *)cts);
+
+ if (cts->protocol == PROTO_UNKNOWN ||
+ cts->protocol == PROTO_UNSPECIFIED) {
+ cts->protocol = device->protocol;
+ cts->protocol_version = device->protocol_version;
+ }
+
+ if (cts->protocol == PROTO_ATA) {
+ ata = &cts->proto_specific.ata;
+ if ((ata->valid & CTS_ATA_VALID_TQ) == 0) {
+ ata->valid |= CTS_ATA_VALID_TQ;
+ if (cts->type == CTS_TYPE_USER_SETTINGS ||
+ (device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0 ||
+ (device->inq_flags & SID_CmdQue) != 0)
+ ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
+ }
+ }
+ if (cts->protocol == PROTO_SCSI) {
+ scsi = &cts->proto_specific.scsi;
+ if ((scsi->valid & CTS_SCSI_VALID_TQ) == 0) {
+ scsi->valid |= CTS_SCSI_VALID_TQ;
+ if (cts->type == CTS_TYPE_USER_SETTINGS ||
+ (device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0 ||
+ (device->inq_flags & SID_CmdQue) != 0)
+ scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
+ }
+ }
+
+ if (cts->transport == XPORT_UNKNOWN ||
+ cts->transport == XPORT_UNSPECIFIED) {
+ cts->transport = device->transport;
+ cts->transport_version = device->transport_version;
+ }
+}
+
+static void
ata_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device,
int async_update)
{
struct ccb_pathinq cpi;
- struct ccb_trans_settings cur_cts;
+ struct ccb_trans_settings_ata *ata;
struct ccb_trans_settings_scsi *scsi;
- struct ccb_trans_settings_scsi *cur_scsi;
struct cam_sim *sim;
+ struct ata_params *ident_data;
struct scsi_inquiry_data *inq_data;
if (device == NULL) {
@@ -1773,95 +1882,63 @@
}
sim = cts->ccb_h.path->bus->sim;
-
- /*
- * Nothing more of interest to do unless
- * this is a device connected via the
- * SCSI protocol.
- */
- if (cts->protocol != PROTO_SCSI) {
- if (async_update == FALSE)
- (*(sim->sim_action))(sim, (union ccb *)cts);
- return;
- }
-
+ ident_data = &device->ident_data;
inq_data = &device->inq_data;
- scsi = &cts->proto_specific.scsi;
+ if (cts->protocol == PROTO_ATA)
+ ata = &cts->proto_specific.ata;
+ else
+ ata = NULL;
+ if (cts->protocol == PROTO_SCSI)
+ scsi = &cts->proto_specific.scsi;
+ else
+ scsi = NULL;
xpt_setup_ccb(&cpi.ccb_h, cts->ccb_h.path, CAM_PRIORITY_NONE);
cpi.ccb_h.func_code = XPT_PATH_INQ;
xpt_action((union ccb *)&cpi);
- /* SCSI specific sanity checking */
+ /* Sanity checking */
if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0
- || (INQ_DATA_TQ_ENABLED(inq_data)) == 0
+ || (ata && (ident_data->satacapabilities & ATA_SUPPORT_NCQ) == 0)
+ || (scsi && (INQ_DATA_TQ_ENABLED(inq_data)) == 0)
|| (device->queue_flags & SCP_QUEUE_DQUE) != 0
|| (device->mintags == 0)) {
/*
* Can't tag on hardware that doesn't support tags,
* doesn't have it enabled, or has broken tag support.
*/
- scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
- }
-
- if (async_update == FALSE) {
- /*
- * Perform sanity checking against what the
- * controller and device can do.
- */
- xpt_setup_ccb(&cur_cts.ccb_h, cts->ccb_h.path, CAM_PRIORITY_NONE);
- cur_cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
- cur_cts.type = cts->type;
- xpt_action((union ccb *)&cur_cts);
- if ((cur_cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
- return;
- }
- cur_scsi = &cur_cts.proto_specific.scsi;
- if ((scsi->valid & CTS_SCSI_VALID_TQ) == 0) {
- scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
- scsi->flags |= cur_scsi->flags & CTS_SCSI_FLAGS_TAG_ENB;
- }
- if ((cur_scsi->valid & CTS_SCSI_VALID_TQ) == 0)
+ if (ata)
+ ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
+ if (scsi)
scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
}
- if (cts->type == CTS_TYPE_CURRENT_SETTINGS
- && (scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
- int device_tagenb;
+ /* Start/stop tags use. */
+ if (cts->type == CTS_TYPE_CURRENT_SETTINGS &&
+ ((ata && (ata->valid & CTS_ATA_VALID_TQ) != 0) ||
+ (scsi && (scsi->valid & CTS_SCSI_VALID_TQ) != 0))) {
+ int nowt, newt = 0;
- /*
- * If we are transitioning from tags to no-tags or
- * vice-versa, we need to carefully freeze and restart
- * the queue so that we don't overlap tagged and non-tagged
- * commands. We also temporarily stop tags if there is
- * a change in transfer negotiation settings to allow
- * "tag-less" negotiation.
- */
- if ((device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
- || (device->inq_flags & SID_CmdQue) != 0)
- device_tagenb = TRUE;
- else
- device_tagenb = FALSE;
+ nowt = ((device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0 ||
+ (device->inq_flags & SID_CmdQue) != 0);
+ if (ata)
+ newt = (ata->flags & CTS_ATA_FLAGS_TAG_ENB) != 0;
+ if (scsi)
+ newt = (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0;
- if (((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0
- && device_tagenb == FALSE)
- || ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) == 0
- && device_tagenb == TRUE)) {
+ if (newt && !nowt) {
+ /*
+ * Delay change to use tags until after a
+ * few commands have gone to this device so
+ * the controller has time to perform transfer
+ * negotiations without tagged messages getting
+ * in the way.
+ */
+ device->tag_delay_count = CAM_TAG_DELAY_COUNT;
+ device->flags |= CAM_DEV_TAG_AFTER_COUNT;
+ } else if (nowt && !newt)
+ xpt_stop_tags(cts->ccb_h.path);
+ }
- if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) {
- /*
- * Delay change to use tags until after a
- * few commands have gone to this device so
- * the controller has time to perform transfer
- * negotiations without tagged messages getting
- * in the way.
- */
- device->tag_delay_count = CAM_TAG_DELAY_COUNT;
- device->flags |= CAM_DEV_TAG_AFTER_COUNT;
- } else {
- xpt_stop_tags(cts->ccb_h.path);
- }
- }
- }
if (async_update == FALSE)
(*(sim->sim_action))(sim, (union ccb *)cts);
}
@@ -1951,11 +2028,11 @@
/* Report connection speed */
speed = cpi.base_transfer_speed;
if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_ATA) {
- struct ccb_trans_settings_ata *ata =
+ struct ccb_trans_settings_pata *pata =
&cts.xport_specific.ata;
- if (ata->valid & CTS_ATA_VALID_MODE)
- speed = ata_mode2speed(ata->mode);
+ if (pata->valid & CTS_ATA_VALID_MODE)
+ speed = ata_mode2speed(pata->mode);
}
if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) {
struct ccb_trans_settings_sata *sata =
@@ -1974,16 +2051,16 @@
periph->unit_number, speed);
/* Report additional information about connection */
if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_ATA) {
- struct ccb_trans_settings_ata *ata =
+ struct ccb_trans_settings_pata *pata =
&cts.xport_specific.ata;
printf(" (");
- if (ata->valid & CTS_ATA_VALID_MODE)
- printf("%s, ", ata_mode2string(ata->mode));
- if ((ata->valid & CTS_ATA_VALID_ATAPI) && ata->atapi != 0)
- printf("ATAPI %dbytes, ", ata->atapi);
- if (ata->valid & CTS_ATA_VALID_BYTECOUNT)
- printf("PIO %dbytes", ata->bytecount);
+ if (pata->valid & CTS_ATA_VALID_MODE)
+ printf("%s, ", ata_mode2string(pata->mode));
+ if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
+ printf("ATAPI %dbytes, ", pata->atapi);
+ if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
+ printf("PIO %dbytes", pata->bytecount);
printf(")");
}
if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) {
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/cam.h
--- a/head/sys/cam/cam.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/cam.h Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/cam/cam.h 236814 2012-06-09 13:07:44Z mav $
*/
#ifndef _CAM_CAM_H
@@ -108,6 +108,15 @@
CAM_RETRY_SELTO = 0x02 /* Retry Selection Timeouts */
} cam_flags;
+enum {
+ SF_RETRY_UA = 0x01, /* Retry UNIT ATTENTION conditions. */
+ SF_NO_PRINT = 0x02, /* Never print error status. */
+ SF_QUIET_IR = 0x04, /* Be quiet about Illegal Request reponses */
+ SF_PRINT_ALWAYS = 0x08, /* Always print error status. */
+ SF_NO_RECOVERY = 0x10, /* Don't do active error recovery. */
+ SF_NO_RETRY = 0x20 /* Don't do any retries. */
+};
+
/* CAM Status field values */
typedef enum {
CAM_REQ_INPROG, /* CCB request is in progress */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/cam_ccb.h
--- a/head/sys/cam/cam_ccb.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/cam_ccb.h Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/cam/cam_ccb.h 230590 2012-01-26 18:09:28Z ken $
+ * $FreeBSD: head/sys/cam/cam_ccb.h 236437 2012-06-02 08:29:07Z mav $
*/
#ifndef _CAM_CAM_CCB_H
@@ -242,6 +242,7 @@
PROTO_ATA, /* AT Attachment */
PROTO_ATAPI, /* AT Attachment Packetized Interface */
PROTO_SATAPM, /* SATA Port Multiplier */
+ PROTO_SEMB, /* SATA Enclosure Management Bridge */
} cam_proto;
typedef enum {
@@ -843,6 +844,14 @@
#define CTS_SCSI_FLAGS_TAG_ENB 0x01
};
+struct ccb_trans_settings_ata
+{
+ u_int valid; /* Which fields to honor */
+#define CTS_ATA_VALID_TQ 0x01
+ u_int flags;
+#define CTS_ATA_FLAGS_TAG_ENB 0x01
+};
+
struct ccb_trans_settings_spi
{
u_int valid; /* Which fields to honor */
@@ -877,7 +886,7 @@
u_int32_t bitrate; /* Mbps */
};
-struct ccb_trans_settings_ata {
+struct ccb_trans_settings_pata {
u_int valid; /* Which fields to honor */
#define CTS_ATA_VALID_MODE 0x01
#define CTS_ATA_VALID_BYTECOUNT 0x02
@@ -923,6 +932,7 @@
u_int transport_version;
union {
u_int valid; /* Which fields to honor */
+ struct ccb_trans_settings_ata ata;
struct ccb_trans_settings_scsi scsi;
} proto_specific;
union {
@@ -930,7 +940,7 @@
struct ccb_trans_settings_spi spi;
struct ccb_trans_settings_fc fc;
struct ccb_trans_settings_sas sas;
- struct ccb_trans_settings_ata ata;
+ struct ccb_trans_settings_pata ata;
struct ccb_trans_settings_sata sata;
} xport_specific;
};
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/cam_debug.h
--- a/head/sys/cam/cam_debug.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/cam_debug.h Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/cam/cam_debug.h 236712 2012-06-07 10:05:51Z mav $
*/
#ifndef _CAM_CAM_DEBUG_H
#define _CAM_CAM_DEBUG_H 1
@@ -44,7 +44,35 @@
CAM_DEBUG_PROBE = 0x40 /* print out probe actions */
} cam_debug_flags;
-#if defined(CAMDEBUG) && defined(_KERNEL)
+#if defined(_KERNEL)
+
+#ifndef CAM_DEBUG_FLAGS
+#define CAM_DEBUG_FLAGS CAM_DEBUG_NONE
+#endif
+
+#ifndef CAM_DEBUG_COMPILE
+#ifdef CAMDEBUG
+#define CAM_DEBUG_COMPILE (-1)
+#else
+#define CAM_DEBUG_COMPILE (CAM_DEBUG_INFO | CAM_DEBUG_CDB | \
+ CAM_DEBUG_PERIPH | CAM_DEBUG_PROBE | \
+ CAM_DEBUG_FLAGS)
+#endif
+#endif
+
+#ifndef CAM_DEBUG_BUS
+#define CAM_DEBUG_BUS (-1)
+#endif
+#ifndef CAM_DEBUG_TARGET
+#define CAM_DEBUG_TARGET (-1)
+#endif
+#ifndef CAM_DEBUG_LUN
+#define CAM_DEBUG_LUN (-1)
+#endif
+
+#ifndef CAM_DEBUG_DELAY
+#define CAM_DEBUG_DELAY 0
+#endif
/* Path we want to debug */
extern struct cam_path *cam_dpath;
@@ -52,48 +80,48 @@
extern u_int32_t cam_dflags;
/* Printf delay value (to prevent scrolling) */
extern u_int32_t cam_debug_delay;
-
+
/* Debugging macros. */
#define CAM_DEBUGGED(path, flag) \
- ((cam_dflags & (flag)) \
+ (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags) \
&& (cam_dpath != NULL) \
&& (xpt_path_comp(cam_dpath, path) >= 0) \
&& (xpt_path_comp(cam_dpath, path) < 2))
#define CAM_DEBUG(path, flag, printfargs) \
- if ((cam_dflags & (flag)) \
+ if (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags) \
&& (cam_dpath != NULL) \
&& (xpt_path_comp(cam_dpath, path) >= 0) \
&& (xpt_path_comp(cam_dpath, path) < 2)) { \
xpt_print_path(path); \
- printf printfargs; \
+ printf printfargs; \
if (cam_debug_delay != 0) \
DELAY(cam_debug_delay); \
}
#define CAM_DEBUG_PRINT(flag, printfargs) \
- if (cam_dflags & (flag)) { \
+ if (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags)) { \
printf("cam_debug: "); \
- printf printfargs; \
+ printf printfargs; \
if (cam_debug_delay != 0) \
DELAY(cam_debug_delay); \
}
#define CAM_DEBUG_PATH_PRINT(flag, path, printfargs) \
- if (cam_dflags & (flag)) { \
+ if (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags)) { \
xpt_print(path, "cam_debug: "); \
- printf printfargs; \
+ printf printfargs; \
if (cam_debug_delay != 0) \
DELAY(cam_debug_delay); \
}
-#else /* !CAMDEBUG || !_KERNEL */
+#else /* !_KERNEL */
#define CAM_DEBUGGED(A, B) 0
#define CAM_DEBUG(A, B, C)
#define CAM_DEBUG_PRINT(A, B)
#define CAM_DEBUG_PATH_PRINT(A, B, C)
-#endif /* CAMDEBUG && _KERNEL */
+#endif /* _KERNEL */
#endif /* _CAM_CAM_DEBUG_H */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/cam_periph.c
--- a/head/sys/cam/cam_periph.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/cam_periph.c Wed Jul 25 16:45:04 2012 +0300
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/cam_periph.c 230544 2012-01-25 17:58:47Z ken $");
+__FBSDID("$FreeBSD: head/sys/cam/cam_periph.c 237682 2012-06-28 03:36:13Z ken $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -69,18 +69,22 @@
union ccb *done_ccb);
static void camperiphfree(struct cam_periph *periph);
static int camperiphscsistatuserror(union ccb *ccb,
+ union ccb **orig_ccb,
cam_flags camflags,
u_int32_t sense_flags,
int *openings,
u_int32_t *relsim_flags,
u_int32_t *timeout,
+ int *print,
const char **action_string);
static int camperiphscsisenseerror(union ccb *ccb,
+ union ccb **orig_ccb,
cam_flags camflags,
u_int32_t sense_flags,
int *openings,
u_int32_t *relsim_flags,
u_int32_t *timeout,
+ int *print,
const char **action_string);
static int nperiph_drivers;
@@ -240,6 +244,7 @@
goto failure;
init_level++;
+ CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Periph created\n"));
status = periph_ctor(periph, arg);
@@ -252,7 +257,8 @@
/* Initialized successfully */
break;
case 3:
- xpt_remove_periph(periph);
+ CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Periph destroyed\n"));
+ xpt_remove_periph(periph, /*topology_lock_held*/ 0);
/* FALLTHROUGH */
case 2:
xpt_lock_buses();
@@ -267,7 +273,7 @@
/* No cleanup to perform. */
break;
default:
- panic("cam_periph_alloc: Unkown init level");
+ panic("%s: Unknown init level", __func__);
}
return(status);
}
@@ -434,6 +440,10 @@
cam_periph_release_locked(periph);
return (error);
}
+ if (periph->flags & CAM_PERIPH_INVALID) {
+ cam_periph_release_locked(periph);
+ return (ENXIO);
+ }
}
periph->flags |= CAM_PERIPH_LOCKED;
@@ -572,6 +582,7 @@
cam_periph_invalidate(struct cam_periph *periph)
{
+ CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Periph invalidated\n"));
/*
* We only call this routine the first time a peripheral is
* invalidated.
@@ -603,13 +614,39 @@
return;
}
+ /*
+ * The peripheral destructor semantics dictate calling with only the
+ * SIM mutex held. Since it might sleep, it should not be called
+ * with the topology lock held.
+ */
+ xpt_unlock_buses();
+
+ /*
+ * We need to call the peripheral destructor prior to removing the
+ * peripheral from the list. Otherwise, we risk running into a
+ * scenario where the peripheral unit number may get reused
+ * (because it has been removed from the list), but some resources
+ * used by the peripheral are still hanging around. In particular,
+ * the devfs nodes used by some peripherals like the pass(4) driver
+ * aren't fully cleaned up until the destructor is run. If the
+ * unit number is reused before the devfs instance is fully gone,
+ * devfs will panic.
+ */
+ if (periph->periph_dtor != NULL)
+ periph->periph_dtor(periph);
+
+ /*
+ * The peripheral list is protected by the topology lock.
+ */
+ xpt_lock_buses();
+
TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links);
(*p_drv)->generation++;
+
+ xpt_remove_periph(periph, /*topology_lock_held*/ 1);
+
xpt_unlock_buses();
-
- if (periph->periph_dtor != NULL)
- periph->periph_dtor(periph);
- xpt_remove_periph(periph);
+ CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Periph destroyed\n"));
if (periph->flags & CAM_PERIPH_NEW_DEV_FOUND) {
union ccb ccb;
@@ -1104,107 +1141,52 @@
}
#define saved_ccb_ptr ppriv_ptr0
-#define recovery_depth ppriv_field1
-static void
-camperiphsensedone(struct cam_periph *periph, union ccb *done_ccb)
-{
- union ccb *saved_ccb = (union ccb *)done_ccb->ccb_h.saved_ccb_ptr;
- cam_status status;
- int frozen = 0;
- int depth = done_ccb->ccb_h.recovery_depth;
-
- status = done_ccb->ccb_h.status;
- if (status & CAM_DEV_QFRZN) {
- frozen = 1;
- /*
- * Clear freeze flag now for case of retry,
- * freeze will be dropped later.
- */
- done_ccb->ccb_h.status &= ~CAM_DEV_QFRZN;
- }
- status &= CAM_STATUS_MASK;
- switch (status) {
- case CAM_REQ_CMP:
- {
- int error_code, sense_key, asc, ascq;
-
- scsi_extract_sense_len(&saved_ccb->csio.sense_data,
- saved_ccb->csio.sense_len -
- saved_ccb->csio.sense_resid,
- &error_code, &sense_key, &asc, &ascq,
- /*show_errors*/ 1);
- /*
- * If we manually retrieved sense into a CCB and got
- * something other than "NO SENSE" send the updated CCB
- * back to the client via xpt_done() to be processed via
- * the error recovery code again.
- */
- if ((sense_key != -1)
- && (sense_key != SSD_KEY_NO_SENSE)) {
- saved_ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
- } else {
- saved_ccb->ccb_h.status &= ~CAM_STATUS_MASK;
- saved_ccb->ccb_h.status |= CAM_AUTOSENSE_FAIL;
- }
- saved_ccb->csio.sense_resid = done_ccb->csio.resid;
- bcopy(saved_ccb, done_ccb, sizeof(union ccb));
- xpt_free_ccb(saved_ccb);
- break;
- }
- default:
- bcopy(saved_ccb, done_ccb, sizeof(union ccb));
- xpt_free_ccb(saved_ccb);
- done_ccb->ccb_h.status &= ~CAM_STATUS_MASK;
- done_ccb->ccb_h.status |= CAM_AUTOSENSE_FAIL;
- break;
- }
- periph->flags &= ~CAM_PERIPH_SENSE_INPROG;
- /*
- * If it is the end of recovery, drop freeze, taken due to
- * CAM_DEV_QFREEZE flag, set on recovery request.
- */
- if (depth == 0) {
- cam_release_devq(done_ccb->ccb_h.path,
- /*relsim_flags*/0,
- /*openings*/0,
- /*timeout*/0,
- /*getcount_only*/0);
- }
- /*
- * Copy frozen flag from recovery request if it is set there
- * for some reason.
- */
- if (frozen != 0)
- done_ccb->ccb_h.status |= CAM_DEV_QFRZN;
- (*done_ccb->ccb_h.cbfcnp)(periph, done_ccb);
-}
-
static void
camperiphdone(struct cam_periph *periph, union ccb *done_ccb)
{
- union ccb *saved_ccb, *save_ccb;
+ union ccb *saved_ccb;
cam_status status;
- int frozen = 0;
struct scsi_start_stop_unit *scsi_cmd;
- u_int32_t relsim_flags, timeout;
+ int error_code, sense_key, asc, ascq;
+ scsi_cmd = (struct scsi_start_stop_unit *)
+ &done_ccb->csio.cdb_io.cdb_bytes;
status = done_ccb->ccb_h.status;
- if (status & CAM_DEV_QFRZN) {
- frozen = 1;
- /*
- * Clear freeze flag now for case of retry,
- * freeze will be dropped later.
- */
- done_ccb->ccb_h.status &= ~CAM_DEV_QFRZN;
- }
- timeout = 0;
- relsim_flags = 0;
- saved_ccb = (union ccb *)done_ccb->ccb_h.saved_ccb_ptr;
-
- switch (status & CAM_STATUS_MASK) {
- case CAM_REQ_CMP:
- {
+ if ((status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
+ if (scsi_extract_sense_ccb(done_ccb,
+ &error_code, &sense_key, &asc, &ascq)) {
+ /*
+ * If the error is "invalid field in CDB",
+ * and the load/eject flag is set, turn the
+ * flag off and try again. This is just in
+ * case the drive in question barfs on the
+ * load eject flag. The CAM code should set
+ * the load/eject flag by default for
+ * removable media.
+ */
+ if ((scsi_cmd->opcode == START_STOP_UNIT) &&
+ ((scsi_cmd->how & SSS_LOEJ) != 0) &&
+ (asc == 0x24) && (ascq == 0x00)) {
+ scsi_cmd->how &= ~SSS_LOEJ;
+ if (status & CAM_DEV_QFRZN) {
+ cam_release_devq(done_ccb->ccb_h.path,
+ 0, 0, 0, 0);
+ done_ccb->ccb_h.status &=
+ ~CAM_DEV_QFRZN;
+ }
+ xpt_action(done_ccb);
+ goto out;
+ }
+ }
+ if (cam_periph_error(done_ccb,
+ 0, SF_RETRY_UA | SF_NO_PRINT, NULL) == ERESTART)
+ goto out;
+ if (done_ccb->ccb_h.status & CAM_DEV_QFRZN) {
+ cam_release_devq(done_ccb->ccb_h.path, 0, 0, 0, 0);
+ done_ccb->ccb_h.status &= ~CAM_DEV_QFRZN;
+ }
+ } else {
/*
* If we have successfully taken a device from the not
* ready to ready state, re-scan the device and re-get
@@ -1212,147 +1194,24 @@
* don't properly report their inquiry information unless
* they are spun up.
*/
- scsi_cmd = (struct scsi_start_stop_unit *)
- &done_ccb->csio.cdb_io.cdb_bytes;
-
- if (scsi_cmd->opcode == START_STOP_UNIT)
- xpt_async(AC_INQ_CHANGED,
- done_ccb->ccb_h.path, NULL);
- goto final;
- }
- case CAM_SCSI_STATUS_ERROR:
- scsi_cmd = (struct scsi_start_stop_unit *)
- &done_ccb->csio.cdb_io.cdb_bytes;
- if (status & CAM_AUTOSNS_VALID) {
- struct ccb_getdev cgd;
- struct scsi_sense_data *sense;
- int error_code, sense_key, asc, ascq, sense_len;
- scsi_sense_action err_action;
-
- sense = &done_ccb->csio.sense_data;
- sense_len = done_ccb->csio.sense_len -
- done_ccb->csio.sense_resid;
- scsi_extract_sense_len(sense, sense_len, &error_code,
- &sense_key, &asc, &ascq,
- /*show_errors*/ 1);
- /*
- * Grab the inquiry data for this device.
- */
- xpt_setup_ccb(&cgd.ccb_h, done_ccb->ccb_h.path,
- CAM_PRIORITY_NORMAL);
- cgd.ccb_h.func_code = XPT_GDEV_TYPE;
- xpt_action((union ccb *)&cgd);
- err_action = scsi_error_action(&done_ccb->csio,
- &cgd.inq_data, 0);
- /*
- * If the error is "invalid field in CDB",
- * and the load/eject flag is set, turn the
- * flag off and try again. This is just in
- * case the drive in question barfs on the
- * load eject flag. The CAM code should set
- * the load/eject flag by default for
- * removable media.
- */
- /* XXX KDM
- * Should we check to see what the specific
- * scsi status is?? Or does it not matter
- * since we already know that there was an
- * error, and we know what the specific
- * error code was, and we know what the
- * opcode is..
- */
- if ((scsi_cmd->opcode == START_STOP_UNIT) &&
- ((scsi_cmd->how & SSS_LOEJ) != 0) &&
- (asc == 0x24) && (ascq == 0x00) &&
- (done_ccb->ccb_h.retry_count > 0)) {
-
- scsi_cmd->how &= ~SSS_LOEJ;
- xpt_action(done_ccb);
- } else if ((done_ccb->ccb_h.retry_count > 1)
- && ((err_action & SS_MASK) != SS_FAIL)) {
-
- /*
- * In this case, the error recovery
- * command failed, but we've got
- * some retries left on it. Give
- * it another try unless this is an
- * unretryable error.
- */
- /* set the timeout to .5 sec */
- relsim_flags =
- RELSIM_RELEASE_AFTER_TIMEOUT;
- timeout = 500;
- xpt_action(done_ccb);
- break;
- } else {
- /*
- * Perform the final retry with the original
- * CCB so that final error processing is
- * performed by the owner of the CCB.
- */
- goto final;
- }
- } else {
- save_ccb = xpt_alloc_ccb_nowait();
- if (save_ccb == NULL)
- goto final;
- bcopy(done_ccb, save_ccb, sizeof(*save_ccb));
- periph->flags |= CAM_PERIPH_SENSE_INPROG;
- /*
- * Send a Request Sense to the device. We
- * assume that we are in a contingent allegiance
- * condition so we do not tag this request.
- */
- scsi_request_sense(&done_ccb->csio, /*retries*/1,
- camperiphsensedone,
- &save_ccb->csio.sense_data,
- save_ccb->csio.sense_len,
- CAM_TAG_ACTION_NONE,
- /*sense_len*/SSD_FULL_SIZE,
- /*timeout*/5000);
- done_ccb->ccb_h.pinfo.priority--;
- done_ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
- done_ccb->ccb_h.saved_ccb_ptr = save_ccb;
- done_ccb->ccb_h.recovery_depth++;
- xpt_action(done_ccb);
- }
- break;
- default:
-final:
- bcopy(saved_ccb, done_ccb, sizeof(*done_ccb));
- xpt_free_ccb(saved_ccb);
- periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG;
- xpt_action(done_ccb);
- break;
+ if (scsi_cmd->opcode == START_STOP_UNIT)
+ xpt_async(AC_INQ_CHANGED, done_ccb->ccb_h.path, NULL);
}
- /* decrement the retry count */
/*
- * XXX This isn't appropriate in all cases. Restructure,
- * so that the retry count is only decremented on an
- * actual retry. Remeber that the orignal ccb had its
- * retry count dropped before entering recovery, so
- * doing it again is a bug.
+ * Perform the final retry with the original CCB so that final
+ * error processing is performed by the owner of the CCB.
*/
- if (done_ccb->ccb_h.retry_count > 0)
- done_ccb->ccb_h.retry_count--;
- /*
- * Drop freeze taken due to CAM_DEV_QFREEZE flag set on recovery
- * request.
- */
- cam_release_devq(done_ccb->ccb_h.path,
- /*relsim_flags*/relsim_flags,
- /*openings*/0,
- /*timeout*/timeout,
- /*getcount_only*/0);
- /* Drop freeze taken, if this recovery request got error. */
- if (frozen != 0) {
- cam_release_devq(done_ccb->ccb_h.path,
- /*relsim_flags*/0,
- /*openings*/0,
- /*timeout*/0,
- /*getcount_only*/0);
- }
+ saved_ccb = (union ccb *)done_ccb->ccb_h.saved_ccb_ptr;
+ bcopy(saved_ccb, done_ccb, sizeof(*done_ccb));
+ xpt_free_ccb(saved_ccb);
+ if (done_ccb->ccb_h.cbfcnp != camperiphdone)
+ periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG;
+ xpt_action(done_ccb);
+
+out:
+ /* Drop freeze taken due to CAM_DEV_QFREEZE flag set. */
+ cam_release_devq(done_ccb->ccb_h.path, 0, 0, 0, 0);
}
/*
@@ -1411,10 +1270,10 @@
}
static int
-camperiphscsistatuserror(union ccb *ccb, cam_flags camflags,
- u_int32_t sense_flags,
- int *openings, u_int32_t *relsim_flags,
- u_int32_t *timeout, const char **action_string)
+camperiphscsistatuserror(union ccb *ccb, union ccb **orig_ccb,
+ cam_flags camflags, u_int32_t sense_flags,
+ int *openings, u_int32_t *relsim_flags,
+ u_int32_t *timeout, int *print, const char **action_string)
{
int error;
@@ -1427,14 +1286,13 @@
break;
case SCSI_STATUS_CMD_TERMINATED:
case SCSI_STATUS_CHECK_COND:
- if (bootverbose)
- xpt_print(ccb->ccb_h.path, "SCSI status error\n");
- error = camperiphscsisenseerror(ccb,
+ error = camperiphscsisenseerror(ccb, orig_ccb,
camflags,
sense_flags,
openings,
relsim_flags,
timeout,
+ print,
action_string);
break;
case SCSI_STATUS_QUEUE_FULL:
@@ -1489,9 +1347,7 @@
}
*timeout = 0;
error = ERESTART;
- if (bootverbose) {
- xpt_print(ccb->ccb_h.path, "Queue full\n");
- }
+ *print = 0;
break;
}
/* FALLTHROUGH */
@@ -1501,9 +1357,6 @@
* Restart the queue after either another
* command completes or a 1 second timeout.
*/
- if (bootverbose) {
- xpt_print(ccb->ccb_h.path, "Device busy\n");
- }
if (ccb->ccb_h.retry_count > 0) {
ccb->ccb_h.retry_count--;
error = ERESTART;
@@ -1515,12 +1368,7 @@
}
break;
case SCSI_STATUS_RESERV_CONFLICT:
- xpt_print(ccb->ccb_h.path, "Reservation conflict\n");
- error = EIO;
- break;
default:
- xpt_print(ccb->ccb_h.path, "SCSI status 0x%x\n",
- ccb->csio.scsi_status);
error = EIO;
break;
}
@@ -1528,18 +1376,18 @@
}
static int
-camperiphscsisenseerror(union ccb *ccb, cam_flags camflags,
- u_int32_t sense_flags,
- int *openings, u_int32_t *relsim_flags,
- u_int32_t *timeout, const char **action_string)
+camperiphscsisenseerror(union ccb *ccb, union ccb **orig,
+ cam_flags camflags, u_int32_t sense_flags,
+ int *openings, u_int32_t *relsim_flags,
+ u_int32_t *timeout, int *print, const char **action_string)
{
struct cam_periph *periph;
union ccb *orig_ccb = ccb;
- int error;
+ int error, recoveryccb;
periph = xpt_path_periph(ccb->ccb_h.path);
- if (periph->flags &
- (CAM_PERIPH_RECOVERY_INPROG | CAM_PERIPH_SENSE_INPROG)) {
+ recoveryccb = (ccb->ccb_h.cbfcnp == camperiphdone);
+ if ((periph->flags & CAM_PERIPH_RECOVERY_INPROG) && !recoveryccb) {
/*
* If error recovery is already in progress, don't attempt
* to process this error, but requeue it unconditionally
@@ -1554,6 +1402,7 @@
* imperitive that we don't violate this assumption.
*/
error = ERESTART;
+ *print = 0;
} else {
scsi_sense_action err_action;
struct ccb_getdev cgd;
@@ -1565,16 +1414,34 @@
cgd.ccb_h.func_code = XPT_GDEV_TYPE;
xpt_action((union ccb *)&cgd);
- if ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)
- err_action = scsi_error_action(&ccb->csio,
- &cgd.inq_data,
- sense_flags);
- else if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
- err_action = SS_REQSENSE;
- else
- err_action = SS_RETRY|SSQ_DECREMENT_COUNT|EIO;
+ err_action = scsi_error_action(&ccb->csio, &cgd.inq_data,
+ sense_flags);
+ error = err_action & SS_ERRMASK;
- error = err_action & SS_ERRMASK;
+ /*
+ * Do not autostart sequential access devices
+ * to avoid unexpected tape loading.
+ */
+ if ((err_action & SS_MASK) == SS_START &&
+ SID_TYPE(&cgd.inq_data) == T_SEQUENTIAL) {
+ *action_string = "Will not autostart a "
+ "sequential access device";
+ goto sense_error_done;
+ }
+
+ /*
+ * Avoid recovery recursion if recovery action is the same.
+ */
+ if ((err_action & SS_MASK) >= SS_START && recoveryccb) {
+ if (((err_action & SS_MASK) == SS_START &&
+ ccb->csio.cdb_io.cdb_bytes[0] == START_STOP_UNIT) ||
+ ((err_action & SS_MASK) == SS_TUR &&
+ (ccb->csio.cdb_io.cdb_bytes[0] == TEST_UNIT_READY))) {
+ err_action = SS_RETRY|SSQ_DECREMENT_COUNT|EIO;
+ *relsim_flags = RELSIM_RELEASE_AFTER_TIMEOUT;
+ *timeout = 500;
+ }
+ }
/*
* If the recovery action will consume a retry,
@@ -1623,15 +1490,6 @@
case SS_START:
{
int le;
- if (SID_TYPE(&cgd.inq_data) == T_SEQUENTIAL) {
- xpt_free_ccb(orig_ccb);
- ccb->ccb_h.status |= CAM_DEV_QFRZN;
- *action_string = "Will not autostart a "
- "sequential access device";
- err_action = SS_FAIL;
- error = EIO;
- break;
- }
/*
* Send a start unit command to the device, and
@@ -1695,24 +1553,6 @@
*timeout = 500;
break;
}
- case SS_REQSENSE:
- {
- *action_string = "Requesting SCSI sense data";
- periph->flags |= CAM_PERIPH_SENSE_INPROG;
- /*
- * Send a Request Sense to the device. We
- * assume that we are in a contingent allegiance
- * condition so we do not tag this request.
- */
- scsi_request_sense(&ccb->csio, /*retries*/1,
- camperiphsensedone,
- &orig_ccb->csio.sense_data,
- orig_ccb->csio.sense_len,
- CAM_TAG_ACTION_NONE,
- /*sense_len*/SSD_FULL_SIZE,
- /*timeout*/5000);
- break;
- }
default:
panic("Unhandled error action %x", err_action);
}
@@ -1729,14 +1569,12 @@
ccb->ccb_h.pinfo.priority--;
ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
ccb->ccb_h.saved_ccb_ptr = orig_ccb;
- ccb->ccb_h.recovery_depth = 0;
error = ERESTART;
+ *orig = orig_ccb;
}
sense_error_done:
- if ((err_action & SSQ_PRINT_SENSE) != 0
- && (ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)
- cam_error_print(orig_ccb, CAM_ESF_ALL, CAM_EPF_ALL);
+ *print = ((err_action & SSQ_PRINT_SENSE) != 0);
}
return (error);
}
@@ -1750,87 +1588,35 @@
cam_periph_error(union ccb *ccb, cam_flags camflags,
u_int32_t sense_flags, union ccb *save_ccb)
{
+ union ccb *orig_ccb;
struct cam_periph *periph;
const char *action_string;
cam_status status;
- int frozen;
- int error, printed = 0;
- int openings;
- u_int32_t relsim_flags;
- u_int32_t timeout = 0;
+ int frozen, error, openings, print, lost_device;
+ u_int32_t relsim_flags, timeout;
+ print = 1;
periph = xpt_path_periph(ccb->ccb_h.path);
action_string = NULL;
status = ccb->ccb_h.status;
frozen = (status & CAM_DEV_QFRZN) != 0;
status &= CAM_STATUS_MASK;
- openings = relsim_flags = 0;
+ openings = relsim_flags = timeout = lost_device = 0;
+ orig_ccb = ccb;
switch (status) {
case CAM_REQ_CMP:
error = 0;
+ print = 0;
break;
case CAM_SCSI_STATUS_ERROR:
- error = camperiphscsistatuserror(ccb,
- camflags,
- sense_flags,
- &openings,
- &relsim_flags,
- &timeout,
- &action_string);
+ error = camperiphscsistatuserror(ccb, &orig_ccb,
+ camflags, sense_flags, &openings, &relsim_flags,
+ &timeout, &print, &action_string);
break;
case CAM_AUTOSENSE_FAIL:
- xpt_print(ccb->ccb_h.path, "AutoSense failed\n");
error = EIO; /* we have to kill the command */
break;
- case CAM_ATA_STATUS_ERROR:
- if (bootverbose && printed == 0) {
- xpt_print(ccb->ccb_h.path, "ATA status error\n");
- cam_error_print(ccb, CAM_ESF_ALL, CAM_EPF_ALL);
- printed++;
- }
- /* FALLTHROUGH */
- case CAM_REQ_CMP_ERR:
- if (bootverbose && printed == 0) {
- xpt_print(ccb->ccb_h.path,
- "Request completed with CAM_REQ_CMP_ERR\n");
- printed++;
- }
- /* FALLTHROUGH */
- case CAM_CMD_TIMEOUT:
- if (bootverbose && printed == 0) {
- xpt_print(ccb->ccb_h.path, "Command timed out\n");
- printed++;
- }
- /* FALLTHROUGH */
- case CAM_UNEXP_BUSFREE:
- if (bootverbose && printed == 0) {
- xpt_print(ccb->ccb_h.path, "Unexpected Bus Free\n");
- printed++;
- }
- /* FALLTHROUGH */
- case CAM_UNCOR_PARITY:
- if (bootverbose && printed == 0) {
- xpt_print(ccb->ccb_h.path,
- "Uncorrected parity error\n");
- printed++;
- }
- /* FALLTHROUGH */
- case CAM_DATA_RUN_ERR:
- if (bootverbose && printed == 0) {
- xpt_print(ccb->ccb_h.path, "Data overrun\n");
- printed++;
- }
- /* decrement the number of retries */
- if (ccb->ccb_h.retry_count > 0 &&
- (periph->flags & CAM_PERIPH_INVALID) == 0) {
- ccb->ccb_h.retry_count--;
- error = ERESTART;
- } else {
- action_string = "Retries exhausted";
- error = EIO;
- }
- break;
case CAM_UA_ABORT:
case CAM_UA_TERMIO:
case CAM_MSG_REJECT_REC:
@@ -1841,14 +1627,8 @@
if ((camflags & CAM_RETRY_SELTO) != 0) {
if (ccb->ccb_h.retry_count > 0 &&
(periph->flags & CAM_PERIPH_INVALID) == 0) {
-
ccb->ccb_h.retry_count--;
error = ERESTART;
- if (bootverbose && printed == 0) {
- xpt_print(ccb->ccb_h.path,
- "Selection timeout\n");
- printed++;
- }
/*
* Wait a bit to give the device
@@ -1862,38 +1642,10 @@
}
/* FALLTHROUGH */
case CAM_DEV_NOT_THERE:
- {
- struct cam_path *newpath;
- lun_id_t lun_id;
-
error = ENXIO;
-
- /*
- * For a selection timeout, we consider all of the LUNs on
- * the target to be gone. If the status is CAM_DEV_NOT_THERE,
- * then we only get rid of the device(s) specified by the
- * path in the original CCB.
- */
- if (status == CAM_DEV_NOT_THERE)
- lun_id = xpt_path_lun_id(ccb->ccb_h.path);
- else
- lun_id = CAM_LUN_WILDCARD;
-
- /* Should we do more if we can't create the path?? */
- if (xpt_create_path(&newpath, periph,
- xpt_path_path_id(ccb->ccb_h.path),
- xpt_path_target_id(ccb->ccb_h.path),
- lun_id) != CAM_REQ_CMP)
- break;
-
- /*
- * Let peripheral drivers know that this device has gone
- * away.
- */
- xpt_async(AC_LOST_DEVICE, newpath, NULL);
- xpt_free_path(newpath);
+ print = 0;
+ lost_device = 1;
break;
- }
case CAM_REQ_INVALID:
case CAM_PATH_INVALID:
case CAM_NO_HBA:
@@ -1913,26 +1665,17 @@
* these events and should be unconditionally
* retried.
*/
- if (bootverbose && printed == 0) {
- xpt_print_path(ccb->ccb_h.path);
- if (status == CAM_BDR_SENT)
- printf("Bus Device Reset sent\n");
- else
- printf("Bus Reset issued\n");
- printed++;
- }
- /* FALLTHROUGH */
case CAM_REQUEUE_REQ:
- /* Unconditional requeue */
- if (bootverbose && printed == 0) {
- xpt_print(ccb->ccb_h.path, "Request requeued\n");
- printed++;
- }
- if ((periph->flags & CAM_PERIPH_INVALID) == 0)
+ /* Unconditional requeue if device is still there */
+ if (periph->flags & CAM_PERIPH_INVALID) {
+ action_string = "Periph was invalidated";
+ error = EIO;
+ } else if (sense_flags & SF_NO_RETRY) {
+ error = EIO;
+ action_string = "Retry was blocked";
+ } else {
error = ERESTART;
- else {
- action_string = "Retries exhausted";
- error = EIO;
+ print = 0;
}
break;
case CAM_RESRC_UNAVAIL:
@@ -1946,30 +1689,37 @@
}
relsim_flags = RELSIM_RELEASE_AFTER_TIMEOUT;
/* FALLTHROUGH */
+ case CAM_ATA_STATUS_ERROR:
+ case CAM_REQ_CMP_ERR:
+ case CAM_CMD_TIMEOUT:
+ case CAM_UNEXP_BUSFREE:
+ case CAM_UNCOR_PARITY:
+ case CAM_DATA_RUN_ERR:
default:
- /* decrement the number of retries */
- if (ccb->ccb_h.retry_count > 0 &&
- (periph->flags & CAM_PERIPH_INVALID) == 0) {
+ if (periph->flags & CAM_PERIPH_INVALID) {
+ error = EIO;
+ action_string = "Periph was invalidated";
+ } else if (ccb->ccb_h.retry_count == 0) {
+ error = EIO;
+ action_string = "Retries exhausted";
+ } else if (sense_flags & SF_NO_RETRY) {
+ error = EIO;
+ action_string = "Retry was blocked";
+ } else {
ccb->ccb_h.retry_count--;
error = ERESTART;
- if (bootverbose && printed == 0) {
- xpt_print(ccb->ccb_h.path, "CAM status 0x%x\n",
- status);
- printed++;
- }
- } else {
- error = EIO;
- action_string = "Retries exhausted";
}
break;
}
- /*
- * If we have and error and are booting verbosely, whine
- * *unless* this was a non-retryable selection timeout.
- */
- if (error != 0 && bootverbose &&
- !(status == CAM_SEL_TIMEOUT && (camflags & CAM_RETRY_SELTO) == 0)) {
+ if ((sense_flags & SF_PRINT_ALWAYS) ||
+ CAM_DEBUGGED(ccb->ccb_h.path, CAM_DEBUG_INFO))
+ print = 1;
+ else if (sense_flags & SF_NO_PRINT)
+ print = 0;
+ if (print)
+ cam_error_print(orig_ccb, CAM_ESF_ALL, CAM_EPF_ALL);
+ if (error != 0 && print) {
if (error != ERESTART) {
if (action_string == NULL)
action_string = "Unretryable error";
@@ -1981,6 +1731,36 @@
xpt_print(ccb->ccb_h.path, "Retrying command\n");
}
+ if (lost_device) {
+ struct cam_path *newpath;
+ lun_id_t lun_id;
+
+ /*
+ * For a selection timeout, we consider all of the LUNs on
+ * the target to be gone. If the status is CAM_DEV_NOT_THERE,
+ * then we only get rid of the device(s) specified by the
+ * path in the original CCB.
+ */
+ if (status == CAM_DEV_NOT_THERE)
+ lun_id = xpt_path_lun_id(ccb->ccb_h.path);
+ else
+ lun_id = CAM_LUN_WILDCARD;
+
+ /* Should we do more if we can't create the path?? */
+ if (xpt_create_path(&newpath, periph,
+ xpt_path_path_id(ccb->ccb_h.path),
+ xpt_path_target_id(ccb->ccb_h.path),
+ lun_id) == CAM_REQ_CMP) {
+
+ /*
+ * Let peripheral drivers know that this
+ * device has gone away.
+ */
+ xpt_async(AC_LOST_DEVICE, newpath, NULL);
+ xpt_free_path(newpath);
+ }
+ }
+
/* Attempt a retry */
if (error == ERESTART || error == 0) {
if (frozen != 0)
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/cam_periph.h
--- a/head/sys/cam/cam_periph.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/cam_periph.h Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/cam/cam_periph.h 230000 2012-01-12 00:41:48Z ken $
+ * $FreeBSD: head/sys/cam/cam_periph.h 236814 2012-06-09 13:07:44Z mav $
*/
#ifndef _CAM_CAM_PERIPH_H
@@ -118,7 +118,6 @@
#define CAM_PERIPH_INVALID 0x08
#define CAM_PERIPH_NEW_DEV_FOUND 0x10
#define CAM_PERIPH_RECOVERY_INPROG 0x20
-#define CAM_PERIPH_SENSE_INPROG 0x40
#define CAM_PERIPH_FREE 0x80
u_int32_t immediate_priority;
u_int32_t refcount;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/cam_sim.h
--- a/head/sys/cam/cam_sim.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/cam_sim.h Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/cam/cam_sim.h 227637 2011-11-17 21:07:56Z mav $
+ * $FreeBSD: head/sys/cam/cam_sim.h 235333 2012-05-12 13:55:36Z mav $
*/
#ifndef _CAM_CAM_SIM_H
@@ -106,6 +106,7 @@
#define CAM_SIM_MPSAFE 0x02
#define CAM_SIM_ON_DONEQ 0x04
#define CAM_SIM_POLLED 0x08
+#define CAM_SIM_BATCH 0x10
struct callout callout;
struct cam_devq *devq; /* Device Queue to use for this SIM */
int refcount; /* References to the SIM. */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/cam_xpt.c
--- a/head/sys/cam/cam_xpt.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/cam_xpt.c Wed Jul 25 16:45:04 2012 +0300
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/cam_xpt.c 230590 2012-01-26 18:09:28Z ken $");
+__FBSDID("$FreeBSD: head/sys/cam/cam_xpt.c 237398 2012-06-21 14:35:46Z mav $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -188,21 +188,15 @@
};
/* Storage for debugging datastructures */
-#ifdef CAMDEBUG
struct cam_path *cam_dpath;
-#ifdef CAM_DEBUG_FLAGS
u_int32_t cam_dflags = CAM_DEBUG_FLAGS;
-#else
-u_int32_t cam_dflags = CAM_DEBUG_NONE;
-#endif
TUNABLE_INT("kern.cam.dflags", &cam_dflags);
SYSCTL_UINT(_kern_cam, OID_AUTO, dflags, CTLFLAG_RW,
- &cam_dflags, 0, "Cam Debug Flags");
-u_int32_t cam_debug_delay;
+ &cam_dflags, 0, "Enabled debug flags");
+u_int32_t cam_debug_delay = CAM_DEBUG_DELAY;
TUNABLE_INT("kern.cam.debug_delay", &cam_debug_delay);
SYSCTL_UINT(_kern_cam, OID_AUTO, debug_delay, CTLFLAG_RW,
- &cam_debug_delay, 0, "Cam Debug Flags");
-#endif
+ &cam_debug_delay, 0, "Delay in us after each debug message");
/* Our boot-time initialization hook */
static int cam_module_event_handler(module_t, int /*modeventtype_t*/, void *);
@@ -1032,7 +1026,7 @@
}
void
-xpt_remove_periph(struct cam_periph *periph)
+xpt_remove_periph(struct cam_periph *periph, int topology_lock_held)
{
struct cam_ed *device;
@@ -1053,9 +1047,13 @@
SLIST_REMOVE(periph_head, periph, cam_periph, periph_links);
}
- mtx_lock(&xsoftc.xpt_topo_lock);
+ if (topology_lock_held == 0)
+ mtx_lock(&xsoftc.xpt_topo_lock);
+
xsoftc.xpt_generation++;
- mtx_unlock(&xsoftc.xpt_topo_lock);
+
+ if (topology_lock_held == 0)
+ mtx_unlock(&xsoftc.xpt_topo_lock);
}
@@ -1080,6 +1078,9 @@
else if (path->device->protocol == PROTO_ATA ||
path->device->protocol == PROTO_SATAPM)
ata_print_ident(&path->device->ident_data);
+ else if (path->device->protocol == PROTO_SEMB)
+ semb_print_ident(
+ (struct sep_identify_data *)&path->device->ident_data);
else
printf("Unknown protocol device\n");
if (bootverbose && path->device->serial_num_len > 0) {
@@ -2469,9 +2470,7 @@
void
xpt_action_default(union ccb *start_ccb)
{
-#ifdef CAMDEBUG
char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1];
-#endif
struct cam_path *path;
path = start_ccb->ccb_h.path;
@@ -2902,17 +2901,13 @@
if ((crs->release_flags & RELSIM_ADJUST_OPENINGS) != 0) {
- if (INQ_DATA_TQ_ENABLED(&dev->inq_data)) {
- /* Don't ever go below one opening */
- if (crs->openings > 0) {
- xpt_dev_ccbq_resize(path,
- crs->openings);
-
- if (bootverbose) {
- xpt_print(path,
- "tagged openings now %d\n",
- crs->openings);
- }
+ /* Don't ever go below one opening */
+ if (crs->openings > 0) {
+ xpt_dev_ccbq_resize(path, crs->openings);
+ if (bootverbose) {
+ xpt_print(path,
+ "number of openings is now %d\n",
+ crs->openings);
}
}
}
@@ -2981,16 +2976,17 @@
break;
}
case XPT_DEBUG: {
-#ifdef CAMDEBUG
-#ifdef CAM_DEBUG_DELAY
- cam_debug_delay = CAM_DEBUG_DELAY;
-#endif
+ /* Check that all request bits are supported. */
+ if (start_ccb->cdbg.flags & ~(CAM_DEBUG_COMPILE)) {
+ start_ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
+ break;
+ }
+
cam_dflags = start_ccb->cdbg.flags;
if (cam_dpath != NULL) {
xpt_free_path(cam_dpath);
cam_dpath = NULL;
}
-
if (cam_dflags != CAM_DEBUG_NONE) {
if (xpt_create_path(&cam_dpath, xpt_periph,
start_ccb->ccb_h.path_id,
@@ -3008,9 +3004,6 @@
cam_dpath = NULL;
start_ccb->ccb_h.status = CAM_REQ_CMP;
}
-#else /* !CAMDEBUG */
- start_ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
-#endif /* CAMDEBUG */
break;
}
case XPT_FREEZE_QUEUE:
@@ -3227,13 +3220,8 @@
("running device %p\n", device));
drvq = &device->drvq;
-
-#ifdef CAMDEBUG
- if (drvq->entries <= 0) {
- panic("xpt_run_dev_allocq: "
- "Device on queue without any work to do");
- }
-#endif
+ KASSERT(drvq->entries > 0, ("xpt_run_dev_allocq: "
+ "Device on queue without any work to do"));
if ((work_ccb = xpt_get_ccb(device)) != NULL) {
devq->alloc_openings--;
devq->alloc_active++;
@@ -4049,6 +4037,28 @@
return (pathid);
}
+static const char *
+xpt_async_string(u_int32_t async_code)
+{
+
+ switch (async_code) {
+ case AC_BUS_RESET: return ("AC_BUS_RESET");
+ case AC_UNSOL_RESEL: return ("AC_UNSOL_RESEL");
+ case AC_SCSI_AEN: return ("AC_SCSI_AEN");
+ case AC_SENT_BDR: return ("AC_SENT_BDR");
+ case AC_PATH_REGISTERED: return ("AC_PATH_REGISTERED");
+ case AC_PATH_DEREGISTERED: return ("AC_PATH_DEREGISTERED");
+ case AC_FOUND_DEVICE: return ("AC_FOUND_DEVICE");
+ case AC_LOST_DEVICE: return ("AC_LOST_DEVICE");
+ case AC_TRANSFER_NEG: return ("AC_TRANSFER_NEG");
+ case AC_INQ_CHANGED: return ("AC_INQ_CHANGED");
+ case AC_GETDEV_CHANGED: return ("AC_GETDEV_CHANGED");
+ case AC_CONTRACT: return ("AC_CONTRACT");
+ case AC_ADVINFO_CHANGED: return ("AC_ADVINFO_CHANGED");
+ }
+ return ("AC_UNKNOWN");
+}
+
void
xpt_async(u_int32_t async_code, struct cam_path *path, void *async_arg)
{
@@ -4057,8 +4067,8 @@
struct cam_ed *device, *next_device;
mtx_assert(path->bus->sim->mtx, MA_OWNED);
-
- CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_async\n"));
+ CAM_DEBUG(path, CAM_DEBUG_TRACE | CAM_DEBUG_INFO,
+ ("xpt_async(%s)\n", xpt_async_string(async_code)));
/*
* Most async events come from a CAM interrupt context. In
@@ -4332,7 +4342,8 @@
TAILQ_INSERT_TAIL(&sim->sim_doneq, &done_ccb->ccb_h,
sim_links.tqe);
done_ccb->ccb_h.pinfo.index = CAM_DONEQ_INDEX;
- if ((sim->flags & (CAM_SIM_ON_DONEQ | CAM_SIM_POLLED)) == 0) {
+ if ((sim->flags & (CAM_SIM_ON_DONEQ | CAM_SIM_POLLED |
+ CAM_SIM_BATCH)) == 0) {
mtx_lock(&cam_simq_lock);
first = TAILQ_EMPTY(&cam_simq);
TAILQ_INSERT_TAIL(&cam_simq, sim, links);
@@ -4344,6 +4355,25 @@
}
}
+void
+xpt_batch_start(struct cam_sim *sim)
+{
+
+ KASSERT((sim->flags & CAM_SIM_BATCH) == 0, ("Batch flag already set"));
+ sim->flags |= CAM_SIM_BATCH;
+}
+
+void
+xpt_batch_done(struct cam_sim *sim)
+{
+
+ KASSERT((sim->flags & CAM_SIM_BATCH) != 0, ("Batch flag was not set"));
+ sim->flags &= ~CAM_SIM_BATCH;
+ if (!TAILQ_EMPTY(&sim->sim_doneq) &&
+ (sim->flags & CAM_SIM_ON_DONEQ) == 0)
+ camisr_runqueue(&sim->sim_doneq);
+}
+
union ccb *
xpt_alloc_ccb()
{
@@ -4696,6 +4726,7 @@
newopenings = min(device->maxtags,
sim->max_tagged_dev_openings);
xpt_dev_ccbq_resize(path, newopenings);
+ xpt_async(AC_GETDEV_CHANGED, path, NULL);
xpt_setup_ccb(&crs.ccb_h, path, CAM_PRIORITY_NORMAL);
crs.ccb_h.func_code = XPT_REL_SIMQ;
crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY;
@@ -4720,6 +4751,7 @@
xpt_freeze_devq(path, /*count*/1);
device->inq_flags &= ~SID_CmdQue;
xpt_dev_ccbq_resize(path, sim->max_dev_openings);
+ xpt_async(AC_GETDEV_CHANGED, path, NULL);
xpt_setup_ccb(&crs.ccb_h, path, CAM_PRIORITY_NORMAL);
crs.ccb_h.func_code = XPT_REL_SIMQ;
crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY;
@@ -4744,9 +4776,7 @@
* Now that interrupts are enabled, go find our devices
*/
-#ifdef CAMDEBUG
- /* Setup debugging flags and path */
-#ifdef CAM_DEBUG_BUS
+ /* Setup debugging path */
if (cam_dflags != CAM_DEBUG_NONE) {
/*
* Locking is specifically omitted here. No SIMs have
@@ -4763,10 +4793,6 @@
}
} else
cam_dpath = NULL;
-#else /* !CAM_DEBUG_BUS */
- cam_dpath = NULL;
-#endif /* CAM_DEBUG_BUS */
-#endif /* CAMDEBUG */
periphdriver_init(1);
xpt_hold_boot();
@@ -4839,7 +4865,8 @@
* attached. For any devices like that, announce the
* passthrough driver so the user will see something.
*/
- xpt_for_all_devices(xptpassannouncefunc, NULL);
+ if (!bootverbose)
+ xpt_for_all_devices(xptpassannouncefunc, NULL);
/* Release our hook so that the boot can continue. */
config_intrhook_disestablish(xsoftc.xpt_config_hook);
@@ -4978,8 +5005,8 @@
while ((sim = TAILQ_FIRST(&queue)) != NULL) {
TAILQ_REMOVE(&queue, sim, links);
CAM_SIM_LOCK(sim);
+ camisr_runqueue(&sim->sim_doneq);
sim->flags &= ~CAM_SIM_ON_DONEQ;
- camisr_runqueue(&sim->sim_doneq);
CAM_SIM_UNLOCK(sim);
}
mtx_lock(&cam_simq_lock);
@@ -5042,10 +5069,16 @@
ccb_h->path->bus->sim->devq->send_openings++;
runq = TRUE;
+ if (((dev->flags & CAM_DEV_REL_ON_QUEUE_EMPTY) != 0
+ && (dev->ccbq.dev_active == 0))) {
+ dev->flags &= ~CAM_DEV_REL_ON_QUEUE_EMPTY;
+ xpt_release_devq(ccb_h->path, /*count*/1,
+ /*run_queue*/FALSE);
+ }
+
if (((dev->flags & CAM_DEV_REL_ON_COMPLETE) != 0
- && (ccb_h->status&CAM_STATUS_MASK) != CAM_REQUEUE_REQ)
- || ((dev->flags & CAM_DEV_REL_ON_QUEUE_EMPTY) != 0
- && (dev->ccbq.dev_active == 0))) {
+ && (ccb_h->status&CAM_STATUS_MASK) != CAM_REQUEUE_REQ)) {
+ dev->flags &= ~CAM_DEV_REL_ON_COMPLETE;
xpt_release_devq(ccb_h->path, /*count*/1,
/*run_queue*/FALSE);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/cam_xpt.h
--- a/head/sys/cam/cam_xpt.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/cam_xpt.h Wed Jul 25 16:45:04 2012 +0300
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/cam/cam_xpt.h 224806 2011-08-12 20:09:38Z mjacob $
+ * $FreeBSD: head/sys/cam/cam_xpt.h 236712 2012-06-07 10:05:51Z mav $
*/
#ifndef _CAM_CAM_XPT_H
@@ -63,28 +63,6 @@
SLIST_HEAD(async_list, async_node);
SLIST_HEAD(periph_list, cam_periph);
-#if defined(CAM_DEBUG_FLAGS) && !defined(CAMDEBUG)
-#error "You must have options CAMDEBUG to use options CAM_DEBUG_FLAGS"
-#endif
-
-/*
- * In order to enable the CAM_DEBUG_* options, the user must have CAMDEBUG
- * enabled. Also, the user must have either none, or all of CAM_DEBUG_BUS,
- * CAM_DEBUG_TARGET, and CAM_DEBUG_LUN specified.
- */
-#if defined(CAM_DEBUG_BUS) || defined(CAM_DEBUG_TARGET) \
- || defined(CAM_DEBUG_LUN)
-#ifdef CAMDEBUG
-#if !defined(CAM_DEBUG_BUS) || !defined(CAM_DEBUG_TARGET) \
- || !defined(CAM_DEBUG_LUN)
-#error "You must define all or none of CAM_DEBUG_BUS, CAM_DEBUG_TARGET \
- and CAM_DEBUG_LUN"
-#endif /* !CAM_DEBUG_BUS || !CAM_DEBUG_TARGET || !CAM_DEBUG_LUN */
-#else /* !CAMDEBUG */
-#error "You must use options CAMDEBUG if you use the CAM_DEBUG_* options"
-#endif /* CAMDEBUG */
-#endif /* CAM_DEBUG_BUS || CAM_DEBUG_TARGET || CAM_DEBUG_LUN */
-
void xpt_action(union ccb *new_ccb);
void xpt_action_default(union ccb *new_ccb);
union ccb *xpt_alloc_ccb(void);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/cam_xpt_periph.h
--- a/head/sys/cam/cam_xpt_periph.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/cam_xpt_periph.h Wed Jul 25 16:45:04 2012 +0300
@@ -27,7 +27,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/cam/cam_xpt_periph.h 237328 2012-06-20 17:08:00Z ken $
*/
#ifndef _CAM_CAM_XPT_PERIPH_H
@@ -42,7 +42,8 @@
void xpt_release_ccb(union ccb *released_ccb);
void xpt_schedule(struct cam_periph *perph, u_int32_t new_priority);
int32_t xpt_add_periph(struct cam_periph *periph);
-void xpt_remove_periph(struct cam_periph *periph);
+void xpt_remove_periph(struct cam_periph *periph,
+ int topology_lock_held);
void xpt_announce_periph(struct cam_periph *periph,
char *announce_string);
#endif
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/cam_xpt_sim.h
--- a/head/sys/cam/cam_xpt_sim.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/cam_xpt_sim.h Wed Jul 25 16:45:04 2012 +0300
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/cam/cam_xpt_sim.h 235333 2012-05-12 13:55:36Z mav $
*/
#ifndef _CAM_CAM_XPT_SIM_H
@@ -51,6 +51,8 @@
u_int count, int run_queue);
int xpt_sim_opened(struct cam_sim *sim);
void xpt_done(union ccb *done_ccb);
+void xpt_batch_start(struct cam_sim *sim);
+void xpt_batch_done(struct cam_sim *sim);
#endif
#endif /* _CAM_CAM_XPT_SIM_H */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/ctl/ctl.c
--- a/head/sys/cam/ctl/ctl.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/ctl/ctl.c Wed Jul 25 16:45:04 2012 +0300
@@ -42,7 +42,7 @@
#define _CTL_C
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl.c 233963 2012-04-06 22:23:13Z ken $");
+__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl.c 237726 2012-06-28 19:39:30Z ken $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -308,7 +308,6 @@
/*aen_holdoff_period*/{0, 0}
};
-SYSCTL_NODE(_kern_cam, OID_AUTO, ctl, CTLFLAG_RD, 0, "CAM Target Layer");
/*
* XXX KDM move these into the softc.
@@ -318,7 +317,12 @@
static uint8_t ctl_pause_rtr;
static int ctl_is_single;
static int index_to_aps_page;
-
+int ctl_disable = 0;
+
+SYSCTL_NODE(_kern_cam, OID_AUTO, ctl, CTLFLAG_RD, 0, "CAM Target Layer");
+SYSCTL_INT(_kern_cam_ctl, OID_AUTO, disable, CTLFLAG_RDTUN, &ctl_disable, 0,
+ "Disable CTL");
+TUNABLE_INT("kern.cam.ctl.disable", &ctl_disable);
/*
* Serial number (0x80), device id (0x83), and supported pages (0x00)
@@ -949,6 +953,10 @@
ctl_pause_rtr = 0;
rcv_sync_msg = 0;
+ /* If we're disabled, don't initialize. */
+ if (ctl_disable != 0)
+ return;
+
control_softc = malloc(sizeof(*control_softc), M_DEVBUF, M_WAITOK);
softc = control_softc;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/ctl/ctl_backend.c
--- a/head/sys/cam/ctl/ctl_backend.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/ctl/ctl_backend.c Wed Jul 25 16:45:04 2012 +0300
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_backend.c 233963 2012-04-06 22:23:13Z ken $");
+__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_backend.c 237726 2012-06-28 19:39:30Z ken $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -62,6 +62,7 @@
#include <cam/ctl/ctl_debug.h>
extern struct ctl_softc *control_softc;
+extern int ctl_disable;
int
ctl_backend_register(struct ctl_backend_driver *be)
@@ -71,6 +72,10 @@
ctl_softc = control_softc;
+ /* Don't continue if CTL is disabled */
+ if (ctl_disable != 0)
+ return (0);
+
mtx_lock(&ctl_softc->ctl_lock);
/*
* Sanity check, make sure this isn't a duplicate registration.
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/ctl/ctl_frontend_cam_sim.c
--- a/head/sys/cam/ctl/ctl_frontend_cam_sim.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/ctl/ctl_frontend_cam_sim.c Wed Jul 25 16:45:04 2012 +0300
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_frontend_cam_sim.c 231092 2012-02-06 18:11:00Z emaste $");
+__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_frontend_cam_sim.c 237726 2012-06-28 19:39:30Z ken $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -119,6 +119,7 @@
* amount of SCSI sense data that we will report to CAM.
*/
static int cfcs_max_sense = sizeof(struct scsi_sense_data);
+extern int ctl_disable;
SYSINIT(cfcs_init, SI_SUB_CONFIGURE, SI_ORDER_FOURTH, cfcs_init, NULL);
SYSCTL_NODE(_kern_cam, OID_AUTO, ctl2cam, CTLFLAG_RD, 0,
@@ -138,6 +139,10 @@
#endif
int retval;
+ /* Don't continue if CTL is disabled */
+ if (ctl_disable != 0)
+ return (0);
+
softc = &cfcs_softc;
retval = 0;
bzero(softc, sizeof(*softc));
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/ctl/ctl_frontend_internal.c
--- a/head/sys/cam/ctl/ctl_frontend_internal.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/ctl/ctl_frontend_internal.c Wed Jul 25 16:45:04 2012 +0300
@@ -48,7 +48,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_frontend_internal.c 233963 2012-04-06 22:23:13Z ken $");
+__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_frontend_internal.c 237726 2012-06-28 19:39:30Z ken $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -187,6 +187,7 @@
MALLOC_DEFINE(M_CTL_CFI, "ctlcfi", "CTL CFI");
static struct cfi_softc fetd_internal_softc;
+extern int ctl_disable;
void cfi_init(void);
void cfi_shutdown(void) __unused;
@@ -231,6 +232,10 @@
retval = 0;
+ /* If we're disabled, don't initialize */
+ if (ctl_disable != 0)
+ return;
+
if (sizeof(struct cfi_lun_io) > CTL_PORT_PRIV_SIZE) {
printf("%s: size of struct cfi_lun_io %zd > "
"CTL_PORT_PRIV_SIZE %d\n", __func__,
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/ctl/scsi_ctl.c
--- a/head/sys/cam/ctl/scsi_ctl.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/ctl/scsi_ctl.c Wed Jul 25 16:45:04 2012 +0300
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/ctl/scsi_ctl.c 230033 2012-01-12 22:08:33Z ken $");
+__FBSDID("$FreeBSD: head/sys/cam/ctl/scsi_ctl.c 237726 2012-06-28 19:39:30Z ken $");
#include <sys/param.h>
#include <sys/queue.h>
@@ -227,12 +227,17 @@
PERIPHDRIVER_DECLARE(ctl, ctlfe_driver);
extern struct ctl_softc *control_softc;
+extern int ctl_disable;
int
ctlfeinitialize(void)
{
cam_status status;
+ /* Don't initialize if we're disabled */
+ if (ctl_disable != 0)
+ return (0);
+
STAILQ_INIT(&ctlfe_softc_list);
mtx_init(&ctlfe_list_mtx, ctlfe_mtx_desc, NULL, MTX_DEF);
@@ -263,6 +268,10 @@
{
cam_status status;
+ /* Don't initialize if we're disabled */
+ if (ctl_disable != 0)
+ return;
+
STAILQ_INIT(&ctlfe_softc_list);
mtx_init(&ctlfe_list_mtx, ctlfe_mtx_desc, NULL, MTX_DEF);
@@ -490,7 +499,7 @@
dev_chg = (struct ac_device_changed *)ac->contract_data;
- printf("%s: WWPN %#jx port %u path %u target %u %s\n",
+ printf("%s: WWPN %#jx port 0x%06x path %u target %u %s\n",
__func__, dev_chg->wwpn, dev_chg->port,
xpt_path_path_id(path), dev_chg->target,
(dev_chg->arrived == 0) ? "left" : "arrived");
@@ -558,7 +567,6 @@
TAILQ_INIT(&softc->work_queue);
softc->periph = periph;
- softc->parent_softc = bus_softc;
callout_init_mtx(&softc->dma_callout, sim->mtx, /*flags*/ 0);
periph->softc = softc;
@@ -582,7 +590,7 @@
union ccb *new_ccb;
new_ccb = (union ccb *)malloc(sizeof(*new_ccb), M_CTLFE,
- M_NOWAIT);
+ M_ZERO|M_NOWAIT);
if (new_ccb == NULL) {
status = CAM_RESRC_UNAVAIL;
break;
@@ -616,7 +624,7 @@
union ccb *new_ccb;
new_ccb = (union ccb *)malloc(sizeof(*new_ccb), M_CTLFE,
- M_NOWAIT);
+ M_ZERO|M_NOWAIT);
if (new_ccb == NULL) {
status = CAM_RESRC_UNAVAIL;
break;
@@ -628,12 +636,22 @@
xpt_action(new_ccb);
softc->inots_sent++;
status = new_ccb->ccb_h.status;
- if (status != CAM_REQ_INPROG) {
- free(new_ccb, M_CTLFE);
+ if ((status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
+ /*
+ * Note that we don't free the CCB here. If the
+ * status is not CAM_REQ_INPROG, then we're
+ * probably talking to a SIM that says it is
+ * target-capable but doesn't support the
+ * XPT_IMMEDIATE_NOTIFY CCB. i.e. it supports the
+ * older API. In that case, it'll call xpt_done()
+ * on the CCB, and we need to free it in our done
+ * routine as a result.
+ */
break;
}
}
- if (i == 0) {
+ if ((i == 0)
+ || (status != CAM_REQ_INPROG)) {
xpt_print(periph->path, "%s: could not allocate immediate "
"notify CCBs, status 0x%x\n", __func__, status);
return (CAM_REQ_CMP_ERR);
@@ -1460,12 +1478,29 @@
*/
send_ctl_io = 0;
break;
+ case CAM_REQ_INVALID:
+ case CAM_PROVIDE_FAIL:
default:
- xpt_print(periph->path, "%s: "
- "unsupported CAM status 0x%x\n",
- __func__, status);
- send_ctl_io = 0;
- break;
+ /*
+ * We should only get here if we're talking
+ * to a talking to a SIM that is target
+ * capable but supports the old API. In
+ * that case, we need to just free the CCB.
+ * If we actually send a notify acknowledge,
+ * it will send that back with an error as
+ * well.
+ */
+
+ if ((status != CAM_REQ_INVALID)
+ && (status != CAM_PROVIDE_FAIL))
+ xpt_print(periph->path, "%s: "
+ "unsupported CAM status "
+ "0x%x\n", __func__, status);
+
+ ctl_free_io(io);
+ ctlfe_free_ccb(periph, done_ccb);
+
+ return;
}
if (send_ctl_io != 0) {
ctl_queue(io);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_all.c
--- a/head/sys/cam/scsi/scsi_all.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/scsi/scsi_all.c Wed Jul 25 16:45:04 2012 +0300
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_all.c 230590 2012-01-26 18:09:28Z ken $");
+__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_all.c 238596 2012-07-18 12:41:09Z mav $");
#include <sys/param.h>
#include <sys/types.h>
@@ -768,7 +768,7 @@
*
* SCSI ASC/ASCQ Assignments
* Numeric Sorted Listing
- * as of 7/29/08
+ * as of 5/20/12
*
* D - DIRECT ACCESS DEVICE (SBC-2) device column key
* .T - SEQUENTIAL ACCESS DEVICE (SSC) -------------------
@@ -854,6 +854,12 @@
/* DT R MAEBKV */
{ SST(0x00, 0x1E, SS_RDEF, /* XXX TBD */
"Conflicting SA creation request") },
+ /* DT B */
+ { SST(0x00, 0x1F, SS_RDEF, /* XXX TBD */
+ "Logical unit transitioning to another power condition") },
+ /* DT P B */
+ { SST(0x00, 0x20, SS_RDEF, /* XXX TBD */
+ "Extended copy information available") },
/* D W O BK */
{ SST(0x01, 0x00, SS_RDEF,
"No index/sector signal") },
@@ -923,6 +929,33 @@
/* DT R MAEBKV */
{ SST(0x04, 0x13, SS_RDEF, /* XXX TBD */
"Logical unit not ready, SA creation in progress") },
+ /* D B */
+ { SST(0x04, 0x14, SS_RDEF, /* XXX TBD */
+ "Logical unit not ready, space allocation in progress") },
+ /* M */
+ { SST(0x04, 0x15, SS_RDEF, /* XXX TBD */
+ "Logical unit not ready, robotics disabled") },
+ /* M */
+ { SST(0x04, 0x16, SS_RDEF, /* XXX TBD */
+ "Logical unit not ready, configuration required") },
+ /* M */
+ { SST(0x04, 0x17, SS_RDEF, /* XXX TBD */
+ "Logical unit not ready, calibration required") },
+ /* M */
+ { SST(0x04, 0x18, SS_RDEF, /* XXX TBD */
+ "Logical unit not ready, a door is open") },
+ /* M */
+ { SST(0x04, 0x19, SS_RDEF, /* XXX TBD */
+ "Logical unit not ready, operating in sequential mode") },
+ /* DT B */
+ { SST(0x04, 0x1A, SS_RDEF, /* XXX TBD */
+ "Logical unit not ready, START/STOP UNIT command in progress") },
+ /* D B */
+ { SST(0x04, 0x1B, SS_RDEF, /* XXX TBD */
+ "Logical unit not ready, sanitize in progress") },
+ /* DT MAEB */
+ { SST(0x04, 0x1C, SS_RDEF, /* XXX TBD */
+ "Logical unit not ready, additional power use not yet granted") },
/* DTL WROMAEBKVF */
{ SST(0x05, 0x00, SS_RDEF,
"Logical unit does not respond to selection") },
@@ -989,6 +1022,12 @@
/* DTLPWROMAEBKVF */
{ SST(0x0B, 0x07, SS_RDEF, /* XXX TBD */
"Warning - degraded power to non-volatile cache") },
+ /* DTLPWROMAEBKVF */
+ { SST(0x0B, 0x08, SS_RDEF, /* XXX TBD */
+ "Warning - power loss expected") },
+ /* D */
+ { SST(0x0B, 0x09, SS_RDEF, /* XXX TBD */
+ "Warning - device statistics notification available") },
/* T R */
{ SST(0x0C, 0x00, SS_RDEF,
"Write error") },
@@ -1031,6 +1070,9 @@
/* DTLPWRO AEBKVF */
{ SST(0x0C, 0x0D, SS_RDEF, /* XXX TBD */
"Write error - not enough unsolicited data") },
+ /* DT W O BK */
+ { SST(0x0C, 0x0E, SS_RDEF, /* XXX TBD */
+ "Multiple write errors") },
/* R */
{ SST(0x0C, 0x0F, SS_RDEF, /* XXX TBD */
"Defects in error window") },
@@ -1076,6 +1118,12 @@
/* DT W O */
{ SST(0x10, 0x03, SS_RDEF, /* XXX TBD */
"Logical block reference tag check failed") },
+ /* T */
+ { SST(0x10, 0x04, SS_RDEF, /* XXX TBD */
+ "Logical block protection error on recovered buffer data") },
+ /* T */
+ { SST(0x10, 0x05, SS_RDEF, /* XXX TBD */
+ "Logical block protection method error") },
/* DT WRO BK */
{ SST(0x11, 0x00, SS_FATAL|EIO,
"Unrecovered read error") },
@@ -1280,6 +1328,9 @@
/* DT WRO BK */
{ SST(0x1D, 0x00, SS_FATAL,
"Miscompare during verify operation") },
+ /* D B */
+ { SST(0x1D, 0x01, SS_RDEF, /* XXX TBD */
+ "Miscomparable verify of unmapped LBA") },
/* D W O BK */
{ SST(0x1E, 0x00, SS_NOP | SSQ_PRINT_SENSE,
"Recovered ID with ECC correction") },
@@ -1322,6 +1373,9 @@
/* DT PWROMAEBK */
{ SST(0x20, 0x0B, SS_RDEF, /* XXX TBD */
"Access denied - ACL LUN conflict") },
+ /* T */
+ { SST(0x20, 0x0C, SS_FATAL | EINVAL,
+ "Illegal command when not in append-only mode") },
/* DT WRO BK */
{ SST(0x21, 0x00, SS_FATAL | EINVAL,
"Logical block address out of range") },
@@ -1337,6 +1391,39 @@
/* D */
{ SST(0x22, 0x00, SS_FATAL | EINVAL,
"Illegal function (use 20 00, 24 00, or 26 00)") },
+ /* DT P B */
+ { SST(0x23, 0x00, SS_RDEF, /* XXX TBD */
+ "Invalid token operation, cause not reportable") },
+ /* DT P B */
+ { SST(0x23, 0x01, SS_RDEF, /* XXX TBD */
+ "Invalid token operation, unsupported token type") },
+ /* DT P B */
+ { SST(0x23, 0x02, SS_RDEF, /* XXX TBD */
+ "Invalid token operation, remote token usage not supported") },
+ /* DT P B */
+ { SST(0x23, 0x03, SS_RDEF, /* XXX TBD */
+ "Invalid token operation, remote ROD token creation not supported") },
+ /* DT P B */
+ { SST(0x23, 0x04, SS_RDEF, /* XXX TBD */
+ "Invalid token operation, token unknown") },
+ /* DT P B */
+ { SST(0x23, 0x05, SS_RDEF, /* XXX TBD */
+ "Invalid token operation, token corrupt") },
+ /* DT P B */
+ { SST(0x23, 0x06, SS_RDEF, /* XXX TBD */
+ "Invalid token operation, token revoked") },
+ /* DT P B */
+ { SST(0x23, 0x07, SS_RDEF, /* XXX TBD */
+ "Invalid token operation, token expired") },
+ /* DT P B */
+ { SST(0x23, 0x08, SS_RDEF, /* XXX TBD */
+ "Invalid token operation, token cancelled") },
+ /* DT P B */
+ { SST(0x23, 0x09, SS_RDEF, /* XXX TBD */
+ "Invalid token operation, token deleted") },
+ /* DT P B */
+ { SST(0x23, 0x0A, SS_RDEF, /* XXX TBD */
+ "Invalid token operation, invalid token length") },
/* DTLPWROMAEBKVF */
{ SST(0x24, 0x00, SS_FATAL | EINVAL,
"Invalid field in CDB") },
@@ -1445,6 +1532,9 @@
/* R F */
{ SST(0x27, 0x06, SS_RDEF, /* XXX TBD */
"Conditional write protect") },
+ /* D B */
+ { SST(0x27, 0x07, SS_RDEF, /* XXX TBD */
+ "Space allocation failed write protect") },
/* DTLPWROMAEBKVF */
{ SST(0x28, 0x00, SS_FATAL | ENXIO,
"Not ready to ready change, medium may have changed") },
@@ -1543,6 +1633,9 @@
/* DT R MAEBKV */
{ SST(0x2A, 0x14, SS_RDEF, /* XXX TBD */
"SA creation capabilities data has changed") },
+ /* T M V */
+ { SST(0x2A, 0x15, SS_RDEF, /* XXX TBD */
+ "Medium removal prevention preempted") },
/* DTLPWRO K */
{ SST(0x2B, 0x00, SS_RDEF,
"Copy cannot execute since host cannot disconnect") },
@@ -1582,6 +1675,9 @@
/* T */
{ SST(0x2C, 0x0B, SS_RDEF, /* XXX TBD */
"Not reserved") },
+ /* D */
+ { SST(0x2C, 0x0C, SS_RDEF, /* XXX TBD */
+ "ORWRITE generation does not match") },
/* T */
{ SST(0x2D, 0x00, SS_RDEF,
"Overwrite error on update in place") },
@@ -1645,6 +1741,9 @@
/* M */
{ SST(0x30, 0x12, SS_RDEF, /* XXX TBD */
"Incompatible volume qualifier") },
+ /* M */
+ { SST(0x30, 0x13, SS_RDEF, /* XXX TBD */
+ "Cleaning volume expired") },
/* DT WRO BK */
{ SST(0x31, 0x00, SS_RDEF,
"Medium format corrupted") },
@@ -1654,6 +1753,9 @@
/* R */
{ SST(0x31, 0x02, SS_RDEF, /* XXX TBD */
"Zoned formatting failed due to spare linking") },
+ /* D B */
+ { SST(0x31, 0x03, SS_RDEF, /* XXX TBD */
+ "SANITIZE command failed") },
/* D W O BK */
{ SST(0x32, 0x00, SS_RDEF,
"No defect spare location available") },
@@ -1702,6 +1804,9 @@
/* B */
{ SST(0x38, 0x06, SS_RDEF, /* XXX TBD */
"ESN - device busy class event") },
+ /* D */
+ { SST(0x38, 0x07, SS_RDEF, /* XXX TBD */
+ "Thin provisioning soft threshold reached") },
/* DTL WROMAE K */
{ SST(0x39, 0x00, SS_RDEF,
"Saving parameters not supported") },
@@ -1801,6 +1906,9 @@
/* M */
{ SST(0x3B, 0x1B, SS_RDEF, /* XXX TBD */
"Data transfer device inserted") },
+ /* T */
+ { SST(0x3B, 0x1C, SS_RDEF, /* XXX TBD */
+ "Too many logical objects on partition to support operation") },
/* DTLPWROMAE K */
{ SST(0x3D, 0x00, SS_RDEF,
"Invalid bits in IDENTIFY message") },
@@ -1904,6 +2012,9 @@
/* DTLPWROMAEBKVF */
{ SST(0x44, 0x00, SS_RDEF,
"Internal target failure") },
+ /* DT P MAEBKVF */
+ { SST(0x44, 0x01, SS_RDEF, /* XXX TBD */
+ "Persistent reservation information lost") },
/* DT B */
{ SST(0x44, 0x71, SS_RDEF, /* XXX TBD */
"ATA device failed set features") },
@@ -1967,6 +2078,27 @@
/* DT PWROMAEBK */
{ SST(0x4B, 0x06, SS_RDEF, /* XXX TBD */
"Initiator response timeout") },
+ /* DT PWROMAEBK F */
+ { SST(0x4B, 0x07, SS_RDEF, /* XXX TBD */
+ "Connection lost") },
+ /* DT PWROMAEBK F */
+ { SST(0x4B, 0x08, SS_RDEF, /* XXX TBD */
+ "Data-in buffer overflow - data buffer size") },
+ /* DT PWROMAEBK F */
+ { SST(0x4B, 0x09, SS_RDEF, /* XXX TBD */
+ "Data-in buffer overflow - data buffer descriptor area") },
+ /* DT PWROMAEBK F */
+ { SST(0x4B, 0x0A, SS_RDEF, /* XXX TBD */
+ "Data-in buffer error") },
+ /* DT PWROMAEBK F */
+ { SST(0x4B, 0x0B, SS_RDEF, /* XXX TBD */
+ "Data-out buffer overflow - data buffer size") },
+ /* DT PWROMAEBK F */
+ { SST(0x4B, 0x0C, SS_RDEF, /* XXX TBD */
+ "Data-out buffer overflow - data buffer descriptor area") },
+ /* DT PWROMAEBK F */
+ { SST(0x4B, 0x0D, SS_RDEF, /* XXX TBD */
+ "Data-out buffer error") },
/* DTLPWROMAEBKVF */
{ SST(0x4C, 0x00, SS_RDEF,
"Logical unit failed self-configuration") },
@@ -2012,6 +2144,18 @@
/* T */
{ SST(0x53, 0x04, SS_RDEF, /* XXX TBD */
"Medium thread or unthread failure") },
+ /* M */
+ { SST(0x53, 0x05, SS_RDEF, /* XXX TBD */
+ "Volume identifier invalid") },
+ /* T */
+ { SST(0x53, 0x06, SS_RDEF, /* XXX TBD */
+ "Volume identifier missing") },
+ /* M */
+ { SST(0x53, 0x07, SS_RDEF, /* XXX TBD */
+ "Duplicate volume identifier") },
+ /* M */
+ { SST(0x53, 0x08, SS_RDEF, /* XXX TBD */
+ "Element status unknown") },
/* P */
{ SST(0x54, 0x00, SS_RDEF,
"SCSI to host system interface failure") },
@@ -2048,6 +2192,15 @@
/* M */
{ SST(0x55, 0x0A, SS_RDEF, /* XXX TBD */
"Data currently unavailable") },
+ /* DTLPWROMAEBKVF */
+ { SST(0x55, 0x0B, SS_RDEF, /* XXX TBD */
+ "Insufficient power for operation") },
+ /* DT P B */
+ { SST(0x55, 0x0C, SS_RDEF, /* XXX TBD */
+ "Insufficient resources to create ROD") },
+ /* DT P B */
+ { SST(0x55, 0x0D, SS_RDEF, /* XXX TBD */
+ "Insufficient resources to create ROD token") },
/* R */
{ SST(0x57, 0x00, SS_RDEF,
"Unable to recover table-of-contents") },
@@ -2354,6 +2507,24 @@
/* DTLPWRO A K */
{ SST(0x5E, 0x04, SS_RDEF,
"Standby condition activated by command") },
+ /* DTLPWRO A K */
+ { SST(0x5E, 0x05, SS_RDEF,
+ "Idle-B condition activated by timer") },
+ /* DTLPWRO A K */
+ { SST(0x5E, 0x06, SS_RDEF,
+ "Idle-B condition activated by command") },
+ /* DTLPWRO A K */
+ { SST(0x5E, 0x07, SS_RDEF,
+ "Idle-C condition activated by timer") },
+ /* DTLPWRO A K */
+ { SST(0x5E, 0x08, SS_RDEF,
+ "Idle-C condition activated by command") },
+ /* DTLPWRO A K */
+ { SST(0x5E, 0x09, SS_RDEF,
+ "Standby-Y condition activated by timer") },
+ /* DTLPWRO A K */
+ { SST(0x5E, 0x0A, SS_RDEF,
+ "Standby-Y condition activated by command") },
/* B */
{ SST(0x5E, 0x41, SS_RDEF, /* XXX TBD */
"Power state change to active") },
@@ -2834,11 +3005,10 @@
int error_code, sense_key, asc, ascq;
scsi_sense_action action;
- scsi_extract_sense_len(&csio->sense_data, csio->sense_len -
- csio->sense_resid, &error_code,
- &sense_key, &asc, &ascq, /*show_errors*/ 1);
-
- if ((error_code == SSD_DEFERRED_ERROR)
+ if (!scsi_extract_sense_ccb((union ccb *)csio,
+ &error_code, &sense_key, &asc, &ascq)) {
+ action = SS_RETRY | SSQ_DECREMENT_COUNT | SSQ_PRINT_SENSE | EIO;
+ } else if ((error_code == SSD_DEFERRED_ERROR)
|| (error_code == SSD_DESC_DEFERRED_ERROR)) {
/*
* XXX dufault at FreeBSD.org
@@ -2901,11 +3071,17 @@
SSQ_PRINT_SENSE;
}
}
+ if ((action & SS_MASK) >= SS_START &&
+ (sense_flags & SF_NO_RECOVERY)) {
+ action &= ~SS_MASK;
+ action |= SS_FAIL;
+ } else if ((action & SS_MASK) == SS_RETRY &&
+ (sense_flags & SF_NO_RETRY)) {
+ action &= ~SS_MASK;
+ action |= SS_FAIL;
+ }
+
}
-#ifdef _KERNEL
- if (bootverbose)
- sense_flags |= SF_PRINT_ALWAYS;
-#endif
if ((sense_flags & SF_PRINT_ALWAYS) != 0)
action |= SSQ_PRINT_SENSE;
else if ((sense_flags & SF_NO_PRINT) != 0)
@@ -3059,6 +3235,10 @@
sizeof(cdb_str)));
}
+#ifdef _KERNEL
+ xpt_free_ccb((union ccb *)cgd);
+#endif
+
return(0);
}
@@ -4138,9 +4318,9 @@
struct scsi_inquiry_data *inq_data,
struct scsi_sense_desc_header *header)
{
- int i, found;
-
- for (i = 0, found = 0; i < (sizeof(scsi_sense_printers) /
+ int i;
+
+ for (i = 0; i < (sizeof(scsi_sense_printers) /
sizeof(scsi_sense_printers[0])); i++) {
struct scsi_sense_desc_printer *printer;
@@ -4612,6 +4792,36 @@
}
/*
+ * Extract basic sense information from SCSI I/O CCB structure.
+ */
+int
+scsi_extract_sense_ccb(union ccb *ccb,
+ int *error_code, int *sense_key, int *asc, int *ascq)
+{
+ struct scsi_sense_data *sense_data;
+
+ /* Make sure there are some sense data we can access. */
+ if (ccb->ccb_h.func_code != XPT_SCSI_IO ||
+ (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_SCSI_STATUS_ERROR ||
+ (ccb->csio.scsi_status != SCSI_STATUS_CHECK_COND) ||
+ (ccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0 ||
+ (ccb->ccb_h.flags & CAM_SENSE_PHYS))
+ return (0);
+
+ if (ccb->ccb_h.flags & CAM_SENSE_PTR)
+ bcopy(&ccb->csio.sense_data, &sense_data,
+ sizeof(struct scsi_sense_data *));
+ else
+ sense_data = &ccb->csio.sense_data;
+ scsi_extract_sense_len(sense_data,
+ ccb->csio.sense_len - ccb->csio.sense_resid,
+ error_code, sense_key, asc, ascq, 1);
+ if (*error_code == -1)
+ return (0);
+ return (1);
+}
+
+/*
* Extract basic sense information. If show_errors is set, sense values
* will be set to -1 if they are not present.
*/
@@ -5740,6 +5950,66 @@
timeout);
}
+void
+scsi_read_buffer(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb*),
+ uint8_t tag_action, int mode,
+ uint8_t buffer_id, u_int32_t offset,
+ uint8_t *data_ptr, uint32_t allocation_length,
+ uint8_t sense_len, uint32_t timeout)
+{
+ struct scsi_read_buffer *scsi_cmd;
+
+ scsi_cmd = (struct scsi_read_buffer *)&csio->cdb_io.cdb_bytes;
+ memset(scsi_cmd, 0, sizeof(*scsi_cmd));
+ scsi_cmd->opcode = READ_BUFFER;
+ scsi_cmd->byte2 = mode;
+ scsi_cmd->buffer_id = buffer_id;
+ scsi_ulto3b(offset, scsi_cmd->offset);
+ scsi_ulto3b(allocation_length, scsi_cmd->length);
+
+ cam_fill_csio(csio,
+ retries,
+ cbfcnp,
+ /*flags*/CAM_DIR_IN,
+ tag_action,
+ data_ptr,
+ allocation_length,
+ sense_len,
+ sizeof(*scsi_cmd),
+ timeout);
+}
+
+void
+scsi_write_buffer(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ uint8_t tag_action, int mode,
+ uint8_t buffer_id, u_int32_t offset,
+ uint8_t *data_ptr, uint32_t param_list_length,
+ uint8_t sense_len, uint32_t timeout)
+{
+ struct scsi_write_buffer *scsi_cmd;
+
+ scsi_cmd = (struct scsi_write_buffer *)&csio->cdb_io.cdb_bytes;
+ memset(scsi_cmd, 0, sizeof(*scsi_cmd));
+ scsi_cmd->opcode = WRITE_BUFFER;
+ scsi_cmd->byte2 = mode;
+ scsi_cmd->buffer_id = buffer_id;
+ scsi_ulto3b(offset, scsi_cmd->offset);
+ scsi_ulto3b(param_list_length, scsi_cmd->length);
+
+ cam_fill_csio(csio,
+ retries,
+ cbfcnp,
+ /*flags*/param_list_length ? CAM_DIR_OUT : CAM_DIR_NONE,
+ tag_action,
+ data_ptr,
+ param_list_length,
+ sense_len,
+ sizeof(*scsi_cmd),
+ timeout);
+}
+
void
scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_all.h
--- a/head/sys/cam/scsi/scsi_all.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/scsi/scsi_all.h Wed Jul 25 16:45:04 2012 +0300
@@ -14,7 +14,7 @@
*
* Ported to run under 386BSD by Julian Elischer (julian at tfs.com) Sept 1992
*
- * $FreeBSD: head/sys/cam/scsi/scsi_all.h 230590 2012-01-26 18:09:28Z ken $
+ * $FreeBSD: head/sys/cam/scsi/scsi_all.h 237478 2012-06-23 12:32:53Z mav $
*/
/*
@@ -74,9 +74,6 @@
SS_TUR = 0x040000, /* Send a Test Unit Ready command to the
* device, then retry the original command.
*/
- SS_REQSENSE = 0x050000, /* Send a RequestSense command to the
- * device, then retry the original command.
- */
SS_MASK = 0xff0000
} scsi_sense_action;
@@ -1267,6 +1264,8 @@
#define SCSI_PROTO_RDMA 0x04
#define SCSI_PROTO_iSCSI 0x05
#define SCSI_PROTO_SAS 0x06
+#define SCSI_PROTO_ADT 0x07
+#define SCSI_PROTO_ATA 0x08
#define SVPD_ID_PROTO_SHIFT 4
#define SVPD_ID_CODESET_BINARY 0x01
#define SVPD_ID_CODESET_ASCII 0x02
@@ -1400,6 +1399,13 @@
uint8_t control;
};
+struct scsi_diag_page {
+ uint8_t page_code;
+ uint8_t page_specific_flags;
+ uint8_t length[2];
+ uint8_t params[0];
+};
+
struct scsi_read_capacity
{
u_int8_t opcode;
@@ -2174,12 +2180,6 @@
char * scsi_sense_string(struct ccb_scsiio *csio,
char *str, int str_len);
void scsi_sense_print(struct ccb_scsiio *csio);
-int scsi_interpret_sense(union ccb *ccb,
- u_int32_t sense_flags,
- u_int32_t *relsim_flags,
- u_int32_t *reduction,
- u_int32_t *timeout,
- scsi_sense_action error_action);
#else /* _KERNEL */
int scsi_command_string(struct cam_device *device,
struct ccb_scsiio *csio, struct sbuf *sb);
@@ -2191,21 +2191,8 @@
char *str, int str_len);
void scsi_sense_print(struct cam_device *device,
struct ccb_scsiio *csio, FILE *ofile);
-int scsi_interpret_sense(struct cam_device *device,
- union ccb *ccb,
- u_int32_t sense_flags,
- u_int32_t *relsim_flags,
- u_int32_t *reduction,
- u_int32_t *timeout,
- scsi_sense_action error_action);
#endif /* _KERNEL */
-#define SF_RETRY_UA 0x01
-#define SF_NO_PRINT 0x02
-#define SF_QUIET_IR 0x04 /* Be quiet about Illegal Request reponses */
-#define SF_PRINT_ALWAYS 0x08
-
-
const char * scsi_op_desc(u_int16_t opcode,
struct scsi_inquiry_data *inq_data);
char * scsi_cdb_string(u_int8_t *cdb_ptr, char *cdb_string,
@@ -2352,6 +2339,20 @@
uint16_t param_list_length, uint8_t sense_len,
uint32_t timeout);
+void scsi_read_buffer(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb*),
+ uint8_t tag_action, int mode,
+ uint8_t buffer_id, u_int32_t offset,
+ uint8_t *data_ptr, uint32_t allocation_length,
+ uint8_t sense_len, uint32_t timeout);
+
+void scsi_write_buffer(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ uint8_t tag_action, int mode,
+ uint8_t buffer_id, u_int32_t offset,
+ uint8_t *data_ptr, uint32_t param_list_length,
+ uint8_t sense_len, uint32_t timeout);
+
void scsi_read_write(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int readop, u_int8_t byte2,
@@ -2387,6 +2388,8 @@
void scsi_extract_sense(struct scsi_sense_data *sense, int *error_code,
int *sense_key, int *asc, int *ascq);
+int scsi_extract_sense_ccb(union ccb *ccb, int *error_code, int *sense_key,
+ int *asc, int *ascq);
void scsi_extract_sense_len(struct scsi_sense_data *sense,
u_int sense_len, int *error_code, int *sense_key,
int *asc, int *ascq, int show_errors);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_cd.c
--- a/head/sys/cam/scsi/scsi_cd.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/scsi/scsi_cd.c Wed Jul 25 16:45:04 2012 +0300
@@ -46,7 +46,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_cd.c 229395 2012-01-03 17:04:09Z mav $");
+__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_cd.c 237689 2012-06-28 07:01:48Z imp $");
#include "opt_cd.h"
@@ -97,15 +97,13 @@
CD_FLAG_NEW_DISC = 0x0002,
CD_FLAG_DISC_LOCKED = 0x0004,
CD_FLAG_DISC_REMOVABLE = 0x0008,
- CD_FLAG_TAGGED_QUEUING = 0x0010,
CD_FLAG_CHANGER = 0x0040,
CD_FLAG_ACTIVE = 0x0080,
CD_FLAG_SCHED_ON_COMP = 0x0100,
CD_FLAG_RETRY_UA = 0x0200,
CD_FLAG_VALID_MEDIA = 0x0400,
CD_FLAG_VALID_TOC = 0x0800,
- CD_FLAG_SCTX_INIT = 0x1000,
- CD_FLAG_OPEN = 0x2000
+ CD_FLAG_SCTX_INIT = 0x1000
} cd_flags;
typedef enum {
@@ -295,6 +293,9 @@
#ifndef CD_DEFAULT_RETRY
#define CD_DEFAULT_RETRY 4
#endif
+#ifndef CD_DEFAULT_TIMEOUT
+#define CD_DEFAULT_TIMEOUT 30000
+#endif
#ifndef CHANGER_MIN_BUSY_SECONDS
#define CHANGER_MIN_BUSY_SECONDS 5
#endif
@@ -303,6 +304,7 @@
#endif
static int cd_retry_count = CD_DEFAULT_RETRY;
+static int cd_timeout = CD_DEFAULT_TIMEOUT;
static int changer_min_busy_seconds = CHANGER_MIN_BUSY_SECONDS;
static int changer_max_busy_seconds = CHANGER_MAX_BUSY_SECONDS;
@@ -312,6 +314,9 @@
SYSCTL_INT(_kern_cam_cd, OID_AUTO, retry_count, CTLFLAG_RW,
&cd_retry_count, 0, "Normal I/O retry count");
TUNABLE_INT("kern.cam.cd.retry_count", &cd_retry_count);
+SYSCTL_INT(_kern_cam_cd, OID_AUTO, timeout, CTLFLAG_RW,
+ &cd_timeout, 0, "Timeout, in us, for read operations");
+TUNABLE_INT("kern.cam.cd.timeout", &cd_timeout);
SYSCTL_INT(_kern_cam_cd_changer, OID_AUTO, min_busy_seconds, CTLFLAG_RW,
&changer_min_busy_seconds, 0, "Minimum changer scheduling quantum");
TUNABLE_INT("kern.cam.cd.changer.min_busy_seconds", &changer_min_busy_seconds);
@@ -359,6 +364,20 @@
}
}
+/*
+ * Callback from GEOM, called when it has finished cleaning up its
+ * resources.
+ */
+static void
+cddiskgonecb(struct disk *dp)
+{
+ struct cam_periph *periph;
+
+ periph = (struct cam_periph *)dp->d_drv1;
+
+ cam_periph_release(periph);
+}
+
static void
cdoninvalidate(struct cam_periph *periph)
{
@@ -390,7 +409,7 @@
camq_remove(&softc->changer->devq, softc->pinfo.index);
disk_gone(softc->disk);
- xpt_print(periph->path, "lost device\n");
+ xpt_print(periph->path, "lost device, %d refs\n", periph->refcount);
}
static void
@@ -653,8 +672,6 @@
bioq_init(&softc->bio_queue);
if (SID_IS_REMOVABLE(&cgd->inq_data))
softc->flags |= CD_FLAG_DISC_REMOVABLE;
- if ((cgd->inq_data.flags & SID_CmdQue) != 0)
- softc->flags |= CD_FLAG_TAGGED_QUEUING;
periph->softc = softc;
softc->periph = periph;
@@ -729,6 +746,7 @@
softc->disk->d_open = cdopen;
softc->disk->d_close = cdclose;
softc->disk->d_strategy = cdstrategy;
+ softc->disk->d_gone = cddiskgonecb;
softc->disk->d_ioctl = cdioctl;
softc->disk->d_name = "cd";
cam_strvis(softc->disk->d_descr, cgd->inq_data.vendor,
@@ -750,6 +768,19 @@
softc->disk->d_hba_device = cpi.hba_device;
softc->disk->d_hba_subvendor = cpi.hba_subvendor;
softc->disk->d_hba_subdevice = cpi.hba_subdevice;
+
+ /*
+ * Acquire a reference to the periph before we register with GEOM.
+ * We'll release this reference once GEOM calls us back (via
+ * dadiskgonecb()) telling us that our provider has been freed.
+ */
+ if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
+ xpt_print(periph->path, "%s: lost periph during "
+ "registration!\n", __func__);
+ cam_periph_lock(periph);
+ return (CAM_REQ_CMP_ERR);
+ }
+
disk_create(softc->disk, DISK_VERSION);
cam_periph_lock(periph);
@@ -1003,17 +1034,20 @@
cam_periph_lock(periph);
if (softc->flags & CD_FLAG_INVALID) {
+ cam_periph_release_locked(periph);
cam_periph_unlock(periph);
- cam_periph_release(periph);
return(ENXIO);
}
if ((error = cam_periph_hold(periph, PRIBIO | PCATCH)) != 0) {
+ cam_periph_release_locked(periph);
cam_periph_unlock(periph);
- cam_periph_release(periph);
return (error);
}
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
+ ("cdopen\n"));
+
/*
* Check for media, and set the appropriate flags. We don't bail
* if we don't have media, but then we don't allow anything but the
@@ -1024,14 +1058,7 @@
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("leaving cdopen\n"));
cam_periph_unhold(periph);
- /* Closes aren't symmetrical with opens, so fix up the refcounting. */
- if ((softc->flags & CD_FLAG_OPEN) == 0) {
- softc->flags |= CD_FLAG_OPEN;
- cam_periph_unlock(periph);
- } else {
- cam_periph_unlock(periph);
- cam_periph_release(periph);
- }
+ cam_periph_unlock(periph);
return (0);
}
@@ -1049,7 +1076,14 @@
softc = (struct cd_softc *)periph->softc;
cam_periph_lock(periph);
- cam_periph_hold(periph, PRIBIO);
+ if (cam_periph_hold(periph, PRIBIO) != 0) {
+ cam_periph_unlock(periph);
+ cam_periph_release(periph);
+ return (0);
+ }
+
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
+ ("cdclose\n"));
if ((softc->flags & CD_FLAG_DISC_REMOVABLE) != 0)
cdprevent(periph, PR_ALLOW);
@@ -1063,11 +1097,11 @@
/*
* We'll check the media and toc again at the next open().
*/
- softc->flags &= ~(CD_FLAG_VALID_MEDIA|CD_FLAG_VALID_TOC|CD_FLAG_OPEN);
+ softc->flags &= ~(CD_FLAG_VALID_MEDIA|CD_FLAG_VALID_TOC);
cam_periph_unhold(periph);
+ cam_periph_release_locked(periph);
cam_periph_unlock(periph);
- cam_periph_release(periph);
return (0);
}
@@ -1395,7 +1429,8 @@
}
cam_periph_lock(periph);
- CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering cdstrategy\n"));
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
+ ("cdstrategy(%p)\n", bp));
softc = (struct cd_softc *)periph->softc;
@@ -1481,8 +1516,9 @@
bp->bio_bcount / softc->params.blksize,
/* data_ptr */ bp->bio_data,
/* dxfer_len */ bp->bio_bcount,
- /* sense_len */ SSD_FULL_SIZE,
- /* timeout */ 30000);
+ /* sense_len */ cd_retry_count ?
+ SSD_FULL_SIZE : SF_NO_PRINT,
+ /* timeout */ cd_timeout);
/* Use READ CD command for audio tracks. */
if (softc->params.blksize == 2352) {
start_ccb->csio.cdb_io.cdb_bytes[0] = READ_CD;
@@ -1668,7 +1704,6 @@
return;
} else if (error != 0) {
- struct scsi_sense_data *sense;
int asc, ascq;
int sense_key, error_code;
int have_sense;
@@ -1691,20 +1726,12 @@
cgd.ccb_h.func_code = XPT_GDEV_TYPE;
xpt_action((union ccb *)&cgd);
- if (((csio->ccb_h.flags & CAM_SENSE_PHYS) != 0)
- || ((csio->ccb_h.flags & CAM_SENSE_PTR) != 0)
- || ((status & CAM_AUTOSNS_VALID) == 0))
+ if (scsi_extract_sense_ccb(done_ccb,
+ &error_code, &sense_key, &asc, &ascq))
+ have_sense = TRUE;
+ else
have_sense = FALSE;
- else
- have_sense = TRUE;
-
- if (have_sense) {
- sense = &csio->sense_data;
- scsi_extract_sense_len(sense,
- csio->sense_len - csio->sense_resid,
- &error_code, &sense_key, &asc,
- &ascq, /*show_errors*/ 1);
- }
+
/*
* Attach to anything that claims to be a
* CDROM or WORM device, as long as it
@@ -1861,12 +1888,11 @@
return(ENXIO);
cam_periph_lock(periph);
- CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering cdioctl\n"));
softc = (struct cd_softc *)periph->softc;
- CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
- ("trying to do ioctl %#lx\n", cmd));
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
+ ("cdioctl(%#lx)\n", cmd));
if ((error = cam_periph_hold(periph, PRIBIO | PCATCH)) != 0) {
cam_periph_unlock(periph);
@@ -3131,7 +3157,7 @@
{
struct cd_softc *softc;
struct cam_periph *periph;
- int error;
+ int error, error_code, sense_key, asc, ascq;
periph = xpt_path_periph(ccb->ccb_h.path);
softc = (struct cd_softc *)periph->softc;
@@ -3145,19 +3171,10 @@
*/
if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) {
error = cd6byteworkaround(ccb);
- } else if (((ccb->ccb_h.status & CAM_STATUS_MASK) ==
- CAM_SCSI_STATUS_ERROR)
- && (ccb->ccb_h.status & CAM_AUTOSNS_VALID)
- && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
- && ((ccb->ccb_h.flags & CAM_SENSE_PHYS) == 0)
- && ((ccb->ccb_h.flags & CAM_SENSE_PTR) == 0)) {
- int sense_key, error_code, asc, ascq;
-
- scsi_extract_sense_len(&ccb->csio.sense_data,
- ccb->csio.sense_len - ccb->csio.sense_resid, &error_code,
- &sense_key, &asc, &ascq, /*show_errors*/ 1);
+ } else if (scsi_extract_sense_ccb(ccb,
+ &error_code, &sense_key, &asc, &ascq)) {
if (sense_key == SSD_KEY_ILLEGAL_REQUEST)
- error = cd6byteworkaround(ccb);
+ error = cd6byteworkaround(ccb);
}
if (error == ERESTART)
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_ch.c
--- a/head/sys/cam/scsi/scsi_ch.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/scsi/scsi_ch.c Wed Jul 25 16:45:04 2012 +0300
@@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_ch.c 227293 2011-11-07 06:44:47Z ed $");
+__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_ch.c 238200 2012-07-07 17:17:43Z eadler $");
#include <sys/param.h>
#include <sys/queue.h>
@@ -107,8 +107,7 @@
static const u_int32_t CH_TIMEOUT_INITIALIZE_ELEMENT_STATUS = 500000;
typedef enum {
- CH_FLAG_INVALID = 0x001,
- CH_FLAG_OPEN = 0x002
+ CH_FLAG_INVALID = 0x001
} ch_flags;
typedef enum {
@@ -211,7 +210,7 @@
static struct cdevsw ch_cdevsw = {
.d_version = D_VERSION,
- .d_flags = 0,
+ .d_flags = D_TRACKCLOSE,
.d_open = chopen,
.d_close = chclose,
.d_ioctl = chioctl,
@@ -404,16 +403,11 @@
cam_periph_lock(periph);
if (softc->flags & CH_FLAG_INVALID) {
+ cam_periph_release_locked(periph);
cam_periph_unlock(periph);
- cam_periph_release(periph);
return(ENXIO);
}
- if ((softc->flags & CH_FLAG_OPEN) == 0)
- softc->flags |= CH_FLAG_OPEN;
- else
- cam_periph_release(periph);
-
if ((error = cam_periph_hold(periph, PRIBIO | PCATCH)) != 0) {
cam_periph_unlock(periph);
cam_periph_release(periph);
@@ -424,9 +418,8 @@
* Load information about this changer device into the softc.
*/
if ((error = chgetparams(periph)) != 0) {
- softc->flags &= ~CH_FLAG_OPEN;
+ cam_periph_release_locked(periph);
cam_periph_unlock(periph);
- cam_periph_release(periph);
return(error);
}
@@ -440,22 +433,11 @@
chclose(struct cdev *dev, int flag, int fmt, struct thread *td)
{
struct cam_periph *periph;
- struct ch_softc *softc;
- int error;
-
- error = 0;
periph = (struct cam_periph *)dev->si_drv1;
if (periph == NULL)
return(ENXIO);
- softc = (struct ch_softc *)periph->softc;
-
- cam_periph_lock(periph);
-
- softc->flags &= ~CH_FLAG_OPEN;
-
- cam_periph_unlock(periph);
cam_periph_release(periph);
return(0);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_da.c
--- a/head/sys/cam/scsi/scsi_da.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/scsi/scsi_da.c Wed Jul 25 16:45:04 2012 +0300
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_da.c 234374 2012-04-17 10:44:28Z trasz $");
+__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_da.c 238437 2012-07-14 02:59:11Z mjacob $");
#include <sys/param.h>
@@ -77,7 +77,6 @@
DA_FLAG_NEW_PACK = 0x002,
DA_FLAG_PACK_LOCKED = 0x004,
DA_FLAG_PACK_REMOVABLE = 0x008,
- DA_FLAG_TAGGED_QUEUING = 0x010,
DA_FLAG_NEED_OTAG = 0x020,
DA_FLAG_WENT_IDLE = 0x040,
DA_FLAG_RETRY_UA = 0x080,
@@ -811,6 +810,27 @@
{ T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "???PVT*", "*" },
/*quirks*/DA_Q_4K
},
+ {
+ /*
+ * Olympus FE-210 camera
+ */
+ {T_DIRECT, SIP_MEDIA_REMOVABLE, "OLYMPUS", "FE210*",
+ "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
+ },
+ {
+ /*
+ * LG UP3S MP3 player
+ */
+ {T_DIRECT, SIP_MEDIA_REMOVABLE, "LG", "UP3S",
+ "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
+ },
+ {
+ /*
+ * Laser MP3-2GA13 MP3 player
+ */
+ {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB 2.0", "(HS) Flash Disk",
+ "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
+ },
};
static disk_strategy_t dastrategy;
@@ -863,9 +883,9 @@
SYSCTL_INT(_kern_cam_da, OID_AUTO, default_timeout, CTLFLAG_RW,
&da_default_timeout, 0, "Normal I/O timeout (in seconds)");
TUNABLE_INT("kern.cam.da.default_timeout", &da_default_timeout);
-SYSCTL_INT(_kern_cam_da, OID_AUTO, da_send_ordered, CTLFLAG_RW,
+SYSCTL_INT(_kern_cam_da, OID_AUTO, send_ordered, CTLFLAG_RW,
&da_send_ordered, 0, "Send Ordered Tags");
-TUNABLE_INT("kern.cam.da.da_send_ordered", &da_send_ordered);
+TUNABLE_INT("kern.cam.da.send_ordered", &da_send_ordered);
/*
* DA_ORDEREDTAG_INTERVAL determines how often, relative
@@ -921,9 +941,8 @@
softc = (struct da_softc *)periph->softc;
softc->flags |= DA_FLAG_OPEN;
- CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
- ("daopen: disk=%s%d (unit %d)\n", dp->d_name, dp->d_unit,
- unit));
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
+ ("daopen\n"));
if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) {
/* Invalidate our pack information. */
@@ -963,14 +982,13 @@
{
struct cam_periph *periph;
struct da_softc *softc;
- int error;
periph = (struct cam_periph *)dp->d_drv1;
if (periph == NULL)
return (0);
cam_periph_lock(periph);
- if ((error = cam_periph_hold(periph, PRIBIO)) != 0) {
+ if (cam_periph_hold(periph, PRIBIO) != 0) {
cam_periph_unlock(periph);
cam_periph_release(periph);
return (0);
@@ -978,6 +996,9 @@
softc = (struct da_softc *)periph->softc;
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
+ ("daclose\n"));
+
if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0
&& (softc->flags & DA_FLAG_PACK_INVALID) == 0) {
union ccb *ccb;
@@ -993,30 +1014,9 @@
SSD_FULL_SIZE,
5 * 60 * 1000);
- cam_periph_runccb(ccb, /*error_routine*/NULL, /*cam_flags*/0,
- /*sense_flags*/SF_RETRY_UA,
+ cam_periph_runccb(ccb, daerror, /*cam_flags*/0,
+ /*sense_flags*/SF_RETRY_UA | SF_QUIET_IR,
softc->disk->d_devstat);
-
- if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
- if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
- CAM_SCSI_STATUS_ERROR) {
- int asc, ascq;
- int sense_key, error_code;
-
- scsi_extract_sense_len(&ccb->csio.sense_data,
- ccb->csio.sense_len - ccb->csio.sense_resid,
- &error_code, &sense_key, &asc, &ascq,
- /*show_errors*/ 1);
- if (sense_key != SSD_KEY_ILLEGAL_REQUEST)
- scsi_sense_print(&ccb->csio);
- } else {
- xpt_print(periph->path, "Synchronize cache "
- "failed, status == 0x%x, scsi status == "
- "0x%x\n", ccb->csio.ccb_h.status,
- ccb->csio.scsi_status);
- }
- }
-
xpt_release_ccb(ccb);
}
@@ -1087,7 +1087,9 @@
biofinish(bp, NULL, ENXIO);
return;
}
-
+
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dastrategy(%p)\n", bp));
+
/*
* Place it in the queue of disk activities for this disk
*/
@@ -1116,6 +1118,7 @@
u_int secsize;
struct ccb_scsiio csio;
struct disk *dp;
+ int error = 0;
dp = arg;
periph = dp->d_drv1;
@@ -1134,7 +1137,7 @@
xpt_setup_ccb(&csio.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
csio.ccb_h.ccb_state = DA_CCB_DUMP;
scsi_read_write(&csio,
- /*retries*/1,
+ /*retries*/0,
dadone,
MSG_ORDERED_Q_TAG,
/*read*/FALSE,
@@ -1147,19 +1150,16 @@
/*sense_len*/SSD_FULL_SIZE,
da_default_timeout * 1000);
xpt_polled_action((union ccb *)&csio);
+
+ error = cam_periph_error((union ccb *)&csio,
+ 0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
+ if ((csio.ccb_h.status & CAM_DEV_QFRZN) != 0)
+ cam_release_devq(csio.ccb_h.path, /*relsim_flags*/0,
+ /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
+ if (error != 0)
+ printf("Aborting dump due to I/O error.\n");
cam_periph_unlock(periph);
-
- if ((csio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
- printf("Aborting dump due to I/O error.\n");
- if ((csio.ccb_h.status & CAM_STATUS_MASK) ==
- CAM_SCSI_STATUS_ERROR)
- scsi_sense_print(&csio);
- else
- printf("status == 0x%x, scsi status == 0x%x\n",
- csio.ccb_h.status, csio.scsi_status);
- return(EIO);
- }
- return(0);
+ return (error);
}
/*
@@ -1170,7 +1170,7 @@
xpt_setup_ccb(&csio.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
csio.ccb_h.ccb_state = DA_CCB_DUMP;
scsi_synchronize_cache(&csio,
- /*retries*/1,
+ /*retries*/0,
/*cbfcnp*/dadone,
MSG_SIMPLE_Q_TAG,
/*begin_lba*/0,/* Cover the whole disk */
@@ -1179,28 +1179,16 @@
5 * 60 * 1000);
xpt_polled_action((union ccb *)&csio);
- if ((csio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
- if ((csio.ccb_h.status & CAM_STATUS_MASK) ==
- CAM_SCSI_STATUS_ERROR) {
- int asc, ascq;
- int sense_key, error_code;
-
- scsi_extract_sense_len(&csio.sense_data,
- csio.sense_len - csio.sense_resid,
- &error_code, &sense_key, &asc, &ascq,
- /*show_errors*/ 1);
- if (sense_key != SSD_KEY_ILLEGAL_REQUEST)
- scsi_sense_print(&csio);
- } else {
- xpt_print(periph->path, "Synchronize cache "
- "failed, status == 0x%x, scsi status == "
- "0x%x\n", csio.ccb_h.status,
- csio.scsi_status);
- }
- }
+ error = cam_periph_error((union ccb *)&csio,
+ 0, SF_NO_RECOVERY | SF_NO_RETRY | SF_QUIET_IR, NULL);
+ if ((csio.ccb_h.status & CAM_DEV_QFRZN) != 0)
+ cam_release_devq(csio.ccb_h.path, /*relsim_flags*/0,
+ /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
+ if (error != 0)
+ xpt_print(periph->path, "Synchronize cache failed\n");
}
cam_periph_unlock(periph);
- return (0);
+ return (error);
}
static int
@@ -1245,6 +1233,20 @@
}
}
+/*
+ * Callback from GEOM, called when it has finished cleaning up its
+ * resources.
+ */
+static void
+dadiskgonecb(struct disk *dp)
+{
+ struct cam_periph *periph;
+
+ periph = (struct cam_periph *)dp->d_drv1;
+
+ cam_periph_release(periph);
+}
+
static void
daoninvalidate(struct cam_periph *periph)
{
@@ -1267,7 +1269,12 @@
bioq_flush(&softc->bio_queue, NULL, ENXIO);
bioq_flush(&softc->delete_queue, NULL, ENXIO);
+ /*
+ * Tell GEOM that we've gone away, we'll get a callback when it is
+ * done cleaning up its resources.
+ */
disk_gone(softc->disk);
+
xpt_print(periph->path, "lost device - %d outstanding, %d refs\n",
softc->outstanding_cmds, periph->refcount);
}
@@ -1550,8 +1557,6 @@
bioq_init(&softc->delete_run_queue);
if (SID_IS_REMOVABLE(&cgd->inq_data))
softc->flags |= DA_FLAG_PACK_REMOVABLE;
- if ((cgd->inq_data.flags & SID_CmdQue) != 0)
- softc->flags |= DA_FLAG_TAGGED_QUEUING;
softc->unmap_max_ranges = UNMAP_MAX_RANGES;
softc->unmap_max_lba = 1024*1024*2;
@@ -1647,6 +1652,7 @@
softc->disk->d_strategy = dastrategy;
softc->disk->d_dump = dadump;
softc->disk->d_getattr = dagetattr;
+ softc->disk->d_gone = dadiskgonecb;
softc->disk->d_name = "da";
softc->disk->d_drv1 = periph;
if (cpi.maxio == 0)
@@ -1669,6 +1675,19 @@
softc->disk->d_hba_device = cpi.hba_device;
softc->disk->d_hba_subvendor = cpi.hba_subvendor;
softc->disk->d_hba_subdevice = cpi.hba_subdevice;
+
+ /*
+ * Acquire a reference to the periph before we register with GEOM.
+ * We'll release this reference once GEOM calls us back (via
+ * dadiskgonecb()) telling us that our provider has been freed.
+ */
+ if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
+ xpt_print(periph->path, "%s: lost periph during "
+ "registration!\n", __func__);
+ mtx_lock(periph->sim->mtx);
+ return (CAM_REQ_CMP_ERR);
+ }
+
disk_create(softc->disk, DISK_VERSION);
mtx_lock(periph->sim->mtx);
@@ -1703,6 +1722,8 @@
softc = (struct da_softc *)periph->softc;
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dastart\n"));
+
switch (softc->state) {
case DA_STATE_NORMAL:
{
@@ -1711,7 +1732,7 @@
/* Execute immediate CCB if waiting. */
if (periph->immediate_priority <= periph->pinfo.priority) {
- CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
+ CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE,
("queuing for immediate ccb\n"));
start_ccb->ccb_h.ccb_state = DA_CCB_WAITING;
SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
@@ -2043,6 +2064,9 @@
softc = (struct da_softc *)periph->softc;
priority = done_ccb->ccb_h.pinfo.priority;
+
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone\n"));
+
csio = &done_ccb->csio;
switch (csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK) {
case DA_CCB_BUFFER_IO:
@@ -2263,7 +2287,6 @@
*/
return;
} else if (error != 0) {
- struct scsi_sense_data *sense;
int asc, ascq;
int sense_key, error_code;
int have_sense;
@@ -2286,20 +2309,12 @@
cgd.ccb_h.func_code = XPT_GDEV_TYPE;
xpt_action((union ccb *)&cgd);
- if (((csio->ccb_h.flags & CAM_SENSE_PHYS) != 0)
- || ((csio->ccb_h.flags & CAM_SENSE_PTR) != 0)
- || ((status & CAM_AUTOSNS_VALID) == 0))
+ if (scsi_extract_sense_ccb(done_ccb,
+ &error_code, &sense_key, &asc, &ascq))
+ have_sense = TRUE;
+ else
have_sense = FALSE;
- else
- have_sense = TRUE;
- if (have_sense) {
- sense = &csio->sense_data;
- scsi_extract_sense_len(sense,
- csio->sense_len - csio->sense_resid,
- &error_code, &sense_key, &asc,
- &ascq, /*show_errors*/ 1);
- }
/*
* If we tried READ CAPACITY(16) and failed,
* fallback to READ CAPACITY(10).
@@ -2437,7 +2452,7 @@
{
struct da_softc *softc;
struct cam_periph *periph;
- int error;
+ int error, error_code, sense_key, asc, ascq;
periph = xpt_path_periph(ccb->ccb_h.path);
softc = (struct da_softc *)periph->softc;
@@ -2449,16 +2464,8 @@
error = 0;
if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) {
error = cmd6workaround(ccb);
- } else if (((ccb->ccb_h.status & CAM_STATUS_MASK) ==
- CAM_SCSI_STATUS_ERROR)
- && (ccb->ccb_h.status & CAM_AUTOSNS_VALID)
- && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
- && ((ccb->ccb_h.flags & CAM_SENSE_PHYS) == 0)
- && ((ccb->ccb_h.flags & CAM_SENSE_PTR) == 0)) {
- int sense_key, error_code, asc, ascq;
-
- scsi_extract_sense(&ccb->csio.sense_data,
- &error_code, &sense_key, &asc, &ascq);
+ } else if (scsi_extract_sense_ccb(ccb,
+ &error_code, &sense_key, &asc, &ascq)) {
if (sense_key == SSD_KEY_ILLEGAL_REQUEST)
error = cmd6workaround(ccb);
/*
@@ -2511,8 +2518,8 @@
SSD_FULL_SIZE,
5000);
- error = cam_periph_runccb(ccb, /*error_routine*/NULL, CAM_RETRY_SELTO,
- SF_RETRY_UA, softc->disk->d_devstat);
+ error = cam_periph_runccb(ccb, daerror, CAM_RETRY_SELTO,
+ SF_RETRY_UA | SF_QUIET_IR, softc->disk->d_devstat);
if (error == 0) {
if (action == PR_ALLOW)
@@ -2637,6 +2644,11 @@
softc->disk->d_flags |= DISKFLAG_CANDELETE;
else
softc->disk->d_flags &= ~DISKFLAG_CANDELETE;
+
+/* Currently as of 6/13/2012, panics if DIAGNOSTIC is set */
+#ifndef DIAGNOSTIC
+ disk_resize(softc->disk);
+#endif
}
static void
@@ -2669,6 +2681,7 @@
{
struct cam_periph *periph;
struct da_softc *softc;
+ int error;
TAILQ_FOREACH(periph, &dadriver.units, unit_links) {
union ccb ccb;
@@ -2690,7 +2703,7 @@
ccb.ccb_h.ccb_state = DA_CCB_DUMP;
scsi_synchronize_cache(&ccb.csio,
- /*retries*/1,
+ /*retries*/0,
/*cbfcnp*/dadone,
MSG_SIMPLE_Q_TAG,
/*begin_lba*/0, /* whole disk */
@@ -2700,32 +2713,13 @@
xpt_polled_action(&ccb);
- if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
- if (((ccb.ccb_h.status & CAM_STATUS_MASK) ==
- CAM_SCSI_STATUS_ERROR)
- && (ccb.csio.scsi_status == SCSI_STATUS_CHECK_COND)){
- int error_code, sense_key, asc, ascq;
-
- scsi_extract_sense(&ccb.csio.sense_data,
- &error_code, &sense_key,
- &asc, &ascq);
-
- if (sense_key != SSD_KEY_ILLEGAL_REQUEST)
- scsi_sense_print(&ccb.csio);
- } else {
- xpt_print(periph->path, "Synchronize "
- "cache failed, status == 0x%x, scsi status "
- "== 0x%x\n", ccb.ccb_h.status,
- ccb.csio.scsi_status);
- }
- }
-
+ error = cam_periph_error(&ccb,
+ 0, SF_NO_RECOVERY | SF_NO_RETRY | SF_QUIET_IR, NULL);
if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
- cam_release_devq(ccb.ccb_h.path,
- /*relsim_flags*/0,
- /*reduction*/0,
- /*timeout*/0,
- /*getcount_only*/0);
+ cam_release_devq(ccb.ccb_h.path, /*relsim_flags*/0,
+ /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
+ if (error != 0)
+ xpt_print(periph->path, "Synchronize cache failed\n");
cam_periph_unlock(periph);
}
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_da.h
--- a/head/sys/cam/scsi/scsi_da.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/scsi/scsi_da.h Wed Jul 25 16:45:04 2012 +0300
@@ -46,7 +46,7 @@
*
* Ported to run under 386BSD by Julian Elischer (julian at tfs.com) Sept 1992
*
- * $FreeBSD: head/sys/cam/scsi/scsi_da.h 229997 2012-01-12 00:34:33Z ken $
+ * $FreeBSD: head/sys/cam/scsi/scsi_da.h 237452 2012-06-22 18:57:06Z ken $
*/
#ifndef _SCSI_SCSI_DA_H
@@ -111,6 +111,7 @@
u_int8_t reserved[4];
u_int8_t alloc_length[2];
+#define SRDD10_MAX_LENGTH 0xffff
u_int8_t control;
};
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_enc.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/cam/scsi/scsi_enc.c Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,1023 @@
+/*-
+ * Copyright (c) 2000 Matthew Jacob
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_enc.c 237328 2012-06-20 17:08:00Z ken $");
+
+#include <sys/param.h>
+
+#include <sys/conf.h>
+#include <sys/errno.h>
+#include <sys/fcntl.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+#include <sys/sx.h>
+#include <sys/systm.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+
+#include <machine/stdarg.h>
+
+#include <cam/cam.h>
+#include <cam/cam_ccb.h>
+#include <cam/cam_debug.h>
+#include <cam/cam_periph.h>
+#include <cam/cam_xpt_periph.h>
+
+#include <cam/scsi/scsi_all.h>
+#include <cam/scsi/scsi_message.h>
+#include <cam/scsi/scsi_enc.h>
+#include <cam/scsi/scsi_enc_internal.h>
+
+#include <opt_enc.h>
+
+MALLOC_DEFINE(M_SCSIENC, "SCSI ENC", "SCSI ENC buffers");
+
+/* Enclosure type independent driver */
+
+#define SEN_ID "UNISYS SUN_SEN"
+#define SEN_ID_LEN 24
+
+static d_open_t enc_open;
+static d_close_t enc_close;
+static d_ioctl_t enc_ioctl;
+static periph_init_t enc_init;
+static periph_ctor_t enc_ctor;
+static periph_oninv_t enc_oninvalidate;
+static periph_dtor_t enc_dtor;
+static periph_start_t enc_start;
+
+static void enc_async(void *, uint32_t, struct cam_path *, void *);
+static enctyp enc_type(struct ccb_getdev *);
+
+SYSCTL_NODE(_kern_cam, OID_AUTO, enc, CTLFLAG_RD, 0,
+ "CAM Enclosure Services driver");
+
+static struct periph_driver encdriver = {
+ enc_init, "ses",
+ TAILQ_HEAD_INITIALIZER(encdriver.units), /* generation */ 0
+};
+
+PERIPHDRIVER_DECLARE(enc, encdriver);
+
+static struct cdevsw enc_cdevsw = {
+ .d_version = D_VERSION,
+ .d_open = enc_open,
+ .d_close = enc_close,
+ .d_ioctl = enc_ioctl,
+ .d_name = "ses",
+ .d_flags = D_TRACKCLOSE,
+};
+
+static void
+enc_init(void)
+{
+ cam_status status;
+
+ /*
+ * Install a global async callback. This callback will
+ * receive async callbacks like "new device found".
+ */
+ status = xpt_register_async(AC_FOUND_DEVICE, enc_async, NULL, NULL);
+
+ if (status != CAM_REQ_CMP) {
+ printf("enc: Failed to attach master async callback "
+ "due to status 0x%x!\n", status);
+ }
+}
+
+static void
+enc_devgonecb(void *arg)
+{
+ struct cam_periph *periph;
+
+ periph = (struct cam_periph *)arg;
+
+ cam_periph_release(periph);
+}
+
+static void
+enc_oninvalidate(struct cam_periph *periph)
+{
+ struct enc_softc *enc;
+
+ enc = periph->softc;
+
+ enc->enc_flags |= ENC_FLAG_INVALID;
+
+ /* If the sub-driver has an invalidate routine, call it */
+ if (enc->enc_vec.softc_invalidate != NULL)
+ enc->enc_vec.softc_invalidate(enc);
+
+ /*
+ * Unregister any async callbacks.
+ */
+ xpt_register_async(0, enc_async, periph, periph->path);
+
+ /*
+ * Shutdown our daemon.
+ */
+ enc->enc_flags |= ENC_FLAG_SHUTDOWN;
+ if (enc->enc_daemon != NULL) {
+ /* Signal the ses daemon to terminate. */
+ wakeup(enc->enc_daemon);
+ }
+ callout_drain(&enc->status_updater);
+
+ destroy_dev_sched_cb(enc->enc_dev, enc_devgonecb, periph);
+
+ xpt_print(periph->path, "lost device\n");
+}
+
+static void
+enc_dtor(struct cam_periph *periph)
+{
+ struct enc_softc *enc;
+
+ enc = periph->softc;
+
+ xpt_print(periph->path, "removing device entry\n");
+
+
+ /* If the sub-driver has a cleanup routine, call it */
+ if (enc->enc_vec.softc_cleanup != NULL)
+ enc->enc_vec.softc_cleanup(enc);
+
+ if (enc->enc_boot_hold_ch.ich_func != NULL) {
+ config_intrhook_disestablish(&enc->enc_boot_hold_ch);
+ enc->enc_boot_hold_ch.ich_func = NULL;
+ }
+
+ ENC_FREE(enc);
+}
+
+static void
+enc_async(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
+{
+ struct cam_periph *periph;
+
+ periph = (struct cam_periph *)callback_arg;
+
+ switch(code) {
+ case AC_FOUND_DEVICE:
+ {
+ struct ccb_getdev *cgd;
+ cam_status status;
+ path_id_t path_id;
+
+ cgd = (struct ccb_getdev *)arg;
+ if (arg == NULL) {
+ break;
+ }
+
+ if (enc_type(cgd) == ENC_NONE) {
+ /*
+ * Schedule announcement of the ENC bindings for
+ * this device if it is managed by a SEP.
+ */
+ path_id = xpt_path_path_id(path);
+ xpt_lock_buses();
+ TAILQ_FOREACH(periph, &encdriver.units, unit_links) {
+ struct enc_softc *softc;
+
+ softc = (struct enc_softc *)periph->softc;
+ if (xpt_path_path_id(periph->path) != path_id
+ || softc == NULL
+ || (softc->enc_flags & ENC_FLAG_INITIALIZED)
+ == 0
+ || softc->enc_vec.device_found == NULL)
+ continue;
+
+ softc->enc_vec.device_found(softc);
+ }
+ xpt_unlock_buses();
+ return;
+ }
+
+ status = cam_periph_alloc(enc_ctor, enc_oninvalidate,
+ enc_dtor, enc_start, "ses", CAM_PERIPH_BIO,
+ cgd->ccb_h.path, enc_async, AC_FOUND_DEVICE, cgd);
+
+ if (status != CAM_REQ_CMP && status != CAM_REQ_INPROG) {
+ printf("enc_async: Unable to probe new device due to "
+ "status 0x%x\n", status);
+ }
+ break;
+ }
+ default:
+ cam_periph_async(periph, code, path, arg);
+ break;
+ }
+}
+
+static int
+enc_open(struct cdev *dev, int flags, int fmt, struct thread *td)
+{
+ struct cam_periph *periph;
+ struct enc_softc *softc;
+ int error = 0;
+
+ periph = (struct cam_periph *)dev->si_drv1;
+ if (periph == NULL) {
+ return (ENXIO);
+ }
+
+ if (cam_periph_acquire(periph) != CAM_REQ_CMP)
+ return (ENXIO);
+
+ cam_periph_lock(periph);
+
+ softc = (struct enc_softc *)periph->softc;
+
+ if ((softc->enc_flags & ENC_FLAG_INITIALIZED) == 0) {
+ error = ENXIO;
+ goto out;
+ }
+ if (softc->enc_flags & ENC_FLAG_INVALID) {
+ error = ENXIO;
+ goto out;
+ }
+out:
+ if (error != 0)
+ cam_periph_release_locked(periph);
+
+ cam_periph_unlock(periph);
+
+ return (error);
+}
+
+static int
+enc_close(struct cdev *dev, int flag, int fmt, struct thread *td)
+{
+ struct cam_periph *periph;
+
+ periph = (struct cam_periph *)dev->si_drv1;
+ if (periph == NULL)
+ return (ENXIO);
+
+ cam_periph_release(periph);
+
+ return (0);
+}
+
+static void
+enc_start(struct cam_periph *p, union ccb *sccb)
+{
+ struct enc_softc *enc;
+
+ enc = p->softc;
+ ENC_DLOG(enc, "%s enter imm=%d prio=%d\n",
+ __func__, p->immediate_priority, p->pinfo.priority);
+ if (p->immediate_priority <= p->pinfo.priority) {
+ SLIST_INSERT_HEAD(&p->ccb_list, &sccb->ccb_h, periph_links.sle);
+ p->immediate_priority = CAM_PRIORITY_NONE;
+ wakeup(&p->ccb_list);
+ } else
+ xpt_release_ccb(sccb);
+ ENC_DLOG(enc, "%s exit\n", __func__);
+}
+
+void
+enc_done(struct cam_periph *periph, union ccb *dccb)
+{
+ wakeup(&dccb->ccb_h.cbfcnp);
+}
+
+int
+enc_error(union ccb *ccb, uint32_t cflags, uint32_t sflags)
+{
+ struct enc_softc *softc;
+ struct cam_periph *periph;
+
+ periph = xpt_path_periph(ccb->ccb_h.path);
+ softc = (struct enc_softc *)periph->softc;
+
+ return (cam_periph_error(ccb, cflags, sflags, &softc->saved_ccb));
+}
+
+static int
+enc_ioctl(struct cdev *dev, u_long cmd, caddr_t arg_addr, int flag,
+ struct thread *td)
+{
+ struct cam_periph *periph;
+ encioc_enc_status_t tmp;
+ encioc_string_t sstr;
+ encioc_elm_status_t elms;
+ encioc_elm_desc_t elmd;
+ encioc_elm_devnames_t elmdn;
+ encioc_element_t *uelm;
+ enc_softc_t *enc;
+ enc_cache_t *cache;
+ void *addr;
+ int error, i;
+
+
+ if (arg_addr)
+ addr = *((caddr_t *) arg_addr);
+ else
+ addr = NULL;
+
+ periph = (struct cam_periph *)dev->si_drv1;
+ if (periph == NULL)
+ return (ENXIO);
+
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering encioctl\n"));
+
+ cam_periph_lock(periph);
+ enc = (struct enc_softc *)periph->softc;
+ cache = &enc->enc_cache;
+
+ /*
+ * Now check to see whether we're initialized or not.
+ * This actually should never fail as we're not supposed
+ * to get past enc_open w/o successfully initializing
+ * things.
+ */
+ if ((enc->enc_flags & ENC_FLAG_INITIALIZED) == 0) {
+ cam_periph_unlock(periph);
+ return (ENXIO);
+ }
+ cam_periph_unlock(periph);
+
+ error = 0;
+
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
+ ("trying to do ioctl %#lx\n", cmd));
+
+ /*
+ * If this command can change the device's state,
+ * we must have the device open for writing.
+ *
+ * For commands that get information about the
+ * device- we don't need to lock the peripheral
+ * if we aren't running a command. The periph
+ * also can't go away while a user process has
+ * it open.
+ */
+ switch (cmd) {
+ case ENCIOC_GETNELM:
+ case ENCIOC_GETELMMAP:
+ case ENCIOC_GETENCSTAT:
+ case ENCIOC_GETELMSTAT:
+ case ENCIOC_GETELMDESC:
+ case ENCIOC_GETELMDEVNAMES:
+ break;
+ default:
+ if ((flag & FWRITE) == 0) {
+ return (EBADF);
+ }
+ }
+
+ /*
+ * XXX The values read here are only valid for the current
+ * configuration generation. We need these ioctls
+ * to also pass in/out a generation number.
+ */
+ sx_slock(&enc->enc_cache_lock);
+ switch (cmd) {
+ case ENCIOC_GETNELM:
+ error = copyout(&cache->nelms, addr, sizeof (cache->nelms));
+ break;
+
+ case ENCIOC_GETELMMAP:
+ for (uelm = addr, i = 0; i != cache->nelms; i++) {
+ encioc_element_t kelm;
+ kelm.elm_idx = i;
+ kelm.elm_subenc_id = cache->elm_map[i].subenclosure;
+ kelm.elm_type = cache->elm_map[i].enctype;
+ error = copyout(&kelm, &uelm[i], sizeof(kelm));
+ if (error)
+ break;
+ }
+ break;
+
+ case ENCIOC_GETENCSTAT:
+ cam_periph_lock(periph);
+ error = enc->enc_vec.get_enc_status(enc, 1);
+ if (error) {
+ cam_periph_unlock(periph);
+ break;
+ }
+ tmp = cache->enc_status;
+ cam_periph_unlock(periph);
+ error = copyout(&tmp, addr, sizeof(tmp));
+ cache->enc_status = tmp;
+ break;
+
+ case ENCIOC_SETENCSTAT:
+ error = copyin(addr, &tmp, sizeof(tmp));
+ if (error)
+ break;
+ cam_periph_lock(periph);
+ error = enc->enc_vec.set_enc_status(enc, tmp, 1);
+ cam_periph_unlock(periph);
+ break;
+
+ case ENCIOC_GETSTRING:
+ case ENCIOC_SETSTRING:
+ if (enc->enc_vec.handle_string == NULL) {
+ error = EINVAL;
+ break;
+ }
+ error = copyin(addr, &sstr, sizeof(sstr));
+ if (error)
+ break;
+ cam_periph_lock(periph);
+ error = enc->enc_vec.handle_string(enc, &sstr, cmd);
+ cam_periph_unlock(periph);
+ break;
+
+ case ENCIOC_GETELMSTAT:
+ error = copyin(addr, &elms, sizeof(elms));
+ if (error)
+ break;
+ if (elms.elm_idx >= cache->nelms) {
+ error = EINVAL;
+ break;
+ }
+ cam_periph_lock(periph);
+ error = enc->enc_vec.get_elm_status(enc, &elms, 1);
+ cam_periph_unlock(periph);
+ if (error)
+ break;
+ error = copyout(&elms, addr, sizeof(elms));
+ break;
+
+ case ENCIOC_GETELMDESC:
+ error = copyin(addr, &elmd, sizeof(elmd));
+ if (error)
+ break;
+ if (elmd.elm_idx >= cache->nelms) {
+ error = EINVAL;
+ break;
+ }
+ if (enc->enc_vec.get_elm_desc != NULL) {
+ error = enc->enc_vec.get_elm_desc(enc, &elmd);
+ if (error)
+ break;
+ } else
+ elmd.elm_desc_len = 0;
+ error = copyout(&elmd, addr, sizeof(elmd));
+ break;
+
+ case ENCIOC_GETELMDEVNAMES:
+ if (enc->enc_vec.get_elm_devnames == NULL) {
+ error = EINVAL;
+ break;
+ }
+ error = copyin(addr, &elmdn, sizeof(elmdn));
+ if (error)
+ break;
+ if (elmdn.elm_idx >= cache->nelms) {
+ error = EINVAL;
+ break;
+ }
+ cam_periph_lock(periph);
+ error = (*enc->enc_vec.get_elm_devnames)(enc, &elmdn);
+ cam_periph_unlock(periph);
+ if (error)
+ break;
+ error = copyout(&elmdn, addr, sizeof(elmdn));
+ break;
+
+ case ENCIOC_SETELMSTAT:
+ error = copyin(addr, &elms, sizeof(elms));
+ if (error)
+ break;
+
+ if (elms.elm_idx >= cache->nelms) {
+ error = EINVAL;
+ break;
+ }
+ cam_periph_lock(periph);
+ error = enc->enc_vec.set_elm_status(enc, &elms, 1);
+ cam_periph_unlock(periph);
+
+ break;
+
+ case ENCIOC_INIT:
+
+ cam_periph_lock(periph);
+ error = enc->enc_vec.init_enc(enc);
+ cam_periph_unlock(periph);
+ break;
+
+ default:
+ cam_periph_lock(periph);
+ error = cam_periph_ioctl(periph, cmd, arg_addr, enc_error);
+ cam_periph_unlock(periph);
+ break;
+ }
+ sx_sunlock(&enc->enc_cache_lock);
+ return (error);
+}
+
+int
+enc_runcmd(struct enc_softc *enc, char *cdb, int cdbl, char *dptr, int *dlenp)
+{
+ int error, dlen, tdlen;
+ ccb_flags ddf;
+ union ccb *ccb;
+
+ CAM_DEBUG(enc->periph->path, CAM_DEBUG_TRACE,
+ ("entering enc_runcmd\n"));
+ if (dptr) {
+ if ((dlen = *dlenp) < 0) {
+ dlen = -dlen;
+ ddf = CAM_DIR_OUT;
+ } else {
+ ddf = CAM_DIR_IN;
+ }
+ } else {
+ dlen = 0;
+ ddf = CAM_DIR_NONE;
+ }
+
+ if (cdbl > IOCDBLEN) {
+ cdbl = IOCDBLEN;
+ }
+
+ ccb = cam_periph_getccb(enc->periph, 1);
+ if (enc->enc_type == ENC_SEMB_SES || enc->enc_type == ENC_SEMB_SAFT) {
+ tdlen = min(dlen, 1020);
+ tdlen = (tdlen + 3) & ~3;
+ cam_fill_ataio(&ccb->ataio, 0, enc_done, ddf, 0, dptr, tdlen,
+ 30 * 1000);
+ if (cdb[0] == RECEIVE_DIAGNOSTIC)
+ ata_28bit_cmd(&ccb->ataio,
+ ATA_SEP_ATTN, cdb[2], 0x02, tdlen / 4);
+ else if (cdb[0] == SEND_DIAGNOSTIC)
+ ata_28bit_cmd(&ccb->ataio,
+ ATA_SEP_ATTN, dlen > 0 ? dptr[0] : 0,
+ 0x82, tdlen / 4);
+ else if (cdb[0] == READ_BUFFER)
+ ata_28bit_cmd(&ccb->ataio,
+ ATA_SEP_ATTN, cdb[2], 0x00, tdlen / 4);
+ else
+ ata_28bit_cmd(&ccb->ataio,
+ ATA_SEP_ATTN, dlen > 0 ? dptr[0] : 0,
+ 0x80, tdlen / 4);
+ } else {
+ tdlen = dlen;
+ cam_fill_csio(&ccb->csio, 0, enc_done, ddf, MSG_SIMPLE_Q_TAG,
+ dptr, dlen, sizeof (struct scsi_sense_data), cdbl,
+ 60 * 1000);
+ bcopy(cdb, ccb->csio.cdb_io.cdb_bytes, cdbl);
+ }
+
+ error = cam_periph_runccb(ccb, enc_error, ENC_CFLAGS, ENC_FLAGS, NULL);
+ if (error) {
+ if (dptr) {
+ *dlenp = dlen;
+ }
+ } else {
+ if (dptr) {
+ if (ccb->ccb_h.func_code == XPT_ATA_IO)
+ *dlenp = ccb->ataio.resid;
+ else
+ *dlenp = ccb->csio.resid;
+ *dlenp += tdlen - dlen;
+ }
+ }
+ xpt_release_ccb(ccb);
+ CAM_DEBUG(enc->periph->path, CAM_DEBUG_SUBTRACE,
+ ("exiting enc_runcmd: *dlenp = %d\n", *dlenp));
+ return (error);
+}
+
+void
+enc_log(struct enc_softc *enc, const char *fmt, ...)
+{
+ va_list ap;
+
+ printf("%s%d: ", enc->periph->periph_name, enc->periph->unit_number);
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+}
+
+/*
+ * The code after this point runs on many platforms,
+ * so forgive the slightly awkward and nonconforming
+ * appearance.
+ */
+
+/*
+ * Is this a device that supports enclosure services?
+ *
+ * It's a a pretty simple ruleset- if it is device type 0x0D (13), it's
+ * an ENC device. If it happens to be an old UNISYS SEN device, we can
+ * handle that too.
+ */
+
+#define SAFTE_START 44
+#define SAFTE_END 50
+#define SAFTE_LEN SAFTE_END-SAFTE_START
+
+static enctyp
+enc_type(struct ccb_getdev *cgd)
+{
+ int buflen;
+ unsigned char *iqd;
+
+ if (cgd->protocol == PROTO_SEMB) {
+ iqd = (unsigned char *)&cgd->ident_data;
+ if (STRNCMP(iqd + 43, "S-E-S", 5) == 0)
+ return (ENC_SEMB_SES);
+ else if (STRNCMP(iqd + 43, "SAF-TE", 6) == 0)
+ return (ENC_SEMB_SAFT);
+ return (ENC_NONE);
+
+ } else if (cgd->protocol != PROTO_SCSI)
+ return (ENC_NONE);
+
+ iqd = (unsigned char *)&cgd->inq_data;
+ buflen = min(sizeof(cgd->inq_data),
+ SID_ADDITIONAL_LENGTH(&cgd->inq_data));
+ if (buflen < 8+SEN_ID_LEN)
+ return (ENC_NONE);
+
+ if ((iqd[0] & 0x1f) == T_ENCLOSURE) {
+ if (STRNCMP(&iqd[8], SEN_ID, SEN_ID_LEN) == 0) {
+ return (ENC_SEN);
+ } else if ((iqd[2] & 0x7) > 2) {
+ return (ENC_SES);
+ } else {
+ return (ENC_SES_SCSI2);
+ }
+ return (ENC_NONE);
+ }
+
+#ifdef ENC_ENABLE_PASSTHROUGH
+ if ((iqd[6] & 0x40) && (iqd[2] & 0x7) >= 2) {
+ /*
+ * PassThrough Device.
+ */
+ return (ENC_ENC_PASSTHROUGH);
+ }
+#endif
+
+ /*
+ * The comparison is short for a reason-
+ * some vendors were chopping it short.
+ */
+
+ if (buflen < SAFTE_END - 2) {
+ return (ENC_NONE);
+ }
+
+ if (STRNCMP((char *)&iqd[SAFTE_START], "SAF-TE", SAFTE_LEN - 2) == 0) {
+ return (ENC_SAFT);
+ }
+ return (ENC_NONE);
+}
+
+/*================== Enclosure Monitoring/Processing Daemon ==================*/
+/**
+ * \brief Queue an update request for a given action, if needed.
+ *
+ * \param enc SES softc to queue the request for.
+ * \param action Action requested.
+ */
+void
+enc_update_request(enc_softc_t *enc, uint32_t action)
+{
+ if ((enc->pending_actions & (0x1 << action)) == 0) {
+ enc->pending_actions |= (0x1 << action);
+ ENC_DLOG(enc, "%s: queing requested action %d\n",
+ __func__, action);
+ if (enc->current_action == ENC_UPDATE_NONE)
+ wakeup(enc->enc_daemon);
+ } else {
+ ENC_DLOG(enc, "%s: ignoring requested action %d - "
+ "Already queued\n", __func__, action);
+ }
+}
+
+/**
+ * \brief Invoke the handler of the highest priority pending
+ * state in the SES state machine.
+ *
+ * \param enc The SES instance invoking the state machine.
+ */
+static void
+enc_fsm_step(enc_softc_t *enc)
+{
+ union ccb *ccb;
+ uint8_t *buf;
+ struct enc_fsm_state *cur_state;
+ int error;
+ uint32_t xfer_len;
+
+ ENC_DLOG(enc, "%s enter %p\n", __func__, enc);
+
+ enc->current_action = ffs(enc->pending_actions) - 1;
+ enc->pending_actions &= ~(0x1 << enc->current_action);
+
+ cur_state = &enc->enc_fsm_states[enc->current_action];
+
+ buf = NULL;
+ if (cur_state->buf_size != 0) {
+ cam_periph_unlock(enc->periph);
+ buf = malloc(cur_state->buf_size, M_SCSIENC, M_WAITOK|M_ZERO);
+ cam_periph_lock(enc->periph);
+ }
+
+ error = 0;
+ ccb = NULL;
+ if (cur_state->fill != NULL) {
+ ccb = cam_periph_getccb(enc->periph, CAM_PRIORITY_NORMAL);
+
+ error = cur_state->fill(enc, cur_state, ccb, buf);
+ if (error != 0)
+ goto done;
+
+ error = cam_periph_runccb(ccb, cur_state->error,
+ ENC_CFLAGS,
+ ENC_FLAGS|SF_QUIET_IR, NULL);
+ }
+
+ if (ccb != NULL) {
+ if (ccb->ccb_h.func_code == XPT_ATA_IO)
+ xfer_len = ccb->ataio.dxfer_len - ccb->ataio.resid;
+ else
+ xfer_len = ccb->csio.dxfer_len - ccb->csio.resid;
+ } else
+ xfer_len = 0;
+
+ cam_periph_unlock(enc->periph);
+ cur_state->done(enc, cur_state, ccb, &buf, error, xfer_len);
+ cam_periph_lock(enc->periph);
+
+done:
+ ENC_DLOG(enc, "%s exit - result %d\n", __func__, error);
+ ENC_FREE_AND_NULL(buf);
+ if (ccb != NULL)
+ xpt_release_ccb(ccb);
+}
+
+/**
+ * \invariant Called with cam_periph mutex held.
+ */
+static void
+enc_status_updater(void *arg)
+{
+ enc_softc_t *enc;
+
+ enc = arg;
+ if (enc->enc_vec.poll_status != NULL)
+ enc->enc_vec.poll_status(enc);
+}
+
+static void
+enc_daemon(void *arg)
+{
+ enc_softc_t *enc;
+
+ enc = arg;
+
+ cam_periph_lock(enc->periph);
+ while ((enc->enc_flags & ENC_FLAG_SHUTDOWN) == 0) {
+ if (enc->pending_actions == 0) {
+ struct intr_config_hook *hook;
+
+ /*
+ * Reset callout and msleep, or
+ * issue timed task completion
+ * status command.
+ */
+ enc->current_action = ENC_UPDATE_NONE;
+
+ /*
+ * We've been through our state machine at least
+ * once. Allow the transition to userland.
+ */
+ hook = &enc->enc_boot_hold_ch;
+ if (hook->ich_func != NULL) {
+ config_intrhook_disestablish(hook);
+ hook->ich_func = NULL;
+ }
+
+ callout_reset(&enc->status_updater, 60*hz,
+ enc_status_updater, enc);
+
+ cam_periph_sleep(enc->periph, enc->enc_daemon,
+ PUSER, "idle", 0);
+ } else {
+ enc_fsm_step(enc);
+ }
+ }
+ enc->enc_daemon = NULL;
+ cam_periph_unlock(enc->periph);
+ cam_periph_release(enc->periph);
+ kproc_exit(0);
+}
+
+static int
+enc_kproc_init(enc_softc_t *enc)
+{
+ int result;
+
+ callout_init_mtx(&enc->status_updater, enc->periph->sim->mtx, 0);
+
+ if (cam_periph_acquire(enc->periph) != CAM_REQ_CMP)
+ return (ENXIO);
+
+ result = kproc_create(enc_daemon, enc, &enc->enc_daemon, /*flags*/0,
+ /*stackpgs*/0, "enc_daemon%d",
+ enc->periph->unit_number);
+ if (result == 0) {
+ /* Do an initial load of all page data. */
+ cam_periph_lock(enc->periph);
+ enc->enc_vec.poll_status(enc);
+ cam_periph_unlock(enc->periph);
+ } else
+ cam_periph_release(enc->periph);
+ return (result);
+}
+
+/**
+ * \brief Interrupt configuration hook callback associated with
+ * enc_boot_hold_ch.
+ *
+ * Since interrupts are always functional at the time of enclosure
+ * configuration, there is nothing to be done when the callback occurs.
+ * This hook is only registered to hold up boot processing while initial
+ * eclosure processing occurs.
+ *
+ * \param arg The enclosure softc, but currently unused in this callback.
+ */
+static void
+enc_nop_confighook_cb(void *arg __unused)
+{
+}
+
+static cam_status
+enc_ctor(struct cam_periph *periph, void *arg)
+{
+ cam_status status = CAM_REQ_CMP_ERR;
+ int err;
+ enc_softc_t *enc;
+ struct ccb_getdev *cgd;
+ char *tname;
+
+ cgd = (struct ccb_getdev *)arg;
+ if (periph == NULL) {
+ printf("enc_ctor: periph was NULL!!\n");
+ goto out;
+ }
+
+ if (cgd == NULL) {
+ printf("enc_ctor: no getdev CCB, can't register device\n");
+ goto out;
+ }
+
+ enc = ENC_MALLOCZ(sizeof(*enc));
+ if (enc == NULL) {
+ printf("enc_ctor: Unable to probe new device. "
+ "Unable to allocate enc\n");
+ goto out;
+ }
+ enc->periph = periph;
+ enc->current_action = ENC_UPDATE_INVALID;
+
+ enc->enc_type = enc_type(cgd);
+ sx_init(&enc->enc_cache_lock, "enccache");
+
+ switch (enc->enc_type) {
+ case ENC_SES:
+ case ENC_SES_SCSI2:
+ case ENC_SES_PASSTHROUGH:
+ case ENC_SEMB_SES:
+ err = ses_softc_init(enc);
+ break;
+ case ENC_SAFT:
+ case ENC_SEMB_SAFT:
+ err = safte_softc_init(enc);
+ break;
+ case ENC_SEN:
+ case ENC_NONE:
+ default:
+ ENC_FREE(enc);
+ return (CAM_REQ_CMP_ERR);
+ }
+
+ if (err) {
+ xpt_print(periph->path, "error %d initializing\n", err);
+ goto out;
+ }
+
+ /*
+ * Hold off userland until we have made at least one pass
+ * through our state machine so that physical path data is
+ * present.
+ */
+ if (enc->enc_vec.poll_status != NULL) {
+ enc->enc_boot_hold_ch.ich_func = enc_nop_confighook_cb;
+ enc->enc_boot_hold_ch.ich_arg = enc;
+ config_intrhook_establish(&enc->enc_boot_hold_ch);
+ }
+
+ /*
+ * The softc field is set only once the enc is fully initialized
+ * so that we can rely on this field to detect partially
+ * initialized periph objects in the AC_FOUND_DEVICE handler.
+ */
+ periph->softc = enc;
+
+ cam_periph_unlock(periph);
+ if (enc->enc_vec.poll_status != NULL) {
+ err = enc_kproc_init(enc);
+ if (err) {
+ xpt_print(periph->path,
+ "error %d starting enc_daemon\n", err);
+ goto out;
+ }
+ }
+
+ if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
+ xpt_print(periph->path, "%s: lost periph during "
+ "registration!\n", __func__);
+ cam_periph_lock(periph);
+
+ return (CAM_REQ_CMP_ERR);
+ }
+
+ enc->enc_dev = make_dev(&enc_cdevsw, periph->unit_number,
+ UID_ROOT, GID_OPERATOR, 0600, "%s%d",
+ periph->periph_name, periph->unit_number);
+
+ cam_periph_lock(periph);
+ enc->enc_dev->si_drv1 = periph;
+
+ enc->enc_flags |= ENC_FLAG_INITIALIZED;
+
+ /*
+ * Add an async callback so that we get notified if this
+ * device goes away.
+ */
+ xpt_register_async(AC_LOST_DEVICE, enc_async, periph, periph->path);
+
+ switch (enc->enc_type) {
+ default:
+ case ENC_NONE:
+ tname = "No ENC device";
+ break;
+ case ENC_SES_SCSI2:
+ tname = "SCSI-2 ENC Device";
+ break;
+ case ENC_SES:
+ tname = "SCSI-3 ENC Device";
+ break;
+ case ENC_SES_PASSTHROUGH:
+ tname = "ENC Passthrough Device";
+ break;
+ case ENC_SEN:
+ tname = "UNISYS SEN Device (NOT HANDLED YET)";
+ break;
+ case ENC_SAFT:
+ tname = "SAF-TE Compliant Device";
+ break;
+ case ENC_SEMB_SES:
+ tname = "SEMB SES Device";
+ break;
+ case ENC_SEMB_SAFT:
+ tname = "SEMB SAF-TE Device";
+ break;
+ }
+ xpt_announce_periph(periph, tname);
+ status = CAM_REQ_CMP;
+
+out:
+ if (status != CAM_REQ_CMP)
+ enc_dtor(periph);
+ return (status);
+}
+
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_enc.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/cam/scsi/scsi_enc.h Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,219 @@
+/* $FreeBSD: head/sys/cam/scsi/scsi_enc.h 235911 2012-05-24 14:07:44Z mav $ */
+/*-
+ * Copyright (c) 2000 by Matthew Jacob
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * the GNU Public License ("GPL").
+ *
+ * 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.
+ *
+ */
+#ifndef _SCSI_ENC_H_
+#define _SCSI_ENC_H_
+
+#include <cam/scsi/scsi_ses.h>
+
+#define ENCIOC ('s' - 040)
+#define ENCIOC_GETNELM _IO(ENCIOC, 1)
+#define ENCIOC_GETELMMAP _IO(ENCIOC, 2)
+#define ENCIOC_GETENCSTAT _IO(ENCIOC, 3)
+#define ENCIOC_SETENCSTAT _IO(ENCIOC, 4)
+#define ENCIOC_GETELMSTAT _IO(ENCIOC, 5)
+#define ENCIOC_SETELMSTAT _IO(ENCIOC, 6)
+#define ENCIOC_GETTEXT _IO(ENCIOC, 7)
+#define ENCIOC_INIT _IO(ENCIOC, 8)
+#define ENCIOC_GETELMDESC _IO(ENCIOC, 9)
+#define ENCIOC_GETELMDEVNAMES _IO(ENCIOC, 10)
+#define ENCIOC_GETSTRING _IO(ENCIOC, 11)
+#define ENCIOC_SETSTRING _IO(ENCIOC, 12)
+
+/*
+ * Platform Independent Definitions for enclosure devices.
+ */
+/*
+ * SCSI Based Environmental Services Application Defines
+ *
+ * Based almost entirely on SCSI-3 ENC Revision 8A specification,
+ * but slightly abstracted as the underlying device may in fact
+ * be a SAF-TE or vendor unique device.
+ */
+/*
+ * ENC Driver Operations:
+ * (The defines themselves are platform and access method specific)
+ *
+ * ENCIOC_GETNELM
+ * ENCIOC_GETELMMAP
+ * ENCIOC_GETENCSTAT
+ * ENCIOC_SETENCSTAT
+ * ENCIOC_GETELMSTAT
+ * ENCIOC_SETELMSTAT
+ * ENCIOC_INIT
+ *
+ *
+ * An application finds out how many elements an enclosure instance
+ * is managing by performing a ENCIOC_GETNELM operation. It then
+ * performs a ENCIOC_GETELMMAP to get the map that contains the
+ * elment identifiers for all elements (see encioc_element_t below).
+ * This information is static.
+ *
+ * The application may perform ENCIOC_GETELMSTAT operations to retrieve
+ * status on an element (see the enc_elm_status_t structure below),
+ * ENCIOC_SETELMSTAT operations to set status for an element.
+ *
+ * Similarly, overall enclosure status me be fetched or set via
+ * ENCIOC_GETENCSTAT or ENCIOC_SETENCSTAT operations (see encioc_enc_status_t
+ * below).
+ *
+ * Readers should note that there is nothing that requires either a set
+ * or a clear operation to actually latch and do anything in the target.
+ *
+ * A ENCIOC_INIT operation causes the enclosure to be initialized.
+ */
+
+/* Element Types */
+typedef enum {
+ ELMTYP_UNSPECIFIED = 0x00,
+ ELMTYP_DEVICE = 0x01,
+ ELMTYP_POWER = 0x02,
+ ELMTYP_FAN = 0x03,
+ ELMTYP_THERM = 0x04,
+ ELMTYP_DOORLOCK = 0x05,
+ ELMTYP_ALARM = 0x06,
+ ELMTYP_ESCC = 0x07, /* Enclosure SCC */
+ ELMTYP_SCC = 0x08, /* SCC */
+ ELMTYP_NVRAM = 0x09,
+ ELMTYP_INV_OP_REASON = 0x0a,
+ ELMTYP_UPS = 0x0b,
+ ELMTYP_DISPLAY = 0x0c,
+ ELMTYP_KEYPAD = 0x0d,
+ ELMTYP_ENCLOSURE = 0x0e,
+ ELMTYP_SCSIXVR = 0x0f,
+ ELMTYP_LANGUAGE = 0x10,
+ ELMTYP_COMPORT = 0x11,
+ ELMTYP_VOM = 0x12,
+ ELMTYP_AMMETER = 0x13,
+ ELMTYP_SCSI_TGT = 0x14,
+ ELMTYP_SCSI_INI = 0x15,
+ ELMTYP_SUBENC = 0x16,
+ ELMTYP_ARRAY_DEV = 0x17,
+ ELMTYP_SAS_EXP = 0x18, /* SAS expander */
+ ELMTYP_SAS_CONN = 0x19 /* SAS connector */
+} elm_type_t;
+
+typedef struct encioc_element {
+ /* Element Index */
+ unsigned int elm_idx;
+
+ /* ID of SubEnclosure containing Element*/
+ unsigned int elm_subenc_id;
+
+ /* Element Type */
+ elm_type_t elm_type;
+} encioc_element_t;
+
+/*
+ * Overall Enclosure Status
+ */
+typedef unsigned char encioc_enc_status_t;
+
+/*
+ * Element Status
+ */
+typedef struct encioc_elm_status {
+ unsigned int elm_idx;
+ unsigned char cstat[4];
+} encioc_elm_status_t;
+
+/*
+ * ENC String structure, for StringIn and StringOut commands; use this with
+ * the ENCIOC_GETSTRING and ENCIOC_SETSTRING ioctls.
+ */
+typedef struct encioc_string {
+ size_t bufsiz; /* IN/OUT: length of string provided/returned */
+#define ENC_STRING_MAX 0xffff
+ uint8_t *buf; /* IN/OUT: string */
+} encioc_string_t;
+
+/*============================================================================*/
+
+/*
+ * SES v2 r20 6.1.10 (pg 39) - Element Descriptor diagnostic page
+ * Tables 21, 22, and 23
+ */
+typedef struct encioc_elm_desc {
+ unsigned int elm_idx; /* IN: elment requested */
+ uint16_t elm_desc_len; /* IN: buffer size; OUT: bytes written */
+ char *elm_desc_str; /* IN/OUT: buffer for descriptor data */
+} encioc_elm_desc_t;
+
+/*
+ * ENCIOC_GETELMDEVNAMES:
+ * ioctl structure to get an element's device names, if available
+ */
+typedef struct encioc_elm_devnames {
+ unsigned int elm_idx; /* IN: element index */
+ size_t elm_names_size;/* IN: size of elm_devnames */
+ size_t elm_names_len; /* OUT: actual size returned */
+ /*
+ * IN/OUT: comma separated list of peripheral driver
+ * instances servicing this element.
+ */
+ char *elm_devnames;
+} encioc_elm_devnames_t;
+
+/* ioctl structure for requesting FC info for a port */
+typedef struct encioc_elm_fc_port {
+ unsigned int elm_idx;
+ unsigned int port_idx;
+ struct ses_elm_fc_port port_data;
+} encioc_elm_fc_port_t;
+
+/* ioctl structure for requesting SAS info for element phys */
+typedef struct encioc_elm_sas_device_phy {
+ unsigned int elm_idx;
+ unsigned int phy_idx;
+ struct ses_elm_sas_device_phy phy_data;
+} enioc_elm_sas_phy_t;
+
+/* ioctl structure for requesting SAS info for an expander phy */
+typedef struct encioc_elm_sas_expander_phy {
+ unsigned int elm_idx;
+ unsigned int phy_idx;
+ struct ses_elm_sas_expander_phy phy_data;
+} encioc_elm_sas_expander_phy_t;
+
+/* ioctl structure for requesting SAS info for a port phy */
+typedef struct encioc_elm_sas_port_phy {
+ unsigned int elm_idx;
+ unsigned int phy_idx;
+ struct ses_elm_sas_port_phy phy_data;
+} enioc_elm_sas_port_phy_t;
+
+/* ioctl structure for requesting additional status for an element */
+typedef struct encioc_addl_status {
+ unsigned int elm_idx;
+ union ses_elm_addlstatus_descr_hdr addl_hdr;
+ union ses_elm_addlstatus_proto_hdr proto_hdr;
+} enioc_addl_status_t;
+
+#endif /* _SCSI_ENC_H_ */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_enc_internal.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/cam/scsi/scsi_enc_internal.h Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,230 @@
+/*-
+ * Copyright (c) 2000 Matthew Jacob
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: head/sys/cam/scsi/scsi_enc_internal.h 235911 2012-05-24 14:07:44Z mav $
+ */
+
+/*
+ * This file contains definitions only intended for use within
+ * sys/cam/scsi/scsi_enc*.c, and not in other kernel components.
+ */
+
+#ifndef __SCSI_ENC_INTERNAL_H__
+#define __SCSI_ENC_INTERNAL_H__
+
+typedef struct enc_element {
+ uint32_t
+ enctype : 8, /* enclosure type */
+ subenclosure : 8, /* subenclosure id */
+ svalid : 1, /* enclosure information valid */
+ overall_status_elem: 1,/*
+ * This object represents generic
+ * status about all objects of this
+ * type.
+ */
+ priv : 14; /* private data, per object */
+ uint8_t encstat[4]; /* state && stats */
+ uint8_t *physical_path; /* Device physical path data. */
+ u_int physical_path_len; /* Length of device path data. */
+ void *elm_private; /* per-type object data */
+} enc_element_t;
+
+typedef enum {
+ ENC_NONE,
+ ENC_SES_SCSI2,
+ ENC_SES,
+ ENC_SES_PASSTHROUGH,
+ ENC_SEN,
+ ENC_SAFT,
+ ENC_SEMB_SES,
+ ENC_SEMB_SAFT
+} enctyp;
+
+/* Platform Independent Driver Internal Definitions for enclosure devices. */
+typedef struct enc_softc enc_softc_t;
+
+struct enc_fsm_state;
+typedef int fsm_fill_handler_t(enc_softc_t *ssc,
+ struct enc_fsm_state *state,
+ union ccb *ccb,
+ uint8_t *buf);
+typedef int fsm_error_handler_t(union ccb *ccb, uint32_t cflags,
+ uint32_t sflags);
+typedef int fsm_done_handler_t(enc_softc_t *ssc,
+ struct enc_fsm_state *state, union ccb *ccb,
+ uint8_t **bufp, int error, int xfer_len);
+
+struct enc_fsm_state {
+ const char *name;
+ int page_code;
+ size_t buf_size;
+ uint32_t timeout;
+ fsm_fill_handler_t *fill;
+ fsm_done_handler_t *done;
+ fsm_error_handler_t *error;
+};
+
+typedef int (enc_softc_init_t)(enc_softc_t *);
+typedef void (enc_softc_invalidate_t)(enc_softc_t *);
+typedef void (enc_softc_cleanup_t)(enc_softc_t *);
+typedef int (enc_init_enc_t)(enc_softc_t *);
+typedef int (enc_get_enc_status_t)(enc_softc_t *, int);
+typedef int (enc_set_enc_status_t)(enc_softc_t *, encioc_enc_status_t, int);
+typedef int (enc_get_elm_status_t)(enc_softc_t *, encioc_elm_status_t *, int);
+typedef int (enc_set_elm_status_t)(enc_softc_t *, encioc_elm_status_t *, int);
+typedef int (enc_get_elm_desc_t)(enc_softc_t *, encioc_elm_desc_t *);
+typedef int (enc_get_elm_devnames_t)(enc_softc_t *, encioc_elm_devnames_t *);
+typedef int (enc_handle_string_t)(enc_softc_t *, encioc_string_t *, int);
+typedef void (enc_device_found_t)(enc_softc_t *);
+typedef void (enc_poll_status_t)(enc_softc_t *);
+
+struct enc_vec {
+ enc_softc_invalidate_t *softc_invalidate;
+ enc_softc_cleanup_t *softc_cleanup;
+ enc_init_enc_t *init_enc;
+ enc_get_enc_status_t *get_enc_status;
+ enc_set_enc_status_t *set_enc_status;
+ enc_get_elm_status_t *get_elm_status;
+ enc_set_elm_status_t *set_elm_status;
+ enc_get_elm_desc_t *get_elm_desc;
+ enc_get_elm_devnames_t *get_elm_devnames;
+ enc_handle_string_t *handle_string;
+ enc_device_found_t *device_found;
+ enc_poll_status_t *poll_status;
+};
+
+typedef struct enc_cache {
+ enc_element_t *elm_map; /* objects */
+ int nelms; /* number of objects */
+ encioc_enc_status_t enc_status; /* overall status */
+ void *private; /* per-type private data */
+} enc_cache_t;
+
+/* Enclosure instance toplevel structure */
+struct enc_softc {
+ enctyp enc_type; /* type of enclosure */
+ struct enc_vec enc_vec; /* vector to handlers */
+ void *enc_private; /* per-type private data */
+
+ /**
+ * "Published" configuration and state data available to
+ * external consumers.
+ */
+ enc_cache_t enc_cache;
+
+ /**
+ * Configuration and state data being actively updated
+ * by the enclosure daemon.
+ */
+ enc_cache_t enc_daemon_cache;
+
+ struct sx enc_cache_lock;
+ uint8_t enc_flags;
+#define ENC_FLAG_INVALID 0x01
+#define ENC_FLAG_INITIALIZED 0x02
+#define ENC_FLAG_SHUTDOWN 0x04
+ union ccb saved_ccb;
+ struct cdev *enc_dev;
+ struct cam_periph *periph;
+
+ /* Bitmap of pending operations. */
+ uint32_t pending_actions;
+
+ /* The action on which the state machine is currently working. */
+ uint32_t current_action;
+#define ENC_UPDATE_NONE 0x00
+#define ENC_UPDATE_INVALID 0xff
+
+ /* Callout for auto-updating enclosure status */
+ struct callout status_updater;
+
+ struct proc *enc_daemon;
+
+ struct enc_fsm_state *enc_fsm_states;
+
+ struct intr_config_hook enc_boot_hold_ch;
+};
+
+static inline enc_cache_t *
+enc_other_cache(enc_softc_t *enc, enc_cache_t *primary)
+{
+ return (primary == &enc->enc_cache
+ ? &enc->enc_daemon_cache : &enc->enc_cache);
+}
+
+/* SES Management mode page - SES2r20 Table 59 */
+struct ses_mgmt_mode_page {
+ struct scsi_mode_header_6 header;
+ struct scsi_mode_blk_desc blk_desc;
+ uint8_t byte0; /* ps : 1, spf : 1, page_code : 6 */
+#define SES_MGMT_MODE_PAGE_CODE 0x14
+ uint8_t length;
+#define SES_MGMT_MODE_PAGE_LEN 6
+ uint8_t reserved[3];
+ uint8_t byte5; /* reserved : 7, enbltc : 1 */
+#define SES_MGMT_TIMED_COMP_EN 0x1
+ uint8_t max_comp_time[2];
+};
+
+/* Enclosure core interface for sub-drivers */
+int enc_runcmd(struct enc_softc *, char *, int, char *, int *);
+void enc_log(struct enc_softc *, const char *, ...);
+void enc_done(struct cam_periph *, union ccb *);
+int enc_error(union ccb *, uint32_t, uint32_t);
+void enc_update_request(enc_softc_t *, uint32_t);
+
+/* SES Native interface */
+enc_softc_init_t ses_softc_init;
+
+/* SAF-TE interface */
+enc_softc_init_t safte_softc_init;
+
+/* Helper macros */
+MALLOC_DECLARE(M_SCSIENC);
+#define ENC_CFLAGS CAM_RETRY_SELTO
+#define ENC_FLAGS SF_NO_PRINT | SF_RETRY_UA
+#define STRNCMP strncmp
+#define PRINTF printf
+#define ENC_LOG enc_log
+#if defined(DEBUG) || defined(ENC_DEBUG)
+#define ENC_DLOG enc_log
+#else
+#define ENC_DLOG if (0) enc_log
+#endif
+#define ENC_VLOG if (bootverbose) enc_log
+#define ENC_MALLOC(amt) malloc(amt, M_SCSIENC, M_NOWAIT)
+#define ENC_MALLOCZ(amt) malloc(amt, M_SCSIENC, M_ZERO|M_NOWAIT)
+/* Cast away const avoiding GCC warnings. */
+#define ENC_FREE(ptr) free((void *)((uintptr_t)ptr), M_SCSIENC)
+#define ENC_FREE_AND_NULL(ptr) do { \
+ if (ptr != NULL) { \
+ ENC_FREE(ptr); \
+ ptr = NULL; \
+ } \
+} while(0)
+#define MEMZERO bzero
+#define MEMCPY(dest, src, amt) bcopy(src, dest, amt)
+
+#endif /* __SCSI_ENC_INTERNAL_H__ */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_enc_safte.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/cam/scsi/scsi_enc_safte.c Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,1137 @@
+/*-
+ * Copyright (c) 2000 Matthew Jacob
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_enc_safte.c 235911 2012-05-24 14:07:44Z mav $");
+
+#include <sys/param.h>
+
+#include <sys/conf.h>
+#include <sys/errno.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+#include <sys/sx.h>
+#include <sys/systm.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+
+#include <cam/cam.h>
+#include <cam/cam_ccb.h>
+#include <cam/cam_periph.h>
+
+#include <cam/scsi/scsi_enc.h>
+#include <cam/scsi/scsi_enc_internal.h>
+#include <cam/scsi/scsi_message.h>
+
+#include <opt_enc.h>
+
+/*
+ * SAF-TE Type Device Emulation
+ */
+
+static int safte_set_enc_status(enc_softc_t *enc, uint8_t encstat, int slpflag);
+
+#define ALL_ENC_STAT (SES_ENCSTAT_CRITICAL | SES_ENCSTAT_UNRECOV | \
+ SES_ENCSTAT_NONCRITICAL | SES_ENCSTAT_INFO)
+/*
+ * SAF-TE specific defines- Mandatory ones only...
+ */
+
+/*
+ * READ BUFFER ('get' commands) IDs- placed in offset 2 of cdb
+ */
+#define SAFTE_RD_RDCFG 0x00 /* read enclosure configuration */
+#define SAFTE_RD_RDESTS 0x01 /* read enclosure status */
+#define SAFTE_RD_RDDSTS 0x04 /* read drive slot status */
+#define SAFTE_RD_RDGFLG 0x05 /* read global flags */
+
+/*
+ * WRITE BUFFER ('set' commands) IDs- placed in offset 0 of databuf
+ */
+#define SAFTE_WT_DSTAT 0x10 /* write device slot status */
+#define SAFTE_WT_SLTOP 0x12 /* perform slot operation */
+#define SAFTE_WT_FANSPD 0x13 /* set fan speed */
+#define SAFTE_WT_ACTPWS 0x14 /* turn on/off power supply */
+#define SAFTE_WT_GLOBAL 0x15 /* send global command */
+
+#define SAFT_SCRATCH 64
+#define SCSZ 0x8000
+
+typedef enum {
+ SAFTE_UPDATE_NONE,
+ SAFTE_UPDATE_READCONFIG,
+ SAFTE_UPDATE_READGFLAGS,
+ SAFTE_UPDATE_READENCSTATUS,
+ SAFTE_UPDATE_READSLOTSTATUS,
+ SAFTE_PROCESS_CONTROL_REQS,
+ SAFTE_NUM_UPDATE_STATES
+} safte_update_action;
+
+static fsm_fill_handler_t safte_fill_read_buf_io;
+static fsm_fill_handler_t safte_fill_control_request;
+static fsm_done_handler_t safte_process_config;
+static fsm_done_handler_t safte_process_gflags;
+static fsm_done_handler_t safte_process_status;
+static fsm_done_handler_t safte_process_slotstatus;
+static fsm_done_handler_t safte_process_control_request;
+
+static struct enc_fsm_state enc_fsm_states[SAFTE_NUM_UPDATE_STATES] =
+{
+ { "SAFTE_UPDATE_NONE", 0, 0, 0, NULL, NULL, NULL },
+ {
+ "SAFTE_UPDATE_READCONFIG",
+ SAFTE_RD_RDCFG,
+ SAFT_SCRATCH,
+ 60 * 1000,
+ safte_fill_read_buf_io,
+ safte_process_config,
+ enc_error
+ },
+ {
+ "SAFTE_UPDATE_READGFLAGS",
+ SAFTE_RD_RDGFLG,
+ 16,
+ 60 * 1000,
+ safte_fill_read_buf_io,
+ safte_process_gflags,
+ enc_error
+ },
+ {
+ "SAFTE_UPDATE_READENCSTATUS",
+ SAFTE_RD_RDESTS,
+ SCSZ,
+ 60 * 1000,
+ safte_fill_read_buf_io,
+ safte_process_status,
+ enc_error
+ },
+ {
+ "SAFTE_UPDATE_READSLOTSTATUS",
+ SAFTE_RD_RDDSTS,
+ SCSZ,
+ 60 * 1000,
+ safte_fill_read_buf_io,
+ safte_process_slotstatus,
+ enc_error
+ },
+ {
+ "SAFTE_PROCESS_CONTROL_REQS",
+ 0,
+ SCSZ,
+ 60 * 1000,
+ safte_fill_control_request,
+ safte_process_control_request,
+ enc_error
+ }
+};
+
+typedef struct safte_control_request {
+ int elm_idx;
+ uint8_t elm_stat[4];
+ int result;
+ TAILQ_ENTRY(safte_control_request) links;
+} safte_control_request_t;
+TAILQ_HEAD(safte_control_reqlist, safte_control_request);
+typedef struct safte_control_reqlist safte_control_reqlist_t;
+enum {
+ SES_SETSTATUS_ENC_IDX = -1
+};
+
+static void
+safte_terminate_control_requests(safte_control_reqlist_t *reqlist, int result)
+{
+ safte_control_request_t *req;
+
+ while ((req = TAILQ_FIRST(reqlist)) != NULL) {
+ TAILQ_REMOVE(reqlist, req, links);
+ req->result = result;
+ wakeup(req);
+ }
+}
+
+struct scfg {
+ /*
+ * Cached Configuration
+ */
+ uint8_t Nfans; /* Number of Fans */
+ uint8_t Npwr; /* Number of Power Supplies */
+ uint8_t Nslots; /* Number of Device Slots */
+ uint8_t DoorLock; /* Door Lock Installed */
+ uint8_t Ntherm; /* Number of Temperature Sensors */
+ uint8_t Nspkrs; /* Number of Speakers */
+ uint8_t Ntstats; /* Number of Thermostats */
+ /*
+ * Cached Flag Bytes for Global Status
+ */
+ uint8_t flag1;
+ uint8_t flag2;
+ /*
+ * What object index ID is where various slots start.
+ */
+ uint8_t pwroff;
+ uint8_t slotoff;
+#define SAFT_ALARM_OFFSET(cc) (cc)->slotoff - 1
+
+ encioc_enc_status_t adm_status;
+ encioc_enc_status_t enc_status;
+ encioc_enc_status_t slot_status;
+
+ safte_control_reqlist_t requests;
+ safte_control_request_t *current_request;
+ int current_request_stage;
+ int current_request_stages;
+};
+
+#define SAFT_FLG1_ALARM 0x1
+#define SAFT_FLG1_GLOBFAIL 0x2
+#define SAFT_FLG1_GLOBWARN 0x4
+#define SAFT_FLG1_ENCPWROFF 0x8
+#define SAFT_FLG1_ENCFANFAIL 0x10
+#define SAFT_FLG1_ENCPWRFAIL 0x20
+#define SAFT_FLG1_ENCDRVFAIL 0x40
+#define SAFT_FLG1_ENCDRVWARN 0x80
+
+#define SAFT_FLG2_LOCKDOOR 0x4
+#define SAFT_PRIVATE sizeof (struct scfg)
+
+static char *safte_2little = "Too Little Data Returned (%d) at line %d\n";
+#define SAFT_BAIL(r, x) \
+ if ((r) >= (x)) { \
+ ENC_LOG(enc, safte_2little, x, __LINE__);\
+ return (EIO); \
+ }
+
+int emulate_array_devices = 1;
+SYSCTL_DECL(_kern_cam_enc);
+SYSCTL_INT(_kern_cam_enc, OID_AUTO, emulate_array_devices, CTLFLAG_RW,
+ &emulate_array_devices, 0, "Emulate Array Devices for SAF-TE");
+TUNABLE_INT("kern.cam.enc.emulate_array_devices", &emulate_array_devices);
+
+static int
+safte_fill_read_buf_io(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t *buf)
+{
+
+ if (state->page_code != SAFTE_RD_RDCFG &&
+ enc->enc_cache.nelms == 0) {
+ enc_update_request(enc, SAFTE_UPDATE_READCONFIG);
+ return (-1);
+ }
+
+ if (enc->enc_type == ENC_SEMB_SAFT) {
+ semb_read_buffer(&ccb->ataio, /*retries*/5,
+ enc_done, MSG_SIMPLE_Q_TAG,
+ state->page_code, buf, state->buf_size,
+ state->timeout);
+ } else {
+ scsi_read_buffer(&ccb->csio, /*retries*/5,
+ enc_done, MSG_SIMPLE_Q_TAG, 1,
+ state->page_code, 0, buf, state->buf_size,
+ SSD_FULL_SIZE, state->timeout);
+ }
+ return (0);
+}
+
+static int
+safte_process_config(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
+{
+ struct scfg *cfg;
+ uint8_t *buf = *bufp;
+ int i, r;
+
+ cfg = enc->enc_private;
+ if (cfg == NULL)
+ return (ENXIO);
+ if (error != 0)
+ return (error);
+ if (xfer_len < 6) {
+ ENC_LOG(enc, "too little data (%d) for configuration\n",
+ xfer_len);
+ return (EIO);
+ }
+ cfg->Nfans = buf[0];
+ cfg->Npwr = buf[1];
+ cfg->Nslots = buf[2];
+ cfg->DoorLock = buf[3];
+ cfg->Ntherm = buf[4];
+ cfg->Nspkrs = buf[5];
+ if (xfer_len >= 7)
+ cfg->Ntstats = buf[6] & 0x0f;
+ else
+ cfg->Ntstats = 0;
+ ENC_VLOG(enc, "Nfans %d Npwr %d Nslots %d Lck %d Ntherm %d Nspkrs %d "
+ "Ntstats %d\n",
+ cfg->Nfans, cfg->Npwr, cfg->Nslots, cfg->DoorLock, cfg->Ntherm,
+ cfg->Nspkrs, cfg->Ntstats);
+
+ enc->enc_cache.nelms = cfg->Nfans + cfg->Npwr + cfg->Nslots +
+ cfg->DoorLock + cfg->Ntherm + cfg->Nspkrs + cfg->Ntstats + 1;
+ ENC_FREE_AND_NULL(enc->enc_cache.elm_map);
+ enc->enc_cache.elm_map =
+ ENC_MALLOCZ(enc->enc_cache.nelms * sizeof(enc_element_t));
+ if (enc->enc_cache.elm_map == NULL) {
+ enc->enc_cache.nelms = 0;
+ return (ENOMEM);
+ }
+
+ r = 0;
+ /*
+ * Note that this is all arranged for the convenience
+ * in later fetches of status.
+ */
+ for (i = 0; i < cfg->Nfans; i++)
+ enc->enc_cache.elm_map[r++].enctype = ELMTYP_FAN;
+ cfg->pwroff = (uint8_t) r;
+ for (i = 0; i < cfg->Npwr; i++)
+ enc->enc_cache.elm_map[r++].enctype = ELMTYP_POWER;
+ for (i = 0; i < cfg->DoorLock; i++)
+ enc->enc_cache.elm_map[r++].enctype = ELMTYP_DOORLOCK;
+ if (cfg->Nspkrs > 0)
+ enc->enc_cache.elm_map[r++].enctype = ELMTYP_ALARM;
+ for (i = 0; i < cfg->Ntherm; i++)
+ enc->enc_cache.elm_map[r++].enctype = ELMTYP_THERM;
+ for (i = 0; i <= cfg->Ntstats; i++)
+ enc->enc_cache.elm_map[r++].enctype = ELMTYP_THERM;
+ cfg->slotoff = (uint8_t) r;
+ for (i = 0; i < cfg->Nslots; i++)
+ enc->enc_cache.elm_map[r++].enctype =
+ emulate_array_devices ? ELMTYP_ARRAY_DEV :
+ ELMTYP_DEVICE;
+
+ enc_update_request(enc, SAFTE_UPDATE_READGFLAGS);
+ enc_update_request(enc, SAFTE_UPDATE_READENCSTATUS);
+ enc_update_request(enc, SAFTE_UPDATE_READSLOTSTATUS);
+
+ return (0);
+}
+
+static int
+safte_process_gflags(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
+{
+ struct scfg *cfg;
+ uint8_t *buf = *bufp;
+
+ cfg = enc->enc_private;
+ if (cfg == NULL)
+ return (ENXIO);
+ if (error != 0)
+ return (error);
+ SAFT_BAIL(3, xfer_len);
+ cfg->flag1 = buf[1];
+ cfg->flag2 = buf[2];
+
+ cfg->adm_status = 0;
+ if (cfg->flag1 & SAFT_FLG1_GLOBFAIL)
+ cfg->adm_status |= SES_ENCSTAT_CRITICAL;
+ else if (cfg->flag1 & SAFT_FLG1_GLOBWARN)
+ cfg->adm_status |= SES_ENCSTAT_NONCRITICAL;
+
+ return (0);
+}
+
+static int
+safte_process_status(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
+{
+ struct scfg *cfg;
+ uint8_t *buf = *bufp;
+ int oid, r, i, nitems;
+ uint16_t tempflags;
+ enc_cache_t *cache = &enc->enc_cache;
+
+ cfg = enc->enc_private;
+ if (cfg == NULL)
+ return (ENXIO);
+ if (error != 0)
+ return (error);
+
+ oid = r = 0;
+ cfg->enc_status = 0;
+
+ for (nitems = i = 0; i < cfg->Nfans; i++) {
+ SAFT_BAIL(r, xfer_len);
+ /*
+ * 0 = Fan Operational
+ * 1 = Fan is malfunctioning
+ * 2 = Fan is not present
+ * 0x80 = Unknown or Not Reportable Status
+ */
+ cache->elm_map[oid].encstat[1] = 0; /* resvd */
+ cache->elm_map[oid].encstat[2] = 0; /* resvd */
+ if (cfg->flag1 & SAFT_FLG1_ENCFANFAIL)
+ cache->elm_map[oid].encstat[3] |= 0x40;
+ else
+ cache->elm_map[oid].encstat[3] &= ~0x40;
+ switch ((int)buf[r]) {
+ case 0:
+ nitems++;
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
+ if ((cache->elm_map[oid].encstat[3] & 0x37) == 0)
+ cache->elm_map[oid].encstat[3] |= 0x27;
+ break;
+
+ case 1:
+ cache->elm_map[oid].encstat[0] =
+ SES_OBJSTAT_CRIT;
+ /*
+ * FAIL and FAN STOPPED synthesized
+ */
+ cache->elm_map[oid].encstat[3] |= 0x10;
+ cache->elm_map[oid].encstat[3] &= ~0x07;
+ /*
+ * Enclosure marked with CRITICAL error
+ * if only one fan or no thermometers,
+ * else the NONCRITICAL error is set.
+ */
+ if (cfg->Nfans == 1 || (cfg->Ntherm + cfg->Ntstats) == 0)
+ cfg->enc_status |= SES_ENCSTAT_CRITICAL;
+ else
+ cfg->enc_status |= SES_ENCSTAT_NONCRITICAL;
+ break;
+ case 2:
+ cache->elm_map[oid].encstat[0] =
+ SES_OBJSTAT_NOTINSTALLED;
+ cache->elm_map[oid].encstat[3] |= 0x10;
+ cache->elm_map[oid].encstat[3] &= ~0x07;
+ /*
+ * Enclosure marked with CRITICAL error
+ * if only one fan or no thermometers,
+ * else the NONCRITICAL error is set.
+ */
+ if (cfg->Nfans == 1)
+ cfg->enc_status |= SES_ENCSTAT_CRITICAL;
+ else
+ cfg->enc_status |= SES_ENCSTAT_NONCRITICAL;
+ break;
+ case 0x80:
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_UNKNOWN;
+ cache->elm_map[oid].encstat[3] = 0;
+ cfg->enc_status |= SES_ENCSTAT_INFO;
+ break;
+ default:
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_UNSUPPORTED;
+ ENC_LOG(enc, "Unknown fan%d status 0x%x\n", i,
+ buf[r] & 0xff);
+ break;
+ }
+ cache->elm_map[oid++].svalid = 1;
+ r++;
+ }
+
+ /*
+ * No matter how you cut it, no cooling elements when there
+ * should be some there is critical.
+ */
+ if (cfg->Nfans && nitems == 0)
+ cfg->enc_status |= SES_ENCSTAT_CRITICAL;
+
+ for (i = 0; i < cfg->Npwr; i++) {
+ SAFT_BAIL(r, xfer_len);
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_UNKNOWN;
+ cache->elm_map[oid].encstat[1] = 0; /* resvd */
+ cache->elm_map[oid].encstat[2] = 0; /* resvd */
+ cache->elm_map[oid].encstat[3] = 0x20; /* requested on */
+ switch (buf[r]) {
+ case 0x00: /* pws operational and on */
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
+ break;
+ case 0x01: /* pws operational and off */
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
+ cache->elm_map[oid].encstat[3] = 0x10;
+ cfg->enc_status |= SES_ENCSTAT_INFO;
+ break;
+ case 0x10: /* pws is malfunctioning and commanded on */
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_CRIT;
+ cache->elm_map[oid].encstat[3] = 0x61;
+ cfg->enc_status |= SES_ENCSTAT_NONCRITICAL;
+ break;
+
+ case 0x11: /* pws is malfunctioning and commanded off */
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_NONCRIT;
+ cache->elm_map[oid].encstat[3] = 0x51;
+ cfg->enc_status |= SES_ENCSTAT_NONCRITICAL;
+ break;
+ case 0x20: /* pws is not present */
+ cache->elm_map[oid].encstat[0] =
+ SES_OBJSTAT_NOTINSTALLED;
+ cache->elm_map[oid].encstat[3] = 0;
+ cfg->enc_status |= SES_ENCSTAT_INFO;
+ break;
+ case 0x21: /* pws is present */
+ /*
+ * This is for enclosures that cannot tell whether the
+ * device is on or malfunctioning, but know that it is
+ * present. Just fall through.
+ */
+ /* FALLTHROUGH */
+ case 0x80: /* Unknown or Not Reportable Status */
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_UNKNOWN;
+ cache->elm_map[oid].encstat[3] = 0;
+ cfg->enc_status |= SES_ENCSTAT_INFO;
+ break;
+ default:
+ ENC_LOG(enc, "unknown power supply %d status (0x%x)\n",
+ i, buf[r] & 0xff);
+ break;
+ }
+ enc->enc_cache.elm_map[oid++].svalid = 1;
+ r++;
+ }
+
+ /*
+ * Copy Slot SCSI IDs
+ */
+ for (i = 0; i < cfg->Nslots; i++) {
+ SAFT_BAIL(r, xfer_len);
+ if (cache->elm_map[cfg->slotoff + i].enctype == ELMTYP_DEVICE)
+ cache->elm_map[cfg->slotoff + i].encstat[1] = buf[r];
+ r++;
+ }
+
+ /*
+ * We always have doorlock status, no matter what,
+ * but we only save the status if we have one.
+ */
+ SAFT_BAIL(r, xfer_len);
+ if (cfg->DoorLock) {
+ /*
+ * 0 = Door Locked
+ * 1 = Door Unlocked, or no Lock Installed
+ * 0x80 = Unknown or Not Reportable Status
+ */
+ cache->elm_map[oid].encstat[1] = 0;
+ cache->elm_map[oid].encstat[2] = 0;
+ switch (buf[r]) {
+ case 0:
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
+ cache->elm_map[oid].encstat[3] = 0;
+ break;
+ case 1:
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
+ cache->elm_map[oid].encstat[3] = 1;
+ break;
+ case 0x80:
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_UNKNOWN;
+ cache->elm_map[oid].encstat[3] = 0;
+ cfg->enc_status |= SES_ENCSTAT_INFO;
+ break;
+ default:
+ cache->elm_map[oid].encstat[0] =
+ SES_OBJSTAT_UNSUPPORTED;
+ ENC_LOG(enc, "unknown lock status 0x%x\n",
+ buf[r] & 0xff);
+ break;
+ }
+ cache->elm_map[oid++].svalid = 1;
+ }
+ r++;
+
+ /*
+ * We always have speaker status, no matter what,
+ * but we only save the status if we have one.
+ */
+ SAFT_BAIL(r, xfer_len);
+ if (cfg->Nspkrs) {
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
+ cache->elm_map[oid].encstat[1] = 0;
+ cache->elm_map[oid].encstat[2] = 0;
+ if (buf[r] == 0) {
+ cache->elm_map[oid].encstat[0] |= SESCTL_DISABLE;
+ cache->elm_map[oid].encstat[3] |= 0x40;
+ }
+ cache->elm_map[oid++].svalid = 1;
+ }
+ r++;
+
+ /*
+ * Now, for "pseudo" thermometers, we have two bytes
+ * of information in enclosure status- 16 bits. Actually,
+ * the MSB is a single TEMP ALERT flag indicating whether
+ * any other bits are set, but, thanks to fuzzy thinking,
+ * in the SAF-TE spec, this can also be set even if no
+ * other bits are set, thus making this really another
+ * binary temperature sensor.
+ */
+
+ SAFT_BAIL(r + cfg->Ntherm, xfer_len);
+ tempflags = buf[r + cfg->Ntherm];
+ SAFT_BAIL(r + cfg->Ntherm + 1, xfer_len);
+ tempflags |= (tempflags << 8) | buf[r + cfg->Ntherm + 1];
+
+ for (i = 0; i < cfg->Ntherm; i++) {
+ SAFT_BAIL(r, xfer_len);
+ /*
+ * Status is a range from -10 to 245 deg Celsius,
+ * which we need to normalize to -20 to -245 according
+ * to the latest SCSI spec, which makes little
+ * sense since this would overflow an 8bit value.
+ * Well, still, the base normalization is -20,
+ * not -10, so we have to adjust.
+ *
+ * So what's over and under temperature?
+ * Hmm- we'll state that 'normal' operating
+ * is 10 to 40 deg Celsius.
+ */
+
+ /*
+ * Actually.... All of the units that people out in the world
+ * seem to have do not come even close to setting a value that
+ * complies with this spec.
+ *
+ * The closest explanation I could find was in an
+ * LSI-Logic manual, which seemed to indicate that
+ * this value would be set by whatever the I2C code
+ * would interpolate from the output of an LM75
+ * temperature sensor.
+ *
+ * This means that it is impossible to use the actual
+ * numeric value to predict anything. But we don't want
+ * to lose the value. So, we'll propagate the *uncorrected*
+ * value and set SES_OBJSTAT_NOTAVAIL. We'll depend on the
+ * temperature flags for warnings.
+ */
+ if (tempflags & (1 << i)) {
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_CRIT;
+ cfg->enc_status |= SES_ENCSTAT_CRITICAL;
+ } else
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
+ cache->elm_map[oid].encstat[1] = 0;
+ cache->elm_map[oid].encstat[2] = buf[r];
+ cache->elm_map[oid].encstat[3] = 0;
+ cache->elm_map[oid++].svalid = 1;
+ r++;
+ }
+
+ for (i = 0; i <= cfg->Ntstats; i++) {
+ cache->elm_map[oid].encstat[1] = 0;
+ if (tempflags & (1 <<
+ ((i == cfg->Ntstats) ? 15 : (cfg->Ntherm + i)))) {
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_CRIT;
+ cache->elm_map[4].encstat[2] = 0xff;
+ /*
+ * Set 'over temperature' failure.
+ */
+ cache->elm_map[oid].encstat[3] = 8;
+ cfg->enc_status |= SES_ENCSTAT_CRITICAL;
+ } else {
+ /*
+ * We used to say 'not available' and synthesize a
+ * nominal 30 deg (C)- that was wrong. Actually,
+ * Just say 'OK', and use the reserved value of
+ * zero.
+ */
+ if ((cfg->Ntherm + cfg->Ntstats) == 0)
+ cache->elm_map[oid].encstat[0] =
+ SES_OBJSTAT_NOTAVAIL;
+ else
+ cache->elm_map[oid].encstat[0] =
+ SES_OBJSTAT_OK;
+ cache->elm_map[oid].encstat[2] = 0;
+ cache->elm_map[oid].encstat[3] = 0;
+ }
+ cache->elm_map[oid++].svalid = 1;
+ }
+ r += 2;
+
+ cache->enc_status =
+ cfg->enc_status | cfg->slot_status | cfg->adm_status;
+ return (0);
+}
+
+static int
+safte_process_slotstatus(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
+{
+ struct scfg *cfg;
+ uint8_t *buf = *bufp;
+ enc_cache_t *cache = &enc->enc_cache;
+ int oid, r, i;
+
+ cfg = enc->enc_private;
+ if (cfg == NULL)
+ return (ENXIO);
+ if (error != 0)
+ return (error);
+ cfg->slot_status = 0;
+ oid = cfg->slotoff;
+ for (r = i = 0; i < cfg->Nslots; i++, r += 4) {
+ SAFT_BAIL(r+3, xfer_len);
+ if (cache->elm_map[oid].enctype == ELMTYP_ARRAY_DEV)
+ cache->elm_map[oid].encstat[1] = 0;
+ cache->elm_map[oid].encstat[2] &= SESCTL_RQSID;
+ cache->elm_map[oid].encstat[3] = 0;
+ if ((buf[r+3] & 0x01) == 0) { /* no device */
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_NOTINSTALLED;
+ } else if (buf[r+0] & 0x02) {
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_CRIT;
+ cfg->slot_status |= SES_ENCSTAT_CRITICAL;
+ } else if (buf[r+0] & 0x40) {
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_NONCRIT;
+ cfg->slot_status |= SES_ENCSTAT_NONCRITICAL;
+ } else {
+ cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
+ }
+ if (buf[r+3] & 0x2) {
+ if (buf[r+3] & 0x01)
+ cache->elm_map[oid].encstat[2] |= SESCTL_RQSRMV;
+ else
+ cache->elm_map[oid].encstat[2] |= SESCTL_RQSINS;
+ }
+ if ((buf[r+3] & 0x04) == 0)
+ cache->elm_map[oid].encstat[3] |= SESCTL_DEVOFF;
+ if (buf[r+0] & 0x02)
+ cache->elm_map[oid].encstat[3] |= SESCTL_RQSFLT;
+ if (buf[r+0] & 0x40)
+ cache->elm_map[oid].encstat[0] |= SESCTL_PRDFAIL;
+ if (cache->elm_map[oid].enctype == ELMTYP_ARRAY_DEV) {
+ if (buf[r+0] & 0x01)
+ cache->elm_map[oid].encstat[1] |= 0x80;
+ if (buf[r+0] & 0x04)
+ cache->elm_map[oid].encstat[1] |= 0x02;
+ if (buf[r+0] & 0x08)
+ cache->elm_map[oid].encstat[1] |= 0x04;
+ if (buf[r+0] & 0x10)
+ cache->elm_map[oid].encstat[1] |= 0x08;
+ if (buf[r+0] & 0x20)
+ cache->elm_map[oid].encstat[1] |= 0x10;
+ if (buf[r+1] & 0x01)
+ cache->elm_map[oid].encstat[1] |= 0x20;
+ if (buf[r+1] & 0x02)
+ cache->elm_map[oid].encstat[1] |= 0x01;
+ }
+ cache->elm_map[oid++].svalid = 1;
+ }
+
+ cache->enc_status =
+ cfg->enc_status | cfg->slot_status | cfg->adm_status;
+ return (0);
+}
+
+static int
+safte_fill_control_request(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t *buf)
+{
+ struct scfg *cfg;
+ enc_element_t *ep, *ep1;
+ safte_control_request_t *req;
+ int i, idx, xfer_len;
+
+ cfg = enc->enc_private;
+ if (cfg == NULL)
+ return (ENXIO);
+
+ if (enc->enc_cache.nelms == 0) {
+ enc_update_request(enc, SAFTE_UPDATE_READCONFIG);
+ return (-1);
+ }
+
+ if (cfg->current_request == NULL) {
+ cfg->current_request = TAILQ_FIRST(&cfg->requests);
+ TAILQ_REMOVE(&cfg->requests, cfg->current_request, links);
+ cfg->current_request_stage = 0;
+ cfg->current_request_stages = 1;
+ }
+ req = cfg->current_request;
+
+ idx = (int)req->elm_idx;
+ if (req->elm_idx == SES_SETSTATUS_ENC_IDX) {
+ cfg->adm_status = req->elm_stat[0] & ALL_ENC_STAT;
+ cfg->flag1 &= ~(SAFT_FLG1_GLOBFAIL|SAFT_FLG1_GLOBWARN);
+ if (req->elm_stat[0] & (SES_ENCSTAT_CRITICAL|SES_ENCSTAT_UNRECOV))
+ cfg->flag1 |= SAFT_FLG1_GLOBFAIL;
+ else if (req->elm_stat[0] & SES_ENCSTAT_NONCRITICAL)
+ cfg->flag1 |= SAFT_FLG1_GLOBWARN;
+ buf[0] = SAFTE_WT_GLOBAL;
+ buf[1] = cfg->flag1;
+ buf[2] = cfg->flag2;
+ buf[3] = 0;
+ xfer_len = 16;
+ } else {
+ ep = &enc->enc_cache.elm_map[idx];
+
+ switch (ep->enctype) {
+ case ELMTYP_DEVICE:
+ case ELMTYP_ARRAY_DEV:
+ switch (cfg->current_request_stage) {
+ case 0:
+ ep->priv = 0;
+ if (req->elm_stat[0] & SESCTL_PRDFAIL)
+ ep->priv |= 0x40;
+ if (req->elm_stat[3] & SESCTL_RQSFLT)
+ ep->priv |= 0x02;
+ if (ep->enctype == ELMTYP_ARRAY_DEV) {
+ if (req->elm_stat[1] & 0x01)
+ ep->priv |= 0x200;
+ if (req->elm_stat[1] & 0x02)
+ ep->priv |= 0x04;
+ if (req->elm_stat[1] & 0x04)
+ ep->priv |= 0x08;
+ if (req->elm_stat[1] & 0x08)
+ ep->priv |= 0x10;
+ if (req->elm_stat[1] & 0x10)
+ ep->priv |= 0x20;
+ if (req->elm_stat[1] & 0x20)
+ ep->priv |= 0x100;
+ if (req->elm_stat[1] & 0x80)
+ ep->priv |= 0x01;
+ }
+ if (ep->priv == 0)
+ ep->priv |= 0x01; /* no errors */
+
+ buf[0] = SAFTE_WT_DSTAT;
+ for (i = 0; i < cfg->Nslots; i++) {
+ ep1 = &enc->enc_cache.elm_map[cfg->slotoff + i];
+ buf[1 + (3 * i)] = ep1->priv;
+ buf[2 + (3 * i)] = ep1->priv >> 8;
+ }
+ xfer_len = cfg->Nslots * 3 + 1;
+#define DEVON(x) (!(((x)[2] & SESCTL_RQSINS) | \
+ ((x)[2] & SESCTL_RQSRMV) | \
+ ((x)[3] & SESCTL_DEVOFF)))
+ if (DEVON(req->elm_stat) != DEVON(ep->encstat))
+ cfg->current_request_stages++;
+#define IDON(x) (!!((x)[2] & SESCTL_RQSID))
+ if (IDON(req->elm_stat) != IDON(ep->encstat))
+ cfg->current_request_stages++;
+ break;
+ case 1:
+ case 2:
+ buf[0] = SAFTE_WT_SLTOP;
+ buf[1] = idx - cfg->slotoff;
+ if (cfg->current_request_stage == 1 &&
+ DEVON(req->elm_stat) != DEVON(ep->encstat)) {
+ if (DEVON(req->elm_stat))
+ buf[2] = 0x01;
+ else
+ buf[2] = 0x02;
+ } else {
+ if (IDON(req->elm_stat))
+ buf[2] = 0x04;
+ else
+ buf[2] = 0x00;
+ ep->encstat[2] &= ~SESCTL_RQSID;
+ ep->encstat[2] |= req->elm_stat[2] &
+ SESCTL_RQSID;
+ }
+ xfer_len = 64;
+ break;
+ default:
+ return (EINVAL);
+ }
+ break;
+ case ELMTYP_POWER:
+ cfg->current_request_stages = 2;
+ switch (cfg->current_request_stage) {
+ case 0:
+ if (req->elm_stat[3] & SESCTL_RQSTFAIL) {
+ cfg->flag1 |= SAFT_FLG1_ENCPWRFAIL;
+ } else {
+ cfg->flag1 &= ~SAFT_FLG1_ENCPWRFAIL;
+ }
+ buf[0] = SAFTE_WT_GLOBAL;
+ buf[1] = cfg->flag1;
+ buf[2] = cfg->flag2;
+ buf[3] = 0;
+ xfer_len = 16;
+ break;
+ case 1:
+ buf[0] = SAFTE_WT_ACTPWS;
+ buf[1] = idx - cfg->pwroff;
+ if (req->elm_stat[3] & SESCTL_RQSTON)
+ buf[2] = 0x01;
+ else
+ buf[2] = 0x00;
+ buf[3] = 0;
+ xfer_len = 16;
+ default:
+ return (EINVAL);
+ }
+ break;
+ case ELMTYP_FAN:
+ if ((req->elm_stat[3] & 0x7) != 0)
+ cfg->current_request_stages = 2;
+ switch (cfg->current_request_stage) {
+ case 0:
+ if (req->elm_stat[3] & SESCTL_RQSTFAIL)
+ cfg->flag1 |= SAFT_FLG1_ENCFANFAIL;
+ else
+ cfg->flag1 &= ~SAFT_FLG1_ENCFANFAIL;
+ buf[0] = SAFTE_WT_GLOBAL;
+ buf[1] = cfg->flag1;
+ buf[2] = cfg->flag2;
+ buf[3] = 0;
+ xfer_len = 16;
+ break;
+ case 1:
+ buf[0] = SAFTE_WT_FANSPD;
+ buf[1] = idx;
+ if (req->elm_stat[3] & SESCTL_RQSTON) {
+ if ((req->elm_stat[3] & 0x7) == 7)
+ buf[2] = 4;
+ else if ((req->elm_stat[3] & 0x7) >= 5)
+ buf[2] = 3;
+ else if ((req->elm_stat[3] & 0x7) >= 3)
+ buf[2] = 2;
+ else
+ buf[2] = 1;
+ } else
+ buf[2] = 0;
+ buf[3] = 0;
+ xfer_len = 16;
+ ep->encstat[3] = req->elm_stat[3] & 0x67;
+ default:
+ return (EINVAL);
+ }
+ break;
+ case ELMTYP_DOORLOCK:
+ if (req->elm_stat[3] & 0x1)
+ cfg->flag2 &= ~SAFT_FLG2_LOCKDOOR;
+ else
+ cfg->flag2 |= SAFT_FLG2_LOCKDOOR;
+ buf[0] = SAFTE_WT_GLOBAL;
+ buf[1] = cfg->flag1;
+ buf[2] = cfg->flag2;
+ buf[3] = 0;
+ xfer_len = 16;
+ break;
+ case ELMTYP_ALARM:
+ if ((req->elm_stat[0] & SESCTL_DISABLE) ||
+ (req->elm_stat[3] & 0x40)) {
+ cfg->flag2 &= ~SAFT_FLG1_ALARM;
+ } else if ((req->elm_stat[3] & 0x0f) != 0) {
+ cfg->flag2 |= SAFT_FLG1_ALARM;
+ } else {
+ cfg->flag2 &= ~SAFT_FLG1_ALARM;
+ }
+ buf[0] = SAFTE_WT_GLOBAL;
+ buf[1] = cfg->flag1;
+ buf[2] = cfg->flag2;
+ buf[3] = 0;
+ xfer_len = 16;
+ ep->encstat[3] = req->elm_stat[3];
+ break;
+ default:
+ return (EINVAL);
+ }
+ }
+
+ if (enc->enc_type == ENC_SEMB_SAFT) {
+ semb_write_buffer(&ccb->ataio, /*retries*/5,
+ enc_done, MSG_SIMPLE_Q_TAG,
+ buf, xfer_len, state->timeout);
+ } else {
+ scsi_write_buffer(&ccb->csio, /*retries*/5,
+ enc_done, MSG_SIMPLE_Q_TAG, 1,
+ 0, 0, buf, xfer_len,
+ SSD_FULL_SIZE, state->timeout);
+ }
+ return (0);
+}
+
+static int
+safte_process_control_request(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
+{
+ struct scfg *cfg;
+ safte_control_request_t *req;
+ int idx, type;
+
+ cfg = enc->enc_private;
+ if (cfg == NULL)
+ return (ENXIO);
+
+ req = cfg->current_request;
+ if (req->result == 0)
+ req->result = error;
+ if (++cfg->current_request_stage >= cfg->current_request_stages) {
+ idx = req->elm_idx;
+ if (idx == SES_SETSTATUS_ENC_IDX)
+ type = -1;
+ else
+ type = enc->enc_cache.elm_map[idx].enctype;
+ if (type == ELMTYP_DEVICE || type == ELMTYP_ARRAY_DEV)
+ enc_update_request(enc, SAFTE_UPDATE_READSLOTSTATUS);
+ else
+ enc_update_request(enc, SAFTE_UPDATE_READENCSTATUS);
+ cfg->current_request = NULL;
+ wakeup(req);
+ } else {
+ enc_update_request(enc, SAFTE_PROCESS_CONTROL_REQS);
+ }
+ return (0);
+}
+
+static void
+safte_softc_invalidate(enc_softc_t *enc)
+{
+ struct scfg *cfg;
+
+ cfg = enc->enc_private;
+ safte_terminate_control_requests(&cfg->requests, ENXIO);
+}
+
+static void
+safte_softc_cleanup(enc_softc_t *enc)
+{
+
+ ENC_FREE_AND_NULL(enc->enc_cache.elm_map);
+ ENC_FREE_AND_NULL(enc->enc_private);
+ enc->enc_cache.nelms = 0;
+}
+
+static int
+safte_init_enc(enc_softc_t *enc)
+{
+ struct scfg *cfg;
+ int err;
+ static char cdb0[6] = { SEND_DIAGNOSTIC };
+
+ cfg = enc->enc_private;
+ if (cfg == NULL)
+ return (ENXIO);
+
+ err = enc_runcmd(enc, cdb0, 6, NULL, 0);
+ if (err) {
+ return (err);
+ }
+ DELAY(5000);
+ cfg->flag1 = 0;
+ cfg->flag2 = 0;
+ err = safte_set_enc_status(enc, 0, 1);
+ return (err);
+}
+
+static int
+safte_get_enc_status(enc_softc_t *enc, int slpflg)
+{
+
+ return (0);
+}
+
+static int
+safte_set_enc_status(enc_softc_t *enc, uint8_t encstat, int slpflag)
+{
+ struct scfg *cfg;
+ safte_control_request_t req;
+
+ cfg = enc->enc_private;
+ if (cfg == NULL)
+ return (ENXIO);
+
+ req.elm_idx = SES_SETSTATUS_ENC_IDX;
+ req.elm_stat[0] = encstat & 0xf;
+ req.result = 0;
+
+ TAILQ_INSERT_TAIL(&cfg->requests, &req, links);
+ enc_update_request(enc, SAFTE_PROCESS_CONTROL_REQS);
+ cam_periph_sleep(enc->periph, &req, PUSER, "encstat", 0);
+
+ return (req.result);
+}
+
+static int
+safte_get_elm_status(enc_softc_t *enc, encioc_elm_status_t *elms, int slpflg)
+{
+ int i = (int)elms->elm_idx;
+
+ elms->cstat[0] = enc->enc_cache.elm_map[i].encstat[0];
+ elms->cstat[1] = enc->enc_cache.elm_map[i].encstat[1];
+ elms->cstat[2] = enc->enc_cache.elm_map[i].encstat[2];
+ elms->cstat[3] = enc->enc_cache.elm_map[i].encstat[3];
+ return (0);
+}
+
+static int
+safte_set_elm_status(enc_softc_t *enc, encioc_elm_status_t *elms, int slpflag)
+{
+ struct scfg *cfg;
+ safte_control_request_t req;
+
+ cfg = enc->enc_private;
+ if (cfg == NULL)
+ return (ENXIO);
+
+ /* If this is clear, we don't do diddly. */
+ if ((elms->cstat[0] & SESCTL_CSEL) == 0)
+ return (0);
+
+ req.elm_idx = elms->elm_idx;
+ memcpy(&req.elm_stat, elms->cstat, sizeof(req.elm_stat));
+ req.result = 0;
+
+ TAILQ_INSERT_TAIL(&cfg->requests, &req, links);
+ enc_update_request(enc, SAFTE_PROCESS_CONTROL_REQS);
+ cam_periph_sleep(enc->periph, &req, PUSER, "encstat", 0);
+
+ return (req.result);
+}
+
+static void
+safte_poll_status(enc_softc_t *enc)
+{
+
+ enc_update_request(enc, SAFTE_UPDATE_READENCSTATUS);
+ enc_update_request(enc, SAFTE_UPDATE_READSLOTSTATUS);
+}
+
+static struct enc_vec safte_enc_vec =
+{
+ .softc_invalidate = safte_softc_invalidate,
+ .softc_cleanup = safte_softc_cleanup,
+ .init_enc = safte_init_enc,
+ .get_enc_status = safte_get_enc_status,
+ .set_enc_status = safte_set_enc_status,
+ .get_elm_status = safte_get_elm_status,
+ .set_elm_status = safte_set_elm_status,
+ .poll_status = safte_poll_status
+};
+
+int
+safte_softc_init(enc_softc_t *enc)
+{
+ struct scfg *cfg;
+
+ enc->enc_vec = safte_enc_vec;
+ enc->enc_fsm_states = enc_fsm_states;
+
+ if (enc->enc_private == NULL) {
+ enc->enc_private = ENC_MALLOCZ(SAFT_PRIVATE);
+ if (enc->enc_private == NULL)
+ return (ENOMEM);
+ }
+ cfg = enc->enc_private;
+
+ enc->enc_cache.nelms = 0;
+ enc->enc_cache.enc_status = 0;
+
+ TAILQ_INIT(&cfg->requests);
+ return (0);
+}
+
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_enc_ses.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/cam/scsi/scsi_enc_ses.c Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,2816 @@
+/*-
+ * Copyright (c) 2000 Matthew Jacob
+ * Copyright (c) 2010 Spectra Logic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/**
+ * \file scsi_enc_ses.c
+ *
+ * Structures and routines specific && private to SES only
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_enc_ses.c 238739 2012-07-24 13:08:43Z mav $");
+
+#include <sys/param.h>
+
+#include <sys/errno.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+#include <sys/sbuf.h>
+#include <sys/sx.h>
+#include <sys/systm.h>
+#include <sys/types.h>
+
+#include <cam/cam.h>
+#include <cam/cam_ccb.h>
+#include <cam/cam_xpt_periph.h>
+#include <cam/cam_periph.h>
+
+#include <cam/scsi/scsi_message.h>
+#include <cam/scsi/scsi_enc.h>
+#include <cam/scsi/scsi_enc_internal.h>
+
+#include <opt_enc.h>
+
+/* SES Native Type Device Support */
+
+/* SES Diagnostic Page Codes */
+typedef enum {
+ SesSupportedPages = 0x0,
+ SesConfigPage = 0x1,
+ SesControlPage = 0x2,
+ SesStatusPage = SesControlPage,
+ SesHelpTxt = 0x3,
+ SesStringOut = 0x4,
+ SesStringIn = SesStringOut,
+ SesThresholdOut = 0x5,
+ SesThresholdIn = SesThresholdOut,
+ SesArrayControl = 0x6, /* Obsolete in SES v2 */
+ SesArrayStatus = SesArrayControl,
+ SesElementDescriptor = 0x7,
+ SesShortStatus = 0x8,
+ SesEnclosureBusy = 0x9,
+ SesAddlElementStatus = 0xa
+} SesDiagPageCodes;
+
+typedef struct ses_type {
+ const struct ses_elm_type_desc *hdr;
+ const char *text;
+} ses_type_t;
+
+typedef struct ses_comstat {
+ uint8_t comstatus;
+ uint8_t comstat[3];
+} ses_comstat_t;
+
+typedef union ses_addl_data {
+ struct ses_elm_sas_device_phy *sasdev_phys;
+ struct ses_elm_sas_expander_phy *sasexp_phys;
+ struct ses_elm_sas_port_phy *sasport_phys;
+ struct ses_fcobj_port *fc_ports;
+} ses_add_data_t;
+
+typedef struct ses_addl_status {
+ struct ses_elm_addlstatus_base_hdr *hdr;
+ union {
+ union ses_fcobj_hdr *fc;
+ union ses_elm_sas_hdr *sas;
+ } proto_hdr;
+ union ses_addl_data proto_data; /* array sizes stored in header */
+} ses_add_status_t;
+
+typedef struct ses_element {
+ uint8_t eip; /* eip bit is set */
+ uint16_t descr_len; /* length of the descriptor */
+ char *descr; /* descriptor for this object */
+ struct ses_addl_status addl; /* additional status info */
+} ses_element_t;
+
+typedef struct ses_control_request {
+ int elm_idx;
+ ses_comstat_t elm_stat;
+ int result;
+ TAILQ_ENTRY(ses_control_request) links;
+} ses_control_request_t;
+TAILQ_HEAD(ses_control_reqlist, ses_control_request);
+typedef struct ses_control_reqlist ses_control_reqlist_t;
+enum {
+ SES_SETSTATUS_ENC_IDX = -1
+};
+
+static void
+ses_terminate_control_requests(ses_control_reqlist_t *reqlist, int result)
+{
+ ses_control_request_t *req;
+
+ while ((req = TAILQ_FIRST(reqlist)) != NULL) {
+ TAILQ_REMOVE(reqlist, req, links);
+ req->result = result;
+ wakeup(req);
+ }
+}
+
+enum ses_iter_index_values {
+ /**
+ * \brief Value of an initialized but invalid index
+ * in a ses_iterator object.
+ *
+ * This value is used for the individual_element_index of
+ * overal status elements and for all index types when
+ * an iterator is first initialized.
+ */
+ ITERATOR_INDEX_INVALID = -1,
+
+ /**
+ * \brief Value of an index in a ses_iterator object
+ * when the iterator has traversed past the last
+ * valid element..
+ */
+ ITERATOR_INDEX_END = INT_MAX
+};
+
+/**
+ * \brief Structure encapsulating all data necessary to traverse the
+ * elements of a SES configuration.
+ *
+ * The ses_iterator object simplifies the task of iterating through all
+ * elements detected via the SES configuration page by tracking the numerous
+ * element indexes that, instead of memoizing in the softc, we calculate
+ * on the fly during the traversal of the element objects. The various
+ * indexes are necessary due to the varying needs of matching objects in
+ * the different SES pages. Some pages (e.g. Status/Control) contain all
+ * elements, while others (e.g. Additional Element Status) only contain
+ * individual elements (no overal status elements) of particular types.
+ *
+ * To use an iterator, initialize it with ses_iter_init(), and then
+ * use ses_iter_next() to traverse the elements (including the first) in
+ * the configuration. Once an iterator is initiailized with ses_iter_init(),
+ * you may also seek to any particular element by either it's global or
+ * individual element index via the ses_iter_seek_to() function. You may
+ * also return an iterator to the position just before the first element
+ * (i.e. the same state as after an ses_iter_init()), with ses_iter_reset().
+ */
+struct ses_iterator {
+ /**
+ * \brief Backlink to the overal software configuration structure.
+ *
+ * This is included for convenience so the iteration functions
+ * need only take a single, struct ses_iterator *, argument.
+ */
+ enc_softc_t *enc;
+
+ enc_cache_t *cache;
+
+ /**
+ * \brief Index of the type of the current element within the
+ * ses_cache's ses_types array.
+ */
+ int type_index;
+
+ /**
+ * \brief The position (0 based) of this element relative to all other
+ * elements of this type.
+ *
+ * This index resets to zero every time the iterator transitions
+ * to elements of a new type in the configuration.
+ */
+ int type_element_index;
+
+ /**
+ * \brief The position (0 based) of this element relative to all
+ * other individual status elements in the configuration.
+ *
+ * This index ranges from 0 through the number of individual
+ * elements in the configuration. When the iterator returns
+ * an overall status element, individual_element_index is
+ * set to ITERATOR_INDEX_INVALID, to indicate that it does
+ * not apply to the current element.
+ */
+ int individual_element_index;
+
+ /**
+ * \brief The position (0 based) of this element relative to
+ * all elements in the configration.
+ *
+ * This index is appropriate for indexing into enc->ses_elm_map.
+ */
+ int global_element_index;
+
+ /**
+ * \brief The last valid individual element index of this
+ * iterator.
+ *
+ * When an iterator traverses an overal status element, the
+ * individual element index is reset to ITERATOR_INDEX_INVALID
+ * to prevent unintential use of the individual_element_index
+ * field. The saved_individual_element_index allows the iterator
+ * to restore it's position in the individual elements upon
+ * reaching the next individual element.
+ */
+ int saved_individual_element_index;
+};
+
+typedef enum {
+ SES_UPDATE_NONE,
+ SES_UPDATE_PAGES,
+ SES_UPDATE_GETCONFIG,
+ SES_UPDATE_GETSTATUS,
+ SES_UPDATE_GETELMDESCS,
+ SES_UPDATE_GETELMADDLSTATUS,
+ SES_PROCESS_CONTROL_REQS,
+ SES_PUBLISH_PHYSPATHS,
+ SES_PUBLISH_CACHE,
+ SES_NUM_UPDATE_STATES
+} ses_update_action;
+
+static enc_softc_cleanup_t ses_softc_cleanup;
+
+#define SCSZ 0x8000
+
+static fsm_fill_handler_t ses_fill_rcv_diag_io;
+static fsm_fill_handler_t ses_fill_control_request;
+static fsm_done_handler_t ses_process_pages;
+static fsm_done_handler_t ses_process_config;
+static fsm_done_handler_t ses_process_status;
+static fsm_done_handler_t ses_process_elm_descs;
+static fsm_done_handler_t ses_process_elm_addlstatus;
+static fsm_done_handler_t ses_process_control_request;
+static fsm_done_handler_t ses_publish_physpaths;
+static fsm_done_handler_t ses_publish_cache;
+
+static struct enc_fsm_state enc_fsm_states[SES_NUM_UPDATE_STATES] =
+{
+ { "SES_UPDATE_NONE", 0, 0, 0, NULL, NULL, NULL },
+ {
+ "SES_UPDATE_PAGES",
+ SesSupportedPages,
+ SCSZ,
+ 60 * 1000,
+ ses_fill_rcv_diag_io,
+ ses_process_pages,
+ enc_error
+ },
+ {
+ "SES_UPDATE_GETCONFIG",
+ SesConfigPage,
+ SCSZ,
+ 60 * 1000,
+ ses_fill_rcv_diag_io,
+ ses_process_config,
+ enc_error
+ },
+ {
+ "SES_UPDATE_GETSTATUS",
+ SesStatusPage,
+ SCSZ,
+ 60 * 1000,
+ ses_fill_rcv_diag_io,
+ ses_process_status,
+ enc_error
+ },
+ {
+ "SES_UPDATE_GETELMDESCS",
+ SesElementDescriptor,
+ SCSZ,
+ 60 * 1000,
+ ses_fill_rcv_diag_io,
+ ses_process_elm_descs,
+ enc_error
+ },
+ {
+ "SES_UPDATE_GETELMADDLSTATUS",
+ SesAddlElementStatus,
+ SCSZ,
+ 60 * 1000,
+ ses_fill_rcv_diag_io,
+ ses_process_elm_addlstatus,
+ enc_error
+ },
+ {
+ "SES_PROCESS_CONTROL_REQS",
+ SesControlPage,
+ SCSZ,
+ 60 * 1000,
+ ses_fill_control_request,
+ ses_process_control_request,
+ enc_error
+ },
+ {
+ "SES_PUBLISH_PHYSPATHS",
+ 0,
+ 0,
+ 0,
+ NULL,
+ ses_publish_physpaths,
+ NULL
+ },
+ {
+ "SES_PUBLISH_CACHE",
+ 0,
+ 0,
+ 0,
+ NULL,
+ ses_publish_cache,
+ NULL
+ }
+};
+
+typedef struct ses_cache {
+ /* Source for all the configuration data pointers */
+ const struct ses_cfg_page *cfg_page;
+
+ /* References into the config page. */
+ const struct ses_enc_desc * const *subencs;
+ uint8_t ses_ntypes;
+ const ses_type_t *ses_types;
+
+ /* Source for all the status pointers */
+ const struct ses_status_page *status_page;
+
+ /* Source for all the object descriptor pointers */
+ const struct ses_elem_descr_page *elm_descs_page;
+
+ /* Source for all the additional object status pointers */
+ const struct ses_addl_elem_status_page *elm_addlstatus_page;
+
+} ses_cache_t;
+
+typedef struct ses_softc {
+ uint32_t ses_flags;
+#define SES_FLAG_TIMEDCOMP 0x01
+#define SES_FLAG_ADDLSTATUS 0x02
+
+ ses_control_reqlist_t ses_requests;
+ ses_control_reqlist_t ses_pending_requests;
+} ses_softc_t;
+
+/**
+ * \brief Reset a SES iterator to just before the first element
+ * in the configuration.
+ *
+ * \param iter The iterator object to reset.
+ *
+ * The indexes within a reset iterator are invalid and will only
+ * become valid upon completion of a ses_iter_seek_to() or a
+ * ses_iter_next().
+ */
+static void
+ses_iter_reset(struct ses_iterator *iter)
+{
+ /*
+ * Set our indexes to just before the first valid element
+ * of the first type (ITERATOR_INDEX_INVALID == -1). This
+ * simplifies the implementation of ses_iter_next().
+ */
+ iter->type_index = 0;
+ iter->type_element_index = ITERATOR_INDEX_INVALID;
+ iter->global_element_index = ITERATOR_INDEX_INVALID;
+ iter->individual_element_index = ITERATOR_INDEX_INVALID;
+ iter->saved_individual_element_index = ITERATOR_INDEX_INVALID;
+}
+
+/**
+ * \brief Initialize the storage of a SES iterator and reset it to
+ * the position just before the first element of the
+ * configuration.
+ *
+ * \param enc The SES softc for the SES instance whose configuration
+ * will be enumerated by this iterator.
+ * \param iter The iterator object to initialize.
+ */
+static void
+ses_iter_init(enc_softc_t *enc, enc_cache_t *cache, struct ses_iterator *iter)
+{
+ iter->enc = enc;
+ iter->cache = cache;
+ ses_iter_reset(iter);
+}
+
+/**
+ * \brief Traverse the provided SES iterator to the next element
+ * within the configuraiton.
+ *
+ * \param iter The iterator to move.
+ *
+ * \return If a valid next element exists, a pointer to it's enc_element_t.
+ * Otherwise NULL.
+ */
+static enc_element_t *
+ses_iter_next(struct ses_iterator *iter)
+{
+ ses_cache_t *ses_cache;
+ const ses_type_t *element_type;
+
+ ses_cache = iter->cache->private;
+
+ /*
+ * Note: Treat nelms as signed, so we will hit this case
+ * and immediately terminate the iteration if the
+ * configuration has 0 objects.
+ */
+ if (iter->global_element_index >= (int)iter->cache->nelms - 1) {
+
+ /* Elements exhausted. */
+ iter->type_index = ITERATOR_INDEX_END;
+ iter->type_element_index = ITERATOR_INDEX_END;
+ iter->global_element_index = ITERATOR_INDEX_END;
+ iter->individual_element_index = ITERATOR_INDEX_END;
+ return (NULL);
+ }
+
+ KASSERT((iter->type_index < ses_cache->ses_ntypes),
+ ("Corrupted element iterator. %d not less than %d",
+ iter->type_index, ses_cache->ses_ntypes));
+
+ element_type = &ses_cache->ses_types[iter->type_index];
+ iter->global_element_index++;
+ iter->type_element_index++;
+
+ /*
+ * There is an object for overal type status in addition
+ * to one for each allowed element, but only if the element
+ * count is non-zero.
+ */
+ if (iter->type_element_index > element_type->hdr->etype_maxelt) {
+
+ /*
+ * We've exhausted the elements of this type.
+ * This next element belongs to the next type.
+ */
+ iter->type_index++;
+ iter->type_element_index = 0;
+ iter->saved_individual_element_index
+ = iter->individual_element_index;
+ iter->individual_element_index = ITERATOR_INDEX_INVALID;
+ }
+
+ if (iter->type_element_index > 0) {
+ if (iter->type_element_index == 1) {
+ iter->individual_element_index
+ = iter->saved_individual_element_index;
+ }
+ iter->individual_element_index++;
+ }
+
+ return (&iter->cache->elm_map[iter->global_element_index]);
+}
+
+/**
+ * Element index types tracked by a SES iterator.
+ */
+typedef enum {
+ /**
+ * Index relative to all elements (overall and individual)
+ * in the system.
+ */
+ SES_ELEM_INDEX_GLOBAL,
+
+ /**
+ * \brief Index relative to all individual elements in the system.
+ *
+ * This index counts only individual elements, skipping overall
+ * status elements. This is the index space of the additional
+ * element status page (page 0xa).
+ */
+ SES_ELEM_INDEX_INDIVIDUAL
+} ses_elem_index_type_t;
+
+/**
+ * \brief Move the provided iterator forwards or backwards to the object
+ * having the give index.
+ *
+ * \param iter The iterator on which to perform the seek.
+ * \param element_index The index of the element to find.
+ * \param index_type The type (global or individual) of element_index.
+ *
+ * \return If the element is found, a pointer to it's enc_element_t.
+ * Otherwise NULL.
+ */
+static enc_element_t *
+ses_iter_seek_to(struct ses_iterator *iter, int element_index,
+ ses_elem_index_type_t index_type)
+{
+ enc_element_t *element;
+ int *cur_index;
+
+ if (index_type == SES_ELEM_INDEX_GLOBAL)
+ cur_index = &iter->global_element_index;
+ else
+ cur_index = &iter->individual_element_index;
+
+ if (*cur_index == element_index) {
+ /* Already there. */
+ return (&iter->cache->elm_map[iter->global_element_index]);
+ }
+
+ ses_iter_reset(iter);
+ while ((element = ses_iter_next(iter)) != NULL
+ && *cur_index != element_index)
+ ;
+
+ if (*cur_index != element_index)
+ return (NULL);
+
+ return (element);
+}
+
+#if 0
+static int ses_encode(enc_softc_t *, uint8_t *, int, int,
+ struct ses_comstat *);
+#endif
+static int ses_set_timed_completion(enc_softc_t *, uint8_t);
+#if 0
+static int ses_putstatus(enc_softc_t *, int, struct ses_comstat *);
+#endif
+
+static void ses_print_addl_data(enc_softc_t *, enc_element_t *);
+
+/*=========================== SES cleanup routines ===========================*/
+
+static void
+ses_cache_free_elm_addlstatus(enc_softc_t *enc, enc_cache_t *cache)
+{
+ ses_cache_t *ses_cache;
+ ses_cache_t *other_ses_cache;
+ enc_element_t *cur_elm;
+ enc_element_t *last_elm;
+
+ ENC_DLOG(enc, "%s: enter\n", __func__);
+ ses_cache = cache->private;
+ if (ses_cache->elm_addlstatus_page == NULL)
+ return;
+
+ for (cur_elm = cache->elm_map,
+ last_elm = &cache->elm_map[cache->nelms - 1];
+ cur_elm <= last_elm; cur_elm++) {
+ ses_element_t *elmpriv;
+
+ elmpriv = cur_elm->elm_private;
+
+ /* Clear references to the additional status page. */
+ bzero(&elmpriv->addl, sizeof(elmpriv->addl));
+ }
+
+ other_ses_cache = enc_other_cache(enc, cache)->private;
+ if (other_ses_cache->elm_addlstatus_page
+ != ses_cache->elm_addlstatus_page)
+ ENC_FREE(ses_cache->elm_addlstatus_page);
+ ses_cache->elm_addlstatus_page = NULL;
+}
+
+static void
+ses_cache_free_elm_descs(enc_softc_t *enc, enc_cache_t *cache)
+{
+ ses_cache_t *ses_cache;
+ ses_cache_t *other_ses_cache;
+ enc_element_t *cur_elm;
+ enc_element_t *last_elm;
+
+ ENC_DLOG(enc, "%s: enter\n", __func__);
+ ses_cache = cache->private;
+ if (ses_cache->elm_descs_page == NULL)
+ return;
+
+ for (cur_elm = cache->elm_map,
+ last_elm = &cache->elm_map[cache->nelms - 1];
+ cur_elm <= last_elm; cur_elm++) {
+ ses_element_t *elmpriv;
+
+ elmpriv = cur_elm->elm_private;
+ elmpriv->descr_len = 0;
+ elmpriv->descr = NULL;
+ }
+
+ other_ses_cache = enc_other_cache(enc, cache)->private;
+ if (other_ses_cache->elm_descs_page
+ != ses_cache->elm_descs_page)
+ ENC_FREE(ses_cache->elm_descs_page);
+ ses_cache->elm_descs_page = NULL;
+}
+
+static void
+ses_cache_free_status(enc_softc_t *enc, enc_cache_t *cache)
+{
+ ses_cache_t *ses_cache;
+ ses_cache_t *other_ses_cache;
+
+ ENC_DLOG(enc, "%s: enter\n", __func__);
+ ses_cache = cache->private;
+ if (ses_cache->status_page == NULL)
+ return;
+
+ other_ses_cache = enc_other_cache(enc, cache)->private;
+ if (other_ses_cache->status_page != ses_cache->status_page)
+ ENC_FREE(ses_cache->status_page);
+ ses_cache->status_page = NULL;
+}
+
+static void
+ses_cache_free_elm_map(enc_softc_t *enc, enc_cache_t *cache)
+{
+ enc_element_t *cur_elm;
+ enc_element_t *last_elm;
+
+ ENC_DLOG(enc, "%s: enter\n", __func__);
+ if (cache->elm_map == NULL)
+ return;
+
+ ses_cache_free_elm_descs(enc, cache);
+ ses_cache_free_elm_addlstatus(enc, cache);
+ for (cur_elm = cache->elm_map,
+ last_elm = &cache->elm_map[cache->nelms - 1];
+ cur_elm <= last_elm; cur_elm++) {
+
+ ENC_FREE_AND_NULL(cur_elm->elm_private);
+ }
+ ENC_FREE_AND_NULL(cache->elm_map);
+ cache->nelms = 0;
+ ENC_DLOG(enc, "%s: exit\n", __func__);
+}
+
+static void
+ses_cache_free(enc_softc_t *enc, enc_cache_t *cache)
+{
+ ses_cache_t *other_ses_cache;
+ ses_cache_t *ses_cache;
+
+ ENC_DLOG(enc, "%s: enter\n", __func__);
+ ses_cache_free_elm_addlstatus(enc, cache);
+ ses_cache_free_status(enc, cache);
+ ses_cache_free_elm_map(enc, cache);
+
+ ses_cache = cache->private;
+ ses_cache->ses_ntypes = 0;
+
+ other_ses_cache = enc_other_cache(enc, cache)->private;
+ if (other_ses_cache->subencs != ses_cache->subencs)
+ ENC_FREE(ses_cache->subencs);
+ ses_cache->subencs = NULL;
+
+ if (other_ses_cache->ses_types != ses_cache->ses_types)
+ ENC_FREE(ses_cache->ses_types);
+ ses_cache->ses_types = NULL;
+
+ if (other_ses_cache->cfg_page != ses_cache->cfg_page)
+ ENC_FREE(ses_cache->cfg_page);
+ ses_cache->cfg_page = NULL;
+
+ ENC_DLOG(enc, "%s: exit\n", __func__);
+}
+
+static void
+ses_cache_clone(enc_softc_t *enc, enc_cache_t *src, enc_cache_t *dst)
+{
+ ses_cache_t *dst_ses_cache;
+ ses_cache_t *src_ses_cache;
+ enc_element_t *src_elm;
+ enc_element_t *dst_elm;
+ enc_element_t *last_elm;
+
+ ses_cache_free(enc, dst);
+ src_ses_cache = src->private;
+ dst_ses_cache = dst->private;
+
+ /*
+ * The cloned enclosure cache and ses specific cache are
+ * mostly identical to the source.
+ */
+ *dst = *src;
+ *dst_ses_cache = *src_ses_cache;
+
+ /*
+ * But the ses cache storage is still independent. Restore
+ * the pointer that was clobbered by the structure copy above.
+ */
+ dst->private = dst_ses_cache;
+
+ /*
+ * The element map is independent even though it starts out
+ * pointing to the same constant page data.
+ */
+ dst->elm_map = ENC_MALLOCZ(dst->nelms * sizeof(enc_element_t));
+ memcpy(dst->elm_map, src->elm_map, dst->nelms * sizeof(enc_element_t));
+ for (dst_elm = dst->elm_map, src_elm = src->elm_map,
+ last_elm = &src->elm_map[src->nelms - 1];
+ src_elm <= last_elm; src_elm++, dst_elm++) {
+
+ dst_elm->elm_private = ENC_MALLOCZ(sizeof(ses_element_t));
+ memcpy(dst_elm->elm_private, src_elm->elm_private,
+ sizeof(ses_element_t));
+ }
+}
+
+/* Structure accessors. These are strongly typed to avoid errors. */
+
+int
+ses_elm_sas_descr_type(union ses_elm_sas_hdr *obj)
+{
+ return ((obj)->base_hdr.byte1 >> 6);
+}
+int
+ses_elm_addlstatus_proto(struct ses_elm_addlstatus_base_hdr *hdr)
+{
+ return ((hdr)->byte0 & 0xf);
+}
+int
+ses_elm_addlstatus_eip(struct ses_elm_addlstatus_base_hdr *hdr)
+{
+ return ((hdr)->byte0 >> 4) & 0x1;
+}
+int
+ses_elm_addlstatus_invalid(struct ses_elm_addlstatus_base_hdr *hdr)
+{
+ return ((hdr)->byte0 >> 7);
+}
+int
+ses_elm_sas_type0_not_all_phys(union ses_elm_sas_hdr *hdr)
+{
+ return ((hdr)->type0_noneip.byte1 & 0x1);
+}
+int
+ses_elm_sas_dev_phy_sata_dev(struct ses_elm_sas_device_phy *phy)
+{
+ return ((phy)->target_ports & 0x1);
+}
+int
+ses_elm_sas_dev_phy_sata_port(struct ses_elm_sas_device_phy *phy)
+{
+ return ((phy)->target_ports >> 7);
+}
+int
+ses_elm_sas_dev_phy_dev_type(struct ses_elm_sas_device_phy *phy)
+{
+ return (((phy)->byte0 >> 4) & 0x7);
+}
+
+/**
+ * \brief Verify that the cached configuration data in our softc
+ * is valid for processing the page data corresponding to
+ * the provided page header.
+ *
+ * \param ses_cache The SES cache to validate.
+ * \param gen_code The 4 byte generation code from a SES diagnostic
+ * page header.
+ *
+ * \return non-zero if true, 0 if false.
+ */
+static int
+ses_config_cache_valid(ses_cache_t *ses_cache, const uint8_t *gen_code)
+{
+ uint32_t cache_gc;
+ uint32_t cur_gc;
+
+ if (ses_cache->cfg_page == NULL)
+ return (0);
+
+ cache_gc = scsi_4btoul(ses_cache->cfg_page->hdr.gen_code);
+ cur_gc = scsi_4btoul(gen_code);
+ return (cache_gc == cur_gc);
+}
+
+/**
+ * Function signature for consumers of the ses_devids_iter() interface.
+ */
+typedef void ses_devid_callback_t(enc_softc_t *, enc_element_t *,
+ struct scsi_vpd_id_descriptor *, void *);
+
+/**
+ * \brief Iterate over and create vpd device id records from the
+ * additional element status data for elm, passing that data
+ * to the provided callback.
+ *
+ * \param enc SES instance containing elm
+ * \param elm Element for which to extract device ID data.
+ * \param callback The callback function to invoke on each generated
+ * device id descriptor for elm.
+ * \param callback_arg Argument passed through to callback on each invocation.
+ */
+static void
+ses_devids_iter(enc_softc_t *enc, enc_element_t *elm,
+ ses_devid_callback_t *callback, void *callback_arg)
+{
+ ses_element_t *elmpriv;
+ struct ses_addl_status *addl;
+ u_int i;
+ size_t devid_record_size;
+
+ elmpriv = elm->elm_private;
+ addl = &(elmpriv->addl);
+
+ /*
+ * Don't assume this object has additional status information, or
+ * that it is a SAS device, or that it is a device slot device.
+ */
+ if (addl->hdr == NULL || addl->proto_hdr.sas == NULL
+ || addl->proto_data.sasdev_phys == NULL)
+ return;
+
+ devid_record_size = SVPD_DEVICE_ID_DESC_HDR_LEN
+ + sizeof(struct scsi_vpd_id_naa_ieee_reg);
+ for (i = 0; i < addl->proto_hdr.sas->base_hdr.num_phys; i++) {
+ uint8_t devid_buf[devid_record_size];
+ struct scsi_vpd_id_descriptor *devid;
+ uint8_t *phy_addr;
+
+ devid = (struct scsi_vpd_id_descriptor *)devid_buf;
+ phy_addr = addl->proto_data.sasdev_phys[i].phy_addr;
+ devid->proto_codeset = (SCSI_PROTO_SAS << SVPD_ID_PROTO_SHIFT)
+ | SVPD_ID_CODESET_BINARY;
+ devid->id_type = SVPD_ID_PIV
+ | SVPD_ID_ASSOC_PORT
+ | SVPD_ID_TYPE_NAA;
+ devid->reserved = 0;
+ devid->length = sizeof(struct scsi_vpd_id_naa_ieee_reg);
+ memcpy(devid->identifier, phy_addr, devid->length);
+
+ callback(enc, elm, devid, callback_arg);
+ }
+}
+
+/**
+ * Function signature for consumers of the ses_paths_iter() interface.
+ */
+typedef void ses_path_callback_t(enc_softc_t *, enc_element_t *,
+ struct cam_path *, void *);
+
+/**
+ * Argument package passed through ses_devids_iter() by
+ * ses_paths_iter() to ses_path_iter_devid_callback().
+ */
+typedef struct ses_path_iter_args {
+ ses_path_callback_t *callback;
+ void *callback_arg;
+} ses_path_iter_args_t;
+
+/**
+ * ses_devids_iter() callback function used by ses_paths_iter()
+ * to map device ids to peripheral driver instances.
+ *
+ * \param enc SES instance containing elm
+ * \param elm Element on which device ID matching is active.
+ * \param periph A device ID corresponding to elm.
+ * \param arg Argument passed through to callback on each invocation.
+ */
+static void
+ses_path_iter_devid_callback(enc_softc_t *enc, enc_element_t *elem,
+ struct scsi_vpd_id_descriptor *devid,
+ void *arg)
+{
+ struct ccb_dev_match cdm;
+ struct dev_match_pattern match_pattern;
+ struct dev_match_result match_result;
+ struct device_match_result *device_match;
+ struct device_match_pattern *device_pattern;
+ ses_path_iter_args_t *args;
+
+ args = (ses_path_iter_args_t *)arg;
+ match_pattern.type = DEV_MATCH_DEVICE;
+ device_pattern = &match_pattern.pattern.device_pattern;
+ device_pattern->flags = DEV_MATCH_DEVID;
+ device_pattern->data.devid_pat.id_len =
+ offsetof(struct scsi_vpd_id_descriptor, identifier)
+ + devid->length;
+ memcpy(device_pattern->data.devid_pat.id, devid,
+ device_pattern->data.devid_pat.id_len);
+
+ memset(&cdm, 0, sizeof(cdm));
+ if (xpt_create_path(&cdm.ccb_h.path, /*periph*/NULL, CAM_XPT_PATH_ID,
+ CAM_TARGET_WILDCARD,
+ CAM_LUN_WILDCARD) != CAM_REQ_CMP)
+ return;
+
+ cdm.ccb_h.func_code = XPT_DEV_MATCH;
+ cdm.num_patterns = 1;
+ cdm.patterns = &match_pattern;
+ cdm.pattern_buf_len = sizeof(match_pattern);
+ cdm.match_buf_len = sizeof(match_result);
+ cdm.matches = &match_result;
+
+ xpt_action((union ccb *)&cdm);
+ xpt_free_path(cdm.ccb_h.path);
+
+ if ((cdm.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP
+ || (cdm.status != CAM_DEV_MATCH_LAST
+ && cdm.status != CAM_DEV_MATCH_MORE)
+ || cdm.num_matches == 0)
+ return;
+
+ device_match = &match_result.result.device_result;
+ if (xpt_create_path(&cdm.ccb_h.path, /*periph*/NULL,
+ device_match->path_id,
+ device_match->target_id,
+ device_match->target_lun) != CAM_REQ_CMP)
+ return;
+
+ args->callback(enc, elem, cdm.ccb_h.path, args->callback_arg);
+ xpt_free_path(cdm.ccb_h.path);
+}
+
+/**
+ * \brief Iterate over and find the matching periph objects for the
+ * specified element.
+ *
+ * \param enc SES instance containing elm
+ * \param elm Element for which to perform periph object matching.
+ * \param callback The callback function to invoke with each matching
+ * periph object.
+ * \param callback_arg Argument passed through to callback on each invocation.
+ */
+static void
+ses_paths_iter(enc_softc_t *enc, enc_element_t *elm,
+ ses_path_callback_t *callback, void *callback_arg)
+{
+ ses_path_iter_args_t args;
+
+ args.callback = callback;
+ args.callback_arg = callback_arg;
+ ses_devids_iter(enc, elm, ses_path_iter_devid_callback, &args);
+}
+
+/**
+ * ses_paths_iter() callback function used by ses_get_elmdevname()
+ * to record periph driver instance strings corresponding to a SES
+ * element.
+ *
+ * \param enc SES instance containing elm
+ * \param elm Element on which periph matching is active.
+ * \param periph A periph instance that matches elm.
+ * \param arg Argument passed through to callback on each invocation.
+ */
+static void
+ses_elmdevname_callback(enc_softc_t *enc, enc_element_t *elem,
+ struct cam_path *path, void *arg)
+{
+ struct sbuf *sb;
+
+ sb = (struct sbuf *)arg;
+ cam_periph_list(path, sb);
+}
+
+/**
+ * Argument package passed through ses_paths_iter() to
+ * ses_getcampath_callback.
+ */
+typedef struct ses_setphyspath_callback_args {
+ struct sbuf *physpath;
+ int num_set;
+} ses_setphyspath_callback_args_t;
+
+/**
+ * \brief ses_paths_iter() callback to set the physical path on the
+ * CAM EDT entries corresponding to a given SES element.
+ *
+ * \param enc SES instance containing elm
+ * \param elm Element on which periph matching is active.
+ * \param periph A periph instance that matches elm.
+ * \param arg Argument passed through to callback on each invocation.
+ */
+static void
+ses_setphyspath_callback(enc_softc_t *enc, enc_element_t *elm,
+ struct cam_path *path, void *arg)
+{
+ struct ccb_dev_advinfo cdai;
+ ses_setphyspath_callback_args_t *args;
+ char *old_physpath;
+
+ args = (ses_setphyspath_callback_args_t *)arg;
+ old_physpath = malloc(MAXPATHLEN, M_SCSIENC, M_WAITOK|M_ZERO);
+
+ xpt_setup_ccb(&cdai.ccb_h, path, CAM_PRIORITY_NORMAL);
+ cdai.ccb_h.func_code = XPT_DEV_ADVINFO;
+ cdai.buftype = CDAI_TYPE_PHYS_PATH;
+ cdai.flags = 0;
+ cdai.bufsiz = MAXPATHLEN;
+ cdai.buf = old_physpath;
+ xpt_action((union ccb *)&cdai);
+ if ((cdai.ccb_h.status & CAM_DEV_QFRZN) != 0)
+ cam_release_devq(cdai.ccb_h.path, 0, 0, 0, FALSE);
+
+ if (strcmp(old_physpath, sbuf_data(args->physpath)) != 0) {
+
+ xpt_setup_ccb(&cdai.ccb_h, path, CAM_PRIORITY_NORMAL);
+ cdai.ccb_h.func_code = XPT_DEV_ADVINFO;
+ cdai.buftype = CDAI_TYPE_PHYS_PATH;
+ cdai.flags |= CDAI_FLAG_STORE;
+ cdai.bufsiz = sbuf_len(args->physpath);
+ cdai.buf = sbuf_data(args->physpath);
+ xpt_action((union ccb *)&cdai);
+ if ((cdai.ccb_h.status & CAM_DEV_QFRZN) != 0)
+ cam_release_devq(cdai.ccb_h.path, 0, 0, 0, FALSE);
+ if (cdai.ccb_h.status == CAM_REQ_CMP)
+ args->num_set++;
+ }
+ free(old_physpath, M_SCSIENC);
+}
+
+/**
+ * \brief Set a device's physical path string in CAM XPT.
+ *
+ * \param enc SES instance containing elm
+ * \param elm Element to publish physical path string for
+ * \param iter Iterator whose state corresponds to elm
+ *
+ * \return 0 on success, errno otherwise.
+ */
+static int
+ses_set_physpath(enc_softc_t *enc, enc_element_t *elm,
+ struct ses_iterator *iter)
+{
+ struct ccb_dev_advinfo cdai;
+ ses_setphyspath_callback_args_t args;
+ int ret;
+ struct sbuf sb;
+ uint8_t *devid, *elmaddr;
+ ses_element_t *elmpriv;
+
+ ret = EIO;
+ devid = NULL;
+
+ /*
+ * Assemble the components of the physical path starting with
+ * the device ID of the enclosure itself.
+ */
+ xpt_setup_ccb(&cdai.ccb_h, enc->periph->path, CAM_PRIORITY_NORMAL);
+ cdai.ccb_h.func_code = XPT_DEV_ADVINFO;
+ cdai.buftype = CDAI_TYPE_SCSI_DEVID;
+ cdai.bufsiz = CAM_SCSI_DEVID_MAXLEN;
+ cdai.buf = devid = ENC_MALLOCZ(cdai.bufsiz);
+ if (devid == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ xpt_action((union ccb *)&cdai);
+ if ((cdai.ccb_h.status & CAM_DEV_QFRZN) != 0)
+ cam_release_devq(cdai.ccb_h.path, 0, 0, 0, FALSE);
+ if (cdai.ccb_h.status != CAM_REQ_CMP)
+ goto out;
+
+ elmaddr = scsi_get_devid((struct scsi_vpd_device_id *)cdai.buf,
+ cdai.provsiz, scsi_devid_is_naa_ieee_reg);
+ if (elmaddr == NULL)
+ goto out;
+
+ if (sbuf_new(&sb, NULL, 128, SBUF_AUTOEXTEND) == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ /* Next, generate the physical path string */
+ sbuf_printf(&sb, "id1,enc at n%jx/type@%x/slot@%x",
+ scsi_8btou64(elmaddr), iter->type_index,
+ iter->type_element_index);
+ /* Append the element descriptor if one exists */
+ elmpriv = elm->elm_private;
+ if (elmpriv->descr != NULL && elmpriv->descr_len > 0) {
+ sbuf_cat(&sb, "/elmdesc@");
+ sbuf_bcat(&sb, elmpriv->descr, elmpriv->descr_len);
+ }
+ sbuf_finish(&sb);
+
+ /*
+ * Set this physical path on any CAM devices with a device ID
+ * descriptor that matches one created from the SES additional
+ * status data for this element.
+ */
+ args.physpath= &sb;
+ args.num_set = 0;
+ ses_paths_iter(enc, elm, ses_setphyspath_callback, &args);
+ sbuf_delete(&sb);
+
+ ret = args.num_set == 0 ? ENOENT : 0;
+
+out:
+ if (devid != NULL)
+ ENC_FREE(devid);
+ return (ret);
+}
+
+/**
+ * \brief Helper to set the CDB fields appropriately.
+ *
+ * \param cdb Buffer containing the cdb.
+ * \param pagenum SES diagnostic page to query for.
+ * \param dir Direction of query.
+ */
+static void
+ses_page_cdb(char *cdb, int bufsiz, SesDiagPageCodes pagenum, int dir)
+{
+
+ /* Ref: SPC-4 r25 Section 6.20 Table 223 */
+ if (dir == CAM_DIR_IN) {
+ cdb[0] = RECEIVE_DIAGNOSTIC;
+ cdb[1] = 1; /* Set page code valid bit */
+ cdb[2] = pagenum;
+ } else {
+ cdb[0] = SEND_DIAGNOSTIC;
+ cdb[1] = 0x10;
+ cdb[2] = pagenum;
+ }
+ cdb[3] = bufsiz >> 8; /* high bits */
+ cdb[4] = bufsiz & 0xff; /* low bits */
+ cdb[5] = 0;
+}
+
+/**
+ * \brief Discover whether this instance supports timed completion of a
+ * RECEIVE DIAGNOSTIC RESULTS command requesting the Enclosure Status
+ * page, and store the result in the softc, updating if necessary.
+ *
+ * \param enc SES instance to query and update.
+ * \param tc_en Value of timed completion to set (see \return).
+ *
+ * \return 1 if timed completion enabled, 0 otherwise.
+ */
+static int
+ses_set_timed_completion(enc_softc_t *enc, uint8_t tc_en)
+{
+ int err;
+ union ccb *ccb;
+ struct cam_periph *periph;
+ struct ses_mgmt_mode_page *mgmt;
+ uint8_t *mode_buf;
+ size_t mode_buf_len;
+ ses_softc_t *ses;
+
+ periph = enc->periph;
+ ses = enc->enc_private;
+ ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
+
+ mode_buf_len = sizeof(struct ses_mgmt_mode_page);
+ mode_buf = ENC_MALLOCZ(mode_buf_len);
+ if (mode_buf == NULL)
+ goto out;
+
+ scsi_mode_sense(&ccb->csio, /*retries*/4, enc_done, MSG_SIMPLE_Q_TAG,
+ /*dbd*/FALSE, SMS_PAGE_CTRL_CURRENT, SES_MGMT_MODE_PAGE_CODE,
+ mode_buf, mode_buf_len, SSD_FULL_SIZE, /*timeout*/60 * 1000);
+
+ /*
+ * Ignore illegal request errors, as they are quite common and we
+ * will print something out in that case anyway.
+ */
+ err = cam_periph_runccb(ccb, enc_error, ENC_CFLAGS,
+ ENC_FLAGS|SF_QUIET_IR, NULL);
+ if (ccb->ccb_h.status != CAM_REQ_CMP) {
+ ENC_LOG(enc, "Timed Completion Unsupported\n");
+ goto release;
+ }
+
+ /* Skip the mode select if the desired value is already set */
+ mgmt = (struct ses_mgmt_mode_page *)mode_buf;
+ if ((mgmt->byte5 & SES_MGMT_TIMED_COMP_EN) == tc_en)
+ goto done;
+
+ /* Value is not what we wanted, set it */
+ if (tc_en)
+ mgmt->byte5 |= SES_MGMT_TIMED_COMP_EN;
+ else
+ mgmt->byte5 &= ~SES_MGMT_TIMED_COMP_EN;
+ /* SES2r20: a completion time of zero means as long as possible */
+ bzero(&mgmt->max_comp_time, sizeof(mgmt->max_comp_time));
+
+ scsi_mode_select(&ccb->csio, 5, enc_done, MSG_SIMPLE_Q_TAG,
+ /*page_fmt*/FALSE, /*save_pages*/TRUE, mode_buf, mode_buf_len,
+ SSD_FULL_SIZE, /*timeout*/60 * 1000);
+
+ err = cam_periph_runccb(ccb, enc_error, ENC_CFLAGS, ENC_FLAGS, NULL);
+ if (ccb->ccb_h.status != CAM_REQ_CMP) {
+ ENC_LOG(enc, "Timed Completion Set Failed\n");
+ goto release;
+ }
+
+done:
+ if ((mgmt->byte5 & SES_MGMT_TIMED_COMP_EN) != 0) {
+ ENC_LOG(enc, "Timed Completion Enabled\n");
+ ses->ses_flags |= SES_FLAG_TIMEDCOMP;
+ } else {
+ ENC_LOG(enc, "Timed Completion Disabled\n");
+ ses->ses_flags &= ~SES_FLAG_TIMEDCOMP;
+ }
+release:
+ ENC_FREE(mode_buf);
+ xpt_release_ccb(ccb);
+out:
+ return (ses->ses_flags & SES_FLAG_TIMEDCOMP);
+}
+
+/**
+ * \brief Process the list of supported pages and update flags.
+ *
+ * \param enc SES device to query.
+ * \param buf Buffer containing the config page.
+ * \param xfer_len Length of the config page in the buffer.
+ *
+ * \return 0 on success, errno otherwise.
+ */
+static int
+ses_process_pages(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
+{
+ ses_softc_t *ses;
+ struct scsi_diag_page *page;
+ int err, i, length;
+
+ CAM_DEBUG(enc->periph->path, CAM_DEBUG_SUBTRACE,
+ ("entering %s(%p, %d)\n", __func__, bufp, xfer_len));
+ ses = enc->enc_private;
+ err = -1;
+
+ if (error != 0) {
+ err = error;
+ goto out;
+ }
+ if (xfer_len < sizeof(*page)) {
+ ENC_LOG(enc, "Unable to parse Diag Pages List Header\n");
+ err = EIO;
+ goto out;
+ }
+ page = (struct scsi_diag_page *)*bufp;
+ length = scsi_2btoul(page->length);
+ if (length + offsetof(struct scsi_diag_page, params) > xfer_len) {
+ ENC_LOG(enc, "Diag Pages List Too Long\n");
+ goto out;
+ }
+ ENC_DLOG(enc, "%s: page length %d, xfer_len %d\n",
+ __func__, length, xfer_len);
+
+ err = 0;
+ for (i = 0; i < length; i++) {
+ if (page->params[i] == SesAddlElementStatus) {
+ ses->ses_flags |= SES_FLAG_ADDLSTATUS;
+ break;
+ }
+ }
+
+out:
+ ENC_DLOG(enc, "%s: exiting with err %d\n", __func__, err);
+ return (err);
+}
+
+/**
+ * \brief Process the config page and update associated structures.
+ *
+ * \param enc SES device to query.
+ * \param buf Buffer containing the config page.
+ * \param xfer_len Length of the config page in the buffer.
+ *
+ * \return 0 on success, errno otherwise.
+ */
+static int
+ses_process_config(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
+{
+ struct ses_iterator iter;
+ ses_softc_t *ses;
+ enc_cache_t *enc_cache;
+ ses_cache_t *ses_cache;
+ uint8_t *buf;
+ int length;
+ int err;
+ int nelm;
+ int ntype;
+ struct ses_cfg_page *cfg_page;
+ struct ses_enc_desc *buf_subenc;
+ const struct ses_enc_desc **subencs;
+ const struct ses_enc_desc **cur_subenc;
+ const struct ses_enc_desc **last_subenc;
+ ses_type_t *ses_types;
+ ses_type_t *sestype;
+ const struct ses_elm_type_desc *cur_buf_type;
+ const struct ses_elm_type_desc *last_buf_type;
+ uint8_t *last_valid_byte;
+ enc_element_t *element;
+ const char *type_text;
+
+ CAM_DEBUG(enc->periph->path, CAM_DEBUG_SUBTRACE,
+ ("entering %s(%p, %d)\n", __func__, bufp, xfer_len));
+ ses = enc->enc_private;
+ enc_cache = &enc->enc_daemon_cache;
+ ses_cache = enc_cache->private;
+ buf = *bufp;
+ err = -1;;
+
+ if (error != 0) {
+ err = error;
+ goto out;
+ }
+ if (xfer_len < sizeof(cfg_page->hdr)) {
+ ENC_LOG(enc, "Unable to parse SES Config Header\n");
+ err = EIO;
+ goto out;
+ }
+
+ cfg_page = (struct ses_cfg_page *)buf;
+ length = ses_page_length(&cfg_page->hdr);
+ if (length > xfer_len) {
+ ENC_LOG(enc, "Enclosure Config Page Too Long\n");
+ goto out;
+ }
+ last_valid_byte = &buf[length - 1];
+
+ ENC_DLOG(enc, "%s: total page length %d, xfer_len %d\n",
+ __func__, length, xfer_len);
+
+ err = 0;
+ if (ses_config_cache_valid(ses_cache, cfg_page->hdr.gen_code)) {
+
+ /* Our cache is still valid. Proceed to fetching status. */
+ goto out;
+ }
+
+ /* Cache is no longer valid. Free old data to make way for new. */
+ ses_cache_free(enc, enc_cache);
+ ENC_VLOG(enc, "Generation Code 0x%x has %d SubEnclosures\n",
+ scsi_4btoul(cfg_page->hdr.gen_code),
+ ses_cfg_page_get_num_subenc(cfg_page));
+
+ /* Take ownership of the buffer. */
+ ses_cache->cfg_page = cfg_page;
+ *bufp = NULL;
+
+ /*
+ * Now waltz through all the subenclosures summing the number of
+ * types available in each.
+ */
+ subencs = ENC_MALLOCZ(ses_cfg_page_get_num_subenc(cfg_page)
+ * sizeof(*subencs));
+ if (subencs == NULL) {
+ err = ENOMEM;
+ goto out;
+ }
+ /*
+ * Sub-enclosure data is const after construction (i.e. when
+ * accessed via our cache object.
+ *
+ * The cast here is not required in C++ but C99 is not so
+ * sophisticated (see C99 6.5.16.1(1)).
+ */
+ ses_cache->subencs = subencs;
+
+ buf_subenc = cfg_page->subencs;
+ cur_subenc = subencs;
+ last_subenc = &subencs[ses_cfg_page_get_num_subenc(cfg_page) - 1];
+ ntype = 0;
+ while (cur_subenc <= last_subenc) {
+
+ if (!ses_enc_desc_is_complete(buf_subenc, last_valid_byte)) {
+ ENC_LOG(enc, "Enclosure %d Beyond End of "
+ "Descriptors\n", cur_subenc - subencs);
+ err = EIO;
+ goto out;
+ }
+
+ ENC_VLOG(enc, " SubEnclosure ID %d, %d Types With this ID, "
+ "Descriptor Length %d, offset %d\n", buf_subenc->subenc_id,
+ buf_subenc->num_types, buf_subenc->length,
+ &buf_subenc->byte0 - buf);
+ ENC_VLOG(enc, "WWN: %jx\n",
+ (uintmax_t)scsi_8btou64(buf_subenc->logical_id));
+
+ ntype += buf_subenc->num_types;
+ *cur_subenc = buf_subenc;
+ cur_subenc++;
+ buf_subenc = ses_enc_desc_next(buf_subenc);
+ }
+
+ /* Process the type headers. */
+ ses_types = ENC_MALLOCZ(ntype * sizeof(*ses_types));
+ if (ses_types == NULL) {
+ err = ENOMEM;
+ goto out;
+ }
+ /*
+ * Type data is const after construction (i.e. when accessed via
+ * our cache object.
+ */
+ ses_cache->ses_types = ses_types;
+
+ cur_buf_type = (const struct ses_elm_type_desc *)
+ (&(*last_subenc)->length + (*last_subenc)->length + 1);
+ last_buf_type = cur_buf_type + ntype - 1;
+ type_text = (const uint8_t *)(last_buf_type + 1);
+ nelm = 0;
+ sestype = ses_types;
+ while (cur_buf_type <= last_buf_type) {
+ if (&cur_buf_type->etype_txt_len > last_valid_byte) {
+ ENC_LOG(enc, "Runt Enclosure Type Header %d\n",
+ sestype - ses_types);
+ err = EIO;
+ goto out;
+ }
+ sestype->hdr = cur_buf_type;
+ sestype->text = type_text;
+ type_text += cur_buf_type->etype_txt_len;
+ ENC_LOG(enc, " Type Desc[%d]: Type 0x%x, MaxElt %d, In Subenc "
+ "%d, Text Length %d: %.*s\n", sestype - ses_types,
+ sestype->hdr->etype_elm_type, sestype->hdr->etype_maxelt,
+ sestype->hdr->etype_subenc, sestype->hdr->etype_txt_len,
+ sestype->hdr->etype_txt_len, sestype->text);
+
+ nelm += sestype->hdr->etype_maxelt
+ + /*overall status element*/1;
+ sestype++;
+ cur_buf_type++;
+ }
+
+ /* Create the object map. */
+ enc_cache->elm_map = ENC_MALLOCZ(nelm * sizeof(enc_element_t));
+ if (enc_cache->elm_map == NULL) {
+ err = ENOMEM;
+ goto out;
+ }
+ ses_cache->ses_ntypes = (uint8_t)ntype;
+ enc_cache->nelms = nelm;
+
+ ses_iter_init(enc, enc_cache, &iter);
+ while ((element = ses_iter_next(&iter)) != NULL) {
+ const struct ses_elm_type_desc *thdr;
+
+ ENC_DLOG(enc, "%s: checking obj %d(%d,%d)\n", __func__,
+ iter.global_element_index, iter.type_index, nelm,
+ iter.type_element_index);
+ thdr = ses_cache->ses_types[iter.type_index].hdr;
+ element->subenclosure = thdr->etype_subenc;
+ element->enctype = thdr->etype_elm_type;
+ element->overall_status_elem = iter.type_element_index == 0;
+ element->elm_private = ENC_MALLOCZ(sizeof(ses_element_t));
+ if (element->elm_private == NULL) {
+ err = ENOMEM;
+ goto out;
+ }
+ ENC_DLOG(enc, "%s: creating elmpriv %d(%d,%d) subenc %d "
+ "type 0x%x\n", __func__, iter.global_element_index,
+ iter.type_index, iter.type_element_index,
+ thdr->etype_subenc, thdr->etype_elm_type);
+ }
+
+ err = 0;
+
+out:
+ if (err)
+ ses_cache_free(enc, enc_cache);
+ else {
+ enc_update_request(enc, SES_UPDATE_GETSTATUS);
+ enc_update_request(enc, SES_UPDATE_GETELMDESCS);
+ if (ses->ses_flags & SES_FLAG_ADDLSTATUS)
+ enc_update_request(enc, SES_UPDATE_GETELMADDLSTATUS);
+ enc_update_request(enc, SES_PUBLISH_CACHE);
+ }
+ ENC_DLOG(enc, "%s: exiting with err %d\n", __func__, err);
+ return (err);
+}
+
+/**
+ * \brief Update the status page and associated structures.
+ *
+ * \param enc SES softc to update for.
+ * \param buf Buffer containing the status page.
+ * \param bufsz Amount of data in the buffer.
+ *
+ * \return 0 on success, errno otherwise.
+ */
+static int
+ses_process_status(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
+{
+ struct ses_iterator iter;
+ enc_element_t *element;
+ ses_softc_t *ses;
+ enc_cache_t *enc_cache;
+ ses_cache_t *ses_cache;
+ uint8_t *buf;
+ int err = -1;
+ int length;
+ struct ses_status_page *page;
+ union ses_status_element *cur_stat;
+ union ses_status_element *last_stat;
+
+ ses = enc->enc_private;
+ enc_cache = &enc->enc_daemon_cache;
+ ses_cache = enc_cache->private;
+ buf = *bufp;
+
+ ENC_DLOG(enc, "%s: enter (%p, %p, %d)\n", __func__, enc, buf, xfer_len);
+ page = (struct ses_status_page *)buf;
+ length = ses_page_length(&page->hdr);
+
+ if (error != 0) {
+ err = error;
+ goto out;
+ }
+ /*
+ * Make sure the length fits in the buffer.
+ *
+ * XXX all this means is that the page is larger than the space
+ * we allocated. Since we use a statically sized buffer, this
+ * could happen... Need to use dynamic discovery of the size.
+ */
+ if (length > xfer_len) {
+ ENC_LOG(enc, "Enclosure Status Page Too Long\n");
+ goto out;
+ }
+ /* Make sure the length contains at least one header and status */
+ if (length < (sizeof(*page) + sizeof(*page->elements))) {
+ ENC_LOG(enc, "Enclosure Status Page Too Short\n");
+ goto out;
+ }
+
+ if (!ses_config_cache_valid(ses_cache, page->hdr.gen_code)) {
+ ENC_DLOG(enc, "%s: Generation count change detected\n",
+ __func__);
+ enc_update_request(enc, SES_UPDATE_GETCONFIG);
+ goto out;
+ }
+
+ ses_cache_free_status(enc, enc_cache);
+ ses_cache->status_page = page;
+ *bufp = NULL;
+
+ enc_cache->enc_status = page->hdr.page_specific_flags;
+
+ /*
+ * Read in individual element status. The element order
+ * matches the order reported in the config page (i.e. the
+ * order of an unfiltered iteration of the config objects)..
+ */
+ ses_iter_init(enc, enc_cache, &iter);
+ cur_stat = page->elements;
+ last_stat = (union ses_status_element *)
+ &buf[length - sizeof(*last_stat)];
+ ENC_DLOG(enc, "%s: total page length %d, xfer_len %d\n",
+ __func__, length, xfer_len);
+ while (cur_stat <= last_stat
+ && (element = ses_iter_next(&iter)) != NULL) {
+
+ ENC_DLOG(enc, "%s: obj %d(%d,%d) off=0x%tx status=%jx\n",
+ __func__, iter.global_element_index, iter.type_index,
+ iter.type_element_index, (uint8_t *)cur_stat - buf,
+ scsi_4btoul(cur_stat->bytes));
+
+ memcpy(&element->encstat, cur_stat, sizeof(element->encstat));
+ element->svalid = 1;
+ cur_stat++;
+ }
+
+ if (ses_iter_next(&iter) != NULL) {
+ ENC_LOG(enc, "Status page, length insufficient for "
+ "expected number of objects\n");
+ } else {
+ if (cur_stat <= last_stat)
+ ENC_LOG(enc, "Status page, exhausted objects before "
+ "exhausing page\n");
+ enc_update_request(enc, SES_PUBLISH_CACHE);
+ err = 0;
+ }
+out:
+ ENC_DLOG(enc, "%s: exiting with error %d\n", __func__, err);
+ return (err);
+}
+
+typedef enum {
+ /**
+ * The enclosure should not provide additional element
+ * status for this element type in page 0x0A.
+ *
+ * \note This status is returned for any types not
+ * listed SES3r02. Further types added in a
+ * future specification will be incorrectly
+ * classified.
+ */
+ TYPE_ADDLSTATUS_NONE,
+
+ /**
+ * The element type provides additional element status
+ * in page 0x0A.
+ */
+ TYPE_ADDLSTATUS_MANDATORY,
+
+ /**
+ * The element type may provide additional element status
+ * in page 0x0A, but i
+ */
+ TYPE_ADDLSTATUS_OPTIONAL
+} ses_addlstatus_avail_t;
+
+/**
+ * \brief Check to see whether a given type (as obtained via type headers) is
+ * supported by the additional status command.
+ *
+ * \param enc SES softc to check.
+ * \param typidx Type index to check for.
+ *
+ * \return An enumeration indicating if additional status is mandatory,
+ * optional, or not required for this type.
+ */
+static ses_addlstatus_avail_t
+ses_typehasaddlstatus(enc_softc_t *enc, uint8_t typidx)
+{
+ enc_cache_t *enc_cache;
+ ses_cache_t *ses_cache;
+
+ enc_cache = &enc->enc_daemon_cache;
+ ses_cache = enc_cache->private;
+ switch(ses_cache->ses_types[typidx].hdr->etype_elm_type) {
+ case ELMTYP_DEVICE:
+ case ELMTYP_ARRAY_DEV:
+ case ELMTYP_SAS_EXP:
+ return (TYPE_ADDLSTATUS_MANDATORY);
+ case ELMTYP_SCSI_INI:
+ case ELMTYP_SCSI_TGT:
+ case ELMTYP_ESCC:
+ return (TYPE_ADDLSTATUS_OPTIONAL);
+ default:
+ /* No additional status information available. */
+ break;
+ }
+ return (TYPE_ADDLSTATUS_NONE);
+}
+
+static int ses_get_elm_addlstatus_fc(enc_softc_t *, enc_cache_t *,
+ uint8_t *, int);
+static int ses_get_elm_addlstatus_sas(enc_softc_t *, enc_cache_t *, uint8_t *,
+ int, int, int, int);
+
+/**
+ * \brief Parse the additional status element data for each object.
+ *
+ * \param enc The SES softc to update.
+ * \param buf The buffer containing the additional status
+ * element response.
+ * \param xfer_len Size of the buffer.
+ *
+ * \return 0 on success, errno otherwise.
+ */
+static int
+ses_process_elm_addlstatus(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
+{
+ struct ses_iterator iter, titer;
+ int eip;
+ int err;
+ int ignore_index = 0;
+ int length;
+ int offset;
+ enc_cache_t *enc_cache;
+ ses_cache_t *ses_cache;
+ uint8_t *buf;
+ ses_element_t *elmpriv;
+ const struct ses_page_hdr *hdr;
+ enc_element_t *element, *telement;
+
+ enc_cache = &enc->enc_daemon_cache;
+ ses_cache = enc_cache->private;
+ buf = *bufp;
+ err = -1;
+
+ if (error != 0) {
+ err = error;
+ goto out;
+ }
+ ses_cache_free_elm_addlstatus(enc, enc_cache);
+ ses_cache->elm_addlstatus_page =
+ (struct ses_addl_elem_status_page *)buf;
+ *bufp = NULL;
+
+ /*
+ * The objects appear in the same order here as in Enclosure Status,
+ * which itself is ordered by the Type Descriptors from the Config
+ * page. However, it is necessary to skip elements that are not
+ * supported by this page when counting them.
+ */
+ hdr = &ses_cache->elm_addlstatus_page->hdr;
+ length = ses_page_length(hdr);
+ ENC_DLOG(enc, "Additional Element Status Page Length 0x%x\n", length);
+ /* Make sure the length includes at least one header. */
+ if (length < sizeof(*hdr)+sizeof(struct ses_elm_addlstatus_base_hdr)) {
+ ENC_LOG(enc, "Runt Additional Element Status Page\n");
+ goto out;
+ }
+ if (length > xfer_len) {
+ ENC_LOG(enc, "Additional Element Status Page Too Long\n");
+ goto out;
+ }
+
+ if (!ses_config_cache_valid(ses_cache, hdr->gen_code)) {
+ ENC_DLOG(enc, "%s: Generation count change detected\n",
+ __func__);
+ enc_update_request(enc, SES_UPDATE_GETCONFIG);
+ goto out;
+ }
+
+ offset = sizeof(struct ses_page_hdr);
+ ses_iter_init(enc, enc_cache, &iter);
+ while (offset < length
+ && (element = ses_iter_next(&iter)) != NULL) {
+ struct ses_elm_addlstatus_base_hdr *elm_hdr;
+ int proto_info_len;
+ ses_addlstatus_avail_t status_type;
+
+ /*
+ * Additional element status is only provided for
+ * individual elements (i.e. overal status elements
+ * are excluded) and those of the types specified
+ * in the SES spec.
+ */
+ status_type = ses_typehasaddlstatus(enc, iter.type_index);
+ if (iter.individual_element_index == ITERATOR_INDEX_INVALID
+ || status_type == TYPE_ADDLSTATUS_NONE)
+ continue;
+
+ elm_hdr = (struct ses_elm_addlstatus_base_hdr *)&buf[offset];
+ eip = ses_elm_addlstatus_eip(elm_hdr);
+ if (eip && !ignore_index) {
+ struct ses_elm_addlstatus_eip_hdr *eip_hdr;
+ int expected_index;
+
+ eip_hdr = (struct ses_elm_addlstatus_eip_hdr *)elm_hdr;
+ expected_index = iter.individual_element_index;
+ titer = iter;
+ telement = ses_iter_seek_to(&titer,
+ eip_hdr->element_index,
+ SES_ELEM_INDEX_INDIVIDUAL);
+ if (telement != NULL &&
+ (ses_typehasaddlstatus(enc, titer.type_index) !=
+ TYPE_ADDLSTATUS_NONE ||
+ titer.type_index > ELMTYP_SAS_CONN)) {
+ iter = titer;
+ element = telement;
+ } else
+ ignore_index = 1;
+
+ if (iter.individual_element_index > expected_index
+ && status_type == TYPE_ADDLSTATUS_MANDATORY) {
+ ENC_LOG(enc, "%s: provided element "
+ "index %d skips mandatory status "
+ " element at index %d\n",
+ __func__, eip_hdr->element_index,
+ expected_index);
+ }
+ }
+ elmpriv = element->elm_private;
+ elmpriv->addl.hdr = elm_hdr;
+ ENC_DLOG(enc, "%s: global element index=%d, type index=%d "
+ "type element index=%d, offset=0x%x, "
+ "byte0=0x%x, length=0x%x\n", __func__,
+ iter.global_element_index, iter.type_index,
+ iter.type_element_index, offset, elmpriv->addl.hdr->byte0,
+ elmpriv->addl.hdr->length);
+
+ /* Skip to after the length field */
+ offset += sizeof(struct ses_elm_addlstatus_base_hdr);
+
+ /* Make sure the descriptor is within bounds */
+ if ((offset + elmpriv->addl.hdr->length) > length) {
+ ENC_LOG(enc, "Element %d Beyond End "
+ "of Additional Element Status Descriptors\n",
+ iter.global_element_index);
+ err = EIO;
+ goto out;
+ }
+
+ /* Advance to the protocol data, skipping eip bytes if needed */
+ offset += (eip * SES_EIP_HDR_EXTRA_LEN);
+ proto_info_len = elmpriv->addl.hdr->length
+ - (eip * SES_EIP_HDR_EXTRA_LEN);
+
+ /* Errors in this block are ignored as they are non-fatal */
+ switch(ses_elm_addlstatus_proto(elmpriv->addl.hdr)) {
+ case SPSP_PROTO_FC:
+ if (elmpriv->addl.hdr->length == 0)
+ break;
+ ses_get_elm_addlstatus_fc(enc, enc_cache,
+ &buf[offset], proto_info_len);
+ break;
+ case SPSP_PROTO_SAS:
+ if (elmpriv->addl.hdr->length <= 2)
+ break;
+ ses_get_elm_addlstatus_sas(enc, enc_cache,
+ &buf[offset],
+ proto_info_len,
+ eip, iter.type_index,
+ iter.global_element_index);
+ break;
+ default:
+ ENC_LOG(enc, "Element %d: Unknown Additional Element "
+ "Protocol 0x%x\n", iter.global_element_index,
+ ses_elm_addlstatus_proto(elmpriv->addl.hdr));
+ goto out;
+ }
+
+ offset += proto_info_len;
+ }
+ err = 0;
+out:
+ if (err)
+ ses_cache_free_elm_addlstatus(enc, enc_cache);
+ enc_update_request(enc, SES_PUBLISH_PHYSPATHS);
+ enc_update_request(enc, SES_PUBLISH_CACHE);
+ return (err);
+}
+
+static int
+ses_process_control_request(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
+{
+ ses_softc_t *ses;
+
+ ses = enc->enc_private;
+ /*
+ * Possible errors:
+ * o Generation count wrong.
+ * o Some SCSI status error.
+ */
+ ses_terminate_control_requests(&ses->ses_pending_requests, error);
+ enc_update_request(enc, SES_UPDATE_GETSTATUS);
+ return (0);
+}
+
+static int
+ses_publish_physpaths(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
+{
+ struct ses_iterator iter;
+ enc_cache_t *enc_cache;
+ ses_cache_t *ses_cache;
+ enc_element_t *element;
+
+ enc_cache = &enc->enc_daemon_cache;
+ ses_cache = enc_cache->private;
+
+ ses_iter_init(enc, enc_cache, &iter);
+ while ((element = ses_iter_next(&iter)) != NULL) {
+ /*
+ * ses_set_physpath() returns success if we changed
+ * the physpath of any element. This allows us to
+ * only announce devices once regardless of how
+ * many times we process additional element status.
+ */
+ if (ses_set_physpath(enc, element, &iter) == 0)
+ ses_print_addl_data(enc, element);
+ }
+
+ return (0);
+}
+
+static int
+ses_publish_cache(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
+{
+
+ sx_xlock(&enc->enc_cache_lock);
+ ses_cache_clone(enc, /*src*/&enc->enc_daemon_cache,
+ /*dst*/&enc->enc_cache);
+ sx_xunlock(&enc->enc_cache_lock);
+
+ return (0);
+}
+
+/**
+ * \brief Parse the descriptors for each object.
+ *
+ * \param enc The SES softc to update.
+ * \param buf The buffer containing the descriptor list response.
+ * \param xfer_len Size of the buffer.
+ *
+ * \return 0 on success, errno otherwise.
+ */
+static int
+ses_process_elm_descs(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
+{
+ ses_softc_t *ses;
+ struct ses_iterator iter;
+ enc_element_t *element;
+ int err;
+ int offset;
+ u_long length, plength;
+ enc_cache_t *enc_cache;
+ ses_cache_t *ses_cache;
+ uint8_t *buf;
+ ses_element_t *elmpriv;
+ const struct ses_page_hdr *phdr;
+ const struct ses_elm_desc_hdr *hdr;
+
+ ses = enc->enc_private;
+ enc_cache = &enc->enc_daemon_cache;
+ ses_cache = enc_cache->private;
+ buf = *bufp;
+ err = -1;
+
+ if (error != 0) {
+ err = error;
+ goto out;
+ }
+ ses_cache_free_elm_descs(enc, enc_cache);
+ ses_cache->elm_descs_page = (struct ses_elem_descr_page *)buf;
+ *bufp = NULL;
+
+ phdr = &ses_cache->elm_descs_page->hdr;
+ plength = ses_page_length(phdr);
+ if (xfer_len < sizeof(struct ses_page_hdr)) {
+ ENC_LOG(enc, "Runt Element Descriptor Page\n");
+ goto out;
+ }
+ if (plength > xfer_len) {
+ ENC_LOG(enc, "Element Descriptor Page Too Long\n");
+ goto out;
+ }
+
+ if (!ses_config_cache_valid(ses_cache, phdr->gen_code)) {
+ ENC_VLOG(enc, "%s: Generation count change detected\n",
+ __func__);
+ enc_update_request(enc, SES_UPDATE_GETCONFIG);
+ goto out;
+ }
+
+ offset = sizeof(struct ses_page_hdr);
+
+ ses_iter_init(enc, enc_cache, &iter);
+ while (offset < plength
+ && (element = ses_iter_next(&iter)) != NULL) {
+
+ if ((offset + sizeof(struct ses_elm_desc_hdr)) > plength) {
+ ENC_LOG(enc, "Element %d Descriptor Header Past "
+ "End of Buffer\n", iter.global_element_index);
+ goto out;
+ }
+ hdr = (struct ses_elm_desc_hdr *)&buf[offset];
+ length = scsi_2btoul(hdr->length);
+ ENC_DLOG(enc, "%s: obj %d(%d,%d) length=%d off=%d\n", __func__,
+ iter.global_element_index, iter.type_index,
+ iter.type_element_index, length, offset);
+ if ((offset + sizeof(*hdr) + length) > plength) {
+ ENC_LOG(enc, "Element%d Descriptor Past "
+ "End of Buffer\n", iter.global_element_index);
+ goto out;
+ }
+ offset += sizeof(*hdr);
+
+ if (length > 0) {
+ elmpriv = element->elm_private;
+ elmpriv->descr_len = length;
+ elmpriv->descr = &buf[offset];
+ }
+
+ /* skip over the descriptor itself */
+ offset += length;
+ }
+
+ err = 0;
+out:
+ if (err == 0) {
+ if (ses->ses_flags & SES_FLAG_ADDLSTATUS)
+ enc_update_request(enc, SES_UPDATE_GETELMADDLSTATUS);
+ }
+ enc_update_request(enc, SES_PUBLISH_CACHE);
+ return (err);
+}
+
+static int
+ses_fill_rcv_diag_io(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t *buf)
+{
+
+ if (enc->enc_type == ENC_SEMB_SES) {
+ semb_receive_diagnostic_results(&ccb->ataio, /*retries*/5,
+ enc_done, MSG_SIMPLE_Q_TAG, /*pcv*/1,
+ state->page_code, buf, state->buf_size,
+ state->timeout);
+ } else {
+ scsi_receive_diagnostic_results(&ccb->csio, /*retries*/5,
+ enc_done, MSG_SIMPLE_Q_TAG, /*pcv*/1,
+ state->page_code, buf, state->buf_size,
+ SSD_FULL_SIZE, state->timeout);
+ }
+ return (0);
+}
+
+/**
+ * \brief Encode the object status into the response buffer, which is
+ * expected to contain the current enclosure status. This function
+ * turns off all the 'select' bits for the objects except for the
+ * object specified, then sends it back to the enclosure.
+ *
+ * \param enc SES enclosure the change is being applied to.
+ * \param buf Buffer containing the current enclosure status response.
+ * \param amt Length of the response in the buffer.
+ * \param req The control request to be applied to buf.
+ *
+ * \return 0 on success, errno otherwise.
+ */
+static int
+ses_encode(enc_softc_t *enc, uint8_t *buf, int amt, ses_control_request_t *req)
+{
+ struct ses_iterator iter;
+ enc_element_t *element;
+ int offset;
+ struct ses_control_page_hdr *hdr;
+
+ ses_iter_init(enc, &enc->enc_cache, &iter);
+ hdr = (struct ses_control_page_hdr *)buf;
+ if (req->elm_idx == -1) {
+ /* for enclosure status, at least 2 bytes are needed */
+ if (amt < 2)
+ return EIO;
+ hdr->control_flags =
+ req->elm_stat.comstatus & SES_SET_STATUS_MASK;
+ ENC_DLOG(enc, "Set EncStat %x\n", hdr->control_flags);
+ return (0);
+ }
+
+ element = ses_iter_seek_to(&iter, req->elm_idx, SES_ELEM_INDEX_GLOBAL);
+ if (element == NULL)
+ return (ENXIO);
+
+ /*
+ * Seek to the type set that corresponds to the requested object.
+ * The +1 is for the overall status element for the type.
+ */
+ offset = sizeof(struct ses_control_page_hdr)
+ + (iter.global_element_index * sizeof(struct ses_comstat));
+
+ /* Check for buffer overflow. */
+ if (offset + sizeof(struct ses_comstat) > amt)
+ return (EIO);
+
+ /* Set the status. */
+ memcpy(&buf[offset], &req->elm_stat, sizeof(struct ses_comstat));
+
+ ENC_DLOG(enc, "Set Type 0x%x Obj 0x%x (offset %d) with %x %x %x %x\n",
+ iter.type_index, iter.global_element_index, offset,
+ req->elm_stat.comstatus, req->elm_stat.comstat[0],
+ req->elm_stat.comstat[1], req->elm_stat.comstat[2]);
+
+ return (0);
+}
+
+static int
+ses_fill_control_request(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t *buf)
+{
+ ses_softc_t *ses;
+ enc_cache_t *enc_cache;
+ ses_cache_t *ses_cache;
+ struct ses_control_page_hdr *hdr;
+ ses_control_request_t *req;
+ size_t plength;
+ size_t offset;
+
+ ses = enc->enc_private;
+ enc_cache = &enc->enc_daemon_cache;
+ ses_cache = enc_cache->private;
+ hdr = (struct ses_control_page_hdr *)buf;
+
+ if (ses_cache->status_page == NULL) {
+ ses_terminate_control_requests(&ses->ses_requests, EIO);
+ return (EIO);
+ }
+
+ plength = ses_page_length(&ses_cache->status_page->hdr);
+ memcpy(buf, ses_cache->status_page, plength);
+
+ /* Disable the select bits in all status entries. */
+ offset = sizeof(struct ses_control_page_hdr);
+ for (offset = sizeof(struct ses_control_page_hdr);
+ offset < plength; offset += sizeof(struct ses_comstat)) {
+ buf[offset] &= ~SESCTL_CSEL;
+ }
+
+ /* And make sure the INVOP bit is clear. */
+ hdr->control_flags &= ~SES_ENCSTAT_INVOP;
+
+ /* Apply incoming requests. */
+ while ((req = TAILQ_FIRST(&ses->ses_requests)) != NULL) {
+
+ TAILQ_REMOVE(&ses->ses_requests, req, links);
+ req->result = ses_encode(enc, buf, plength, req);
+ if (req->result != 0) {
+ wakeup(req);
+ continue;
+ }
+ TAILQ_INSERT_TAIL(&ses->ses_pending_requests, req, links);
+ }
+
+ if (TAILQ_EMPTY(&ses->ses_pending_requests) != 0)
+ return (ENOENT);
+
+ /* Fill out the ccb */
+ if (enc->enc_type == ENC_SEMB_SES) {
+ semb_send_diagnostic(&ccb->ataio, /*retries*/5, enc_done,
+ MSG_SIMPLE_Q_TAG,
+ buf, ses_page_length(&ses_cache->status_page->hdr),
+ state->timeout);
+ } else {
+ scsi_send_diagnostic(&ccb->csio, /*retries*/5, enc_done,
+ MSG_SIMPLE_Q_TAG, /*unit_offline*/0,
+ /*device_offline*/0, /*self_test*/0,
+ /*page_format*/1, /*self_test_code*/0,
+ buf, ses_page_length(&ses_cache->status_page->hdr),
+ SSD_FULL_SIZE, state->timeout);
+ }
+ return (0);
+}
+
+static int
+ses_get_elm_addlstatus_fc(enc_softc_t *enc, enc_cache_t *enc_cache,
+ uint8_t *buf, int bufsiz)
+{
+ ENC_LOG(enc, "FC Device Support Stubbed in Additional Status Page\n");
+ return (ENODEV);
+}
+
+#define SES_PRINT_PORTS(p, type) do { \
+ sbuf_printf(sbp, " %s(", type); \
+ if (((p) & SES_SASOBJ_DEV_PHY_PROTOMASK) == 0) \
+ sbuf_printf(sbp, " None"); \
+ else { \
+ if ((p) & SES_SASOBJ_DEV_PHY_SMP) \
+ sbuf_printf(sbp, " SMP"); \
+ if ((p) & SES_SASOBJ_DEV_PHY_STP) \
+ sbuf_printf(sbp, " STP"); \
+ if ((p) & SES_SASOBJ_DEV_PHY_SSP) \
+ sbuf_printf(sbp, " SSP"); \
+ } \
+ sbuf_printf(sbp, " )"); \
+} while(0)
+
+/**
+ * \brief Print the additional element status data for this object, for SAS
+ * type 0 objects. See SES2 r20 Section 6.1.13.3.2.
+ *
+ * \param sesname SES device name associated with the object.
+ * \param sbp Sbuf to print to.
+ * \param obj The object to print the data for.
+ * \param periph_name Peripheral string associated with the object.
+ */
+static void
+ses_print_addl_data_sas_type0(char *sesname, struct sbuf *sbp,
+ enc_element_t *obj, char *periph_name)
+{
+ int i;
+ ses_element_t *elmpriv;
+ struct ses_addl_status *addl;
+ struct ses_elm_sas_device_phy *phy;
+
+ elmpriv = obj->elm_private;
+ addl = &(elmpriv->addl);
+ if (addl->proto_hdr.sas == NULL)
+ return;
+ sbuf_printf(sbp, "%s: %s: SAS Device Slot Element:",
+ sesname, periph_name);
+ sbuf_printf(sbp, " %d Phys", addl->proto_hdr.sas->base_hdr.num_phys);
+ if (ses_elm_addlstatus_eip(addl->hdr))
+ sbuf_printf(sbp, " at Slot %d",
+ addl->proto_hdr.sas->type0_eip.dev_slot_num);
+ if (ses_elm_sas_type0_not_all_phys(addl->proto_hdr.sas))
+ sbuf_printf(sbp, ", Not All Phys");
+ sbuf_printf(sbp, "\n");
+ if (addl->proto_data.sasdev_phys == NULL)
+ return;
+ for (i = 0;i < addl->proto_hdr.sas->base_hdr.num_phys;i++) {
+ phy = &addl->proto_data.sasdev_phys[i];
+ sbuf_printf(sbp, "%s: phy %d:", sesname, i);
+ if (ses_elm_sas_dev_phy_sata_dev(phy))
+ /* Spec says all other fields are specific values */
+ sbuf_printf(sbp, " SATA device\n");
+ else {
+ sbuf_printf(sbp, " SAS device type %d id %d\n",
+ ses_elm_sas_dev_phy_dev_type(phy), phy->phy_id);
+ sbuf_printf(sbp, "%s: phy %d: protocols:", sesname, i);
+ SES_PRINT_PORTS(phy->initiator_ports, "Initiator");
+ SES_PRINT_PORTS(phy->target_ports, "Target");
+ sbuf_printf(sbp, "\n");
+ }
+ sbuf_printf(sbp, "%s: phy %d: parent %jx addr %jx\n",
+ sesname, i,
+ (uintmax_t)scsi_8btou64(phy->parent_addr),
+ (uintmax_t)scsi_8btou64(phy->phy_addr));
+ }
+}
+#undef SES_PRINT_PORTS
+
+/**
+ * \brief Report whether a given enclosure object is an expander.
+ *
+ * \param enc SES softc associated with object.
+ * \param obj Enclosure object to report for.
+ *
+ * \return 1 if true, 0 otherwise.
+ */
+static int
+ses_obj_is_expander(enc_softc_t *enc, enc_element_t *obj)
+{
+ return (obj->enctype == ELMTYP_SAS_EXP);
+}
+
+/**
+ * \brief Print the additional element status data for this object, for SAS
+ * type 1 objects. See SES2 r20 Sections 6.1.13.3.3 and 6.1.13.3.4.
+ *
+ * \param enc SES enclosure, needed for type identification.
+ * \param sesname SES device name associated with the object.
+ * \param sbp Sbuf to print to.
+ * \param obj The object to print the data for.
+ * \param periph_name Peripheral string associated with the object.
+ */
+static void
+ses_print_addl_data_sas_type1(enc_softc_t *enc, char *sesname,
+ struct sbuf *sbp, enc_element_t *obj, char *periph_name)
+{
+ int i, num_phys;
+ ses_element_t *elmpriv;
+ struct ses_addl_status *addl;
+ struct ses_elm_sas_expander_phy *exp_phy;
+ struct ses_elm_sas_port_phy *port_phy;
+
+ elmpriv = obj->elm_private;
+ addl = &(elmpriv->addl);
+ if (addl->proto_hdr.sas == NULL)
+ return;
+ sbuf_printf(sbp, "%s: %s: SAS ", sesname, periph_name);
+ if (ses_obj_is_expander(enc, obj)) {
+ num_phys = addl->proto_hdr.sas->base_hdr.num_phys;
+ sbuf_printf(sbp, "Expander: %d Phys", num_phys);
+ if (addl->proto_data.sasexp_phys == NULL)
+ return;
+ for (i = 0;i < num_phys;i++) {
+ exp_phy = &addl->proto_data.sasexp_phys[i];
+ sbuf_printf(sbp, "%s: phy %d: connector %d other %d\n",
+ sesname, i, exp_phy->connector_index,
+ exp_phy->other_index);
+ }
+ } else {
+ num_phys = addl->proto_hdr.sas->base_hdr.num_phys;
+ sbuf_printf(sbp, "Port: %d Phys", num_phys);
+ if (addl->proto_data.sasport_phys == NULL)
+ return;
+ for (i = 0;i < num_phys;i++) {
+ port_phy = &addl->proto_data.sasport_phys[i];
+ sbuf_printf(sbp,
+ "%s: phy %d: id %d connector %d other %d\n",
+ sesname, i, port_phy->phy_id,
+ port_phy->connector_index, port_phy->other_index);
+ sbuf_printf(sbp, "%s: phy %d: addr %jx\n", sesname, i,
+ (uintmax_t)scsi_8btou64(port_phy->phy_addr));
+ }
+ }
+}
+
+/**
+ * \brief Print the additional element status data for this object.
+ *
+ * \param enc SES softc associated with the object.
+ * \param obj The object to print the data for.
+ */
+static void
+ses_print_addl_data(enc_softc_t *enc, enc_element_t *obj)
+{
+ ses_element_t *elmpriv;
+ struct ses_addl_status *addl;
+ struct sbuf sesname, name, out;
+
+ elmpriv = obj->elm_private;
+ if (elmpriv == NULL)
+ return;
+
+ addl = &(elmpriv->addl);
+ if (addl->hdr == NULL)
+ return;
+
+ sbuf_new(&sesname, NULL, 16, SBUF_AUTOEXTEND);
+ sbuf_new(&name, NULL, 16, SBUF_AUTOEXTEND);
+ sbuf_new(&out, NULL, 512, SBUF_AUTOEXTEND);
+ ses_paths_iter(enc, obj, ses_elmdevname_callback, &name);
+ if (sbuf_len(&name) == 0)
+ sbuf_printf(&name, "(none)");
+ sbuf_finish(&name);
+ sbuf_printf(&sesname, "%s%d", enc->periph->periph_name,
+ enc->periph->unit_number);
+ sbuf_finish(&sesname);
+ if (elmpriv->descr != NULL)
+ sbuf_printf(&out, "%s: %s: Element descriptor: '%s'\n",
+ sbuf_data(&sesname), sbuf_data(&name), elmpriv->descr);
+ switch(ses_elm_addlstatus_proto(addl->hdr)) {
+ case SPSP_PROTO_SAS:
+ switch(ses_elm_sas_descr_type(addl->proto_hdr.sas)) {
+ case SES_SASOBJ_TYPE_SLOT:
+ ses_print_addl_data_sas_type0(sbuf_data(&sesname),
+ &out, obj, sbuf_data(&name));
+ break;
+ case SES_SASOBJ_TYPE_OTHER:
+ ses_print_addl_data_sas_type1(enc, sbuf_data(&sesname),
+ &out, obj, sbuf_data(&name));
+ break;
+ default:
+ break;
+ }
+ break;
+ case SPSP_PROTO_FC: /* stubbed for now */
+ break;
+ default:
+ break;
+ }
+ sbuf_finish(&out);
+ printf("%s", sbuf_data(&out));
+ sbuf_delete(&out);
+ sbuf_delete(&name);
+ sbuf_delete(&sesname);
+}
+
+/**
+ * \brief Update the softc with the additional element status data for this
+ * object, for SAS type 0 objects.
+ *
+ * \param enc SES softc to be updated.
+ * \param buf The additional element status response buffer.
+ * \param bufsiz Size of the response buffer.
+ * \param eip The EIP bit value.
+ * \param nobj Number of objects attached to the SES softc.
+ *
+ * \return 0 on success, errno otherwise.
+ */
+static int
+ses_get_elm_addlstatus_sas_type0(enc_softc_t *enc, enc_cache_t *enc_cache,
+ uint8_t *buf, int bufsiz, int eip, int nobj)
+{
+ int err, offset, physz;
+ enc_element_t *obj;
+ ses_element_t *elmpriv;
+ struct ses_addl_status *addl;
+
+ err = offset = 0;
+
+ /* basic object setup */
+ obj = &(enc_cache->elm_map[nobj]);
+ elmpriv = obj->elm_private;
+ addl = &(elmpriv->addl);
+
+ addl->proto_hdr.sas = (union ses_elm_sas_hdr *)&buf[offset];
+
+ /* Don't assume this object has any phys */
+ bzero(&addl->proto_data, sizeof(addl->proto_data));
+ if (addl->proto_hdr.sas->base_hdr.num_phys == 0)
+ goto out;
+
+ /* Skip forward to the phy list */
+ if (eip)
+ offset += sizeof(struct ses_elm_sas_type0_eip_hdr);
+ else
+ offset += sizeof(struct ses_elm_sas_type0_base_hdr);
+
+ /* Make sure the phy list fits in the buffer */
+ physz = addl->proto_hdr.sas->base_hdr.num_phys;
+ physz *= sizeof(struct ses_elm_sas_device_phy);
+ if (physz > (bufsiz - offset + 4)) {
+ ENC_LOG(enc, "Element %d Device Phy List Beyond End Of Buffer\n",
+ nobj);
+ err = EIO;
+ goto out;
+ }
+
+ /* Point to the phy list */
+ addl->proto_data.sasdev_phys =
+ (struct ses_elm_sas_device_phy *)&buf[offset];
+
+out:
+ return (err);
+}
+
+/**
+ * \brief Update the softc with the additional element status data for this
+ * object, for SAS type 1 objects.
+ *
+ * \param enc SES softc to be updated.
+ * \param buf The additional element status response buffer.
+ * \param bufsiz Size of the response buffer.
+ * \param eip The EIP bit value.
+ * \param nobj Number of objects attached to the SES softc.
+ *
+ * \return 0 on success, errno otherwise.
+ */
+static int
+ses_get_elm_addlstatus_sas_type1(enc_softc_t *enc, enc_cache_t *enc_cache,
+ uint8_t *buf, int bufsiz, int eip, int nobj)
+{
+ int err, offset, physz;
+ enc_element_t *obj;
+ ses_element_t *elmpriv;
+ struct ses_addl_status *addl;
+
+ err = offset = 0;
+
+ /* basic object setup */
+ obj = &(enc_cache->elm_map[nobj]);
+ elmpriv = obj->elm_private;
+ addl = &(elmpriv->addl);
+
+ addl->proto_hdr.sas = (union ses_elm_sas_hdr *)&buf[offset];
+
+ /* Don't assume this object has any phys */
+ bzero(&addl->proto_data, sizeof(addl->proto_data));
+ if (addl->proto_hdr.sas->base_hdr.num_phys == 0)
+ goto out;
+
+ /* Process expanders differently from other type1 cases */
+ if (ses_obj_is_expander(enc, obj)) {
+ offset += sizeof(struct ses_elm_sas_type1_expander_hdr);
+ physz = addl->proto_hdr.sas->base_hdr.num_phys *
+ sizeof(struct ses_elm_sas_expander_phy);
+ if (physz > (bufsiz - offset)) {
+ ENC_LOG(enc, "Element %d: Expander Phy List Beyond "
+ "End Of Buffer\n", nobj);
+ err = EIO;
+ goto out;
+ }
+ addl->proto_data.sasexp_phys =
+ (struct ses_elm_sas_expander_phy *)&buf[offset];
+ } else {
+ offset += sizeof(struct ses_elm_sas_type1_nonexpander_hdr);
+ physz = addl->proto_hdr.sas->base_hdr.num_phys *
+ sizeof(struct ses_elm_sas_port_phy);
+ if (physz > (bufsiz - offset + 4)) {
+ ENC_LOG(enc, "Element %d: Port Phy List Beyond End "
+ "Of Buffer\n", nobj);
+ err = EIO;
+ goto out;
+ }
+ addl->proto_data.sasport_phys =
+ (struct ses_elm_sas_port_phy *)&buf[offset];
+ }
+
+out:
+ return (err);
+}
+
+/**
+ * \brief Update the softc with the additional element status data for this
+ * object, for SAS objects.
+ *
+ * \param enc SES softc to be updated.
+ * \param buf The additional element status response buffer.
+ * \param bufsiz Size of the response buffer.
+ * \param eip The EIP bit value.
+ * \param tidx Type index for this object.
+ * \param nobj Number of objects attached to the SES softc.
+ *
+ * \return 0 on success, errno otherwise.
+ */
+static int
+ses_get_elm_addlstatus_sas(enc_softc_t *enc, enc_cache_t *enc_cache,
+ uint8_t *buf, int bufsiz, int eip, int tidx,
+ int nobj)
+{
+ int dtype, err;
+ ses_cache_t *ses_cache;
+ union ses_elm_sas_hdr *hdr;
+
+ /* Need to be able to read the descriptor type! */
+ if (bufsiz < sizeof(union ses_elm_sas_hdr)) {
+ err = EIO;
+ goto out;
+ }
+
+ ses_cache = enc_cache->private;
+
+ hdr = (union ses_elm_sas_hdr *)buf;
+ dtype = ses_elm_sas_descr_type(hdr);
+ switch(dtype) {
+ case SES_SASOBJ_TYPE_SLOT:
+ switch(ses_cache->ses_types[tidx].hdr->etype_elm_type) {
+ case ELMTYP_DEVICE:
+ case ELMTYP_ARRAY_DEV:
+ break;
+ default:
+ ENC_LOG(enc, "Element %d has Additional Status type 0, "
+ "invalid for SES element type 0x%x\n", nobj,
+ ses_cache->ses_types[tidx].hdr->etype_elm_type);
+ err = ENODEV;
+ goto out;
+ }
+ err = ses_get_elm_addlstatus_sas_type0(enc, enc_cache,
+ buf, bufsiz, eip,
+ nobj);
+ break;
+ case SES_SASOBJ_TYPE_OTHER:
+ switch(ses_cache->ses_types[tidx].hdr->etype_elm_type) {
+ case ELMTYP_SAS_EXP:
+ case ELMTYP_SCSI_INI:
+ case ELMTYP_SCSI_TGT:
+ case ELMTYP_ESCC:
+ break;
+ default:
+ ENC_LOG(enc, "Element %d has Additional Status type 1, "
+ "invalid for SES element type 0x%x\n", nobj,
+ ses_cache->ses_types[tidx].hdr->etype_elm_type);
+ err = ENODEV;
+ goto out;
+ }
+ err = ses_get_elm_addlstatus_sas_type1(enc, enc_cache, buf,
+ bufsiz, eip, nobj);
+ break;
+ default:
+ ENC_LOG(enc, "Element %d of type 0x%x has Additional Status "
+ "of unknown type 0x%x\n", nobj,
+ ses_cache->ses_types[tidx].hdr->etype_elm_type, dtype);
+ err = ENODEV;
+ break;
+ }
+
+out:
+ return (err);
+}
+
+static void
+ses_softc_invalidate(enc_softc_t *enc)
+{
+ ses_softc_t *ses;
+
+ ses = enc->enc_private;
+ ses_terminate_control_requests(&ses->ses_requests, ENXIO);
+}
+
+static void
+ses_softc_cleanup(enc_softc_t *enc)
+{
+
+ ses_cache_free(enc, &enc->enc_cache);
+ ses_cache_free(enc, &enc->enc_daemon_cache);
+ ENC_FREE_AND_NULL(enc->enc_private);
+ ENC_FREE_AND_NULL(enc->enc_cache.private);
+ ENC_FREE_AND_NULL(enc->enc_daemon_cache.private);
+}
+
+static int
+ses_init_enc(enc_softc_t *enc)
+{
+ return (0);
+}
+
+static int
+ses_get_enc_status(enc_softc_t *enc, int slpflag)
+{
+ /* Automatically updated, caller checks enc_cache->encstat itself */
+ return (0);
+}
+
+static int
+ses_set_enc_status(enc_softc_t *enc, uint8_t encstat, int slpflag)
+{
+ ses_control_request_t req;
+ ses_softc_t *ses;
+
+ ses = enc->enc_private;
+ req.elm_idx = SES_SETSTATUS_ENC_IDX;
+ req.elm_stat.comstatus = encstat & 0xf;
+
+ TAILQ_INSERT_TAIL(&ses->ses_requests, &req, links);
+ enc_update_request(enc, SES_PROCESS_CONTROL_REQS);
+ cam_periph_sleep(enc->periph, &req, PUSER, "encstat", 0);
+
+ return (req.result);
+}
+
+static int
+ses_get_elm_status(enc_softc_t *enc, encioc_elm_status_t *elms, int slpflag)
+{
+ unsigned int i = elms->elm_idx;
+
+ memcpy(elms->cstat, &enc->enc_cache.elm_map[i].encstat, 4);
+ return (0);
+}
+
+static int
+ses_set_elm_status(enc_softc_t *enc, encioc_elm_status_t *elms, int slpflag)
+{
+ ses_control_request_t req;
+ ses_softc_t *ses;
+
+ /* If this is clear, we don't do diddly. */
+ if ((elms->cstat[0] & SESCTL_CSEL) == 0)
+ return (0);
+
+ ses = enc->enc_private;
+ req.elm_idx = elms->elm_idx;
+ memcpy(&req.elm_stat, elms->cstat, sizeof(req.elm_stat));
+
+ TAILQ_INSERT_TAIL(&ses->ses_requests, &req, links);
+ enc_update_request(enc, SES_PROCESS_CONTROL_REQS);
+ cam_periph_sleep(enc->periph, &req, PUSER, "encstat", 0);
+
+ return (req.result);
+}
+
+static int
+ses_get_elm_desc(enc_softc_t *enc, encioc_elm_desc_t *elmd)
+{
+ int i = (int)elmd->elm_idx;
+ ses_element_t *elmpriv;
+
+ /* Assume caller has already checked obj_id validity */
+ elmpriv = enc->enc_cache.elm_map[i].elm_private;
+ /* object might not have a descriptor */
+ if (elmpriv == NULL || elmpriv->descr == NULL) {
+ elmd->elm_desc_len = 0;
+ return (0);
+ }
+ if (elmd->elm_desc_len > elmpriv->descr_len)
+ elmd->elm_desc_len = elmpriv->descr_len;
+ copyout(elmpriv->descr, elmd->elm_desc_str, elmd->elm_desc_len);
+ return (0);
+}
+
+/**
+ * \brief Respond to ENCIOC_GETELMDEVNAME, providing a device name for the
+ * given object id if one is available.
+ *
+ * \param enc SES softc to examine.
+ * \param objdn ioctl structure to read/write device name info.
+ *
+ * \return 0 on success, errno otherwise.
+ */
+static int
+ses_get_elm_devnames(enc_softc_t *enc, encioc_elm_devnames_t *elmdn)
+{
+ struct sbuf sb;
+ int len;
+
+ len = elmdn->elm_names_size;
+ if (len < 0)
+ return (EINVAL);
+
+ sbuf_new(&sb, elmdn->elm_devnames, len, 0);
+
+ cam_periph_unlock(enc->periph);
+ ses_paths_iter(enc, &enc->enc_cache.elm_map[elmdn->elm_idx],
+ ses_elmdevname_callback, &sb);
+ sbuf_finish(&sb);
+ elmdn->elm_names_len = sbuf_len(&sb);
+ cam_periph_lock(enc->periph);
+ return (elmdn->elm_names_len > 0 ? 0 : ENODEV);
+}
+
+/**
+ * \brief Send a string to the primary subenclosure using the String Out
+ * SES diagnostic page.
+ *
+ * \param enc SES enclosure to run the command on.
+ * \param sstr SES string structure to operate on
+ * \param ioc Ioctl being performed
+ *
+ * \return 0 on success, errno otherwise.
+ */
+static int
+ses_handle_string(enc_softc_t *enc, encioc_string_t *sstr, int ioc)
+{
+ int amt, payload, ret;
+ char cdb[6];
+ uint8_t *buf;
+
+ /* Implement SES2r20 6.1.6 */
+ if (sstr->bufsiz > 0xffff)
+ return (EINVAL); /* buffer size too large */
+
+ if (ioc == ENCIOC_SETSTRING) {
+ payload = sstr->bufsiz + 4; /* header for SEND DIAGNOSTIC */
+ amt = 0 - payload;
+ buf = ENC_MALLOC(payload);
+ if (buf == NULL)
+ return ENOMEM;
+
+ ses_page_cdb(cdb, payload, 0, CAM_DIR_OUT);
+ /* Construct the page request */
+ buf[0] = SesStringOut;
+ buf[1] = 0;
+ buf[2] = sstr->bufsiz >> 8;
+ buf[3] = sstr->bufsiz & 0xff;
+ memcpy(&buf[4], sstr->buf, sstr->bufsiz);
+ } else if (ioc == ENCIOC_GETSTRING) {
+ payload = sstr->bufsiz;
+ amt = payload;
+ ses_page_cdb(cdb, payload, SesStringIn, CAM_DIR_IN);
+ buf = sstr->buf;
+ } else
+ return EINVAL;
+
+ ret = enc_runcmd(enc, cdb, 6, buf, &amt);
+ if (ioc == ENCIOC_SETSTRING)
+ ENC_FREE(buf);
+ return ret;
+}
+
+/**
+ * \invariant Called with cam_periph mutex held.
+ */
+static void
+ses_poll_status(enc_softc_t *enc)
+{
+ ses_softc_t *ses;
+
+ ses = enc->enc_private;
+ enc_update_request(enc, SES_UPDATE_GETSTATUS);
+ if (ses->ses_flags & SES_FLAG_ADDLSTATUS)
+ enc_update_request(enc, SES_UPDATE_GETELMADDLSTATUS);
+}
+
+/**
+ * \brief Notification received when CAM detects a new device in the
+ * SCSI domain in which this SEP resides.
+ *
+ * \param enc SES enclosure instance.
+ */
+static void
+ses_device_found(enc_softc_t *enc)
+{
+ ses_poll_status(enc);
+ enc_update_request(enc, SES_PUBLISH_PHYSPATHS);
+}
+
+static struct enc_vec ses_enc_vec =
+{
+ .softc_invalidate = ses_softc_invalidate,
+ .softc_cleanup = ses_softc_cleanup,
+ .init_enc = ses_init_enc,
+ .get_enc_status = ses_get_enc_status,
+ .set_enc_status = ses_set_enc_status,
+ .get_elm_status = ses_get_elm_status,
+ .set_elm_status = ses_set_elm_status,
+ .get_elm_desc = ses_get_elm_desc,
+ .get_elm_devnames = ses_get_elm_devnames,
+ .handle_string = ses_handle_string,
+ .device_found = ses_device_found,
+ .poll_status = ses_poll_status
+};
+
+/**
+ * \brief Initialize a new SES instance.
+ *
+ * \param enc SES softc structure to set up the instance in.
+ * \param doinit Do the initialization (see main driver).
+ *
+ * \return 0 on success, errno otherwise.
+ */
+int
+ses_softc_init(enc_softc_t *enc)
+{
+ ses_softc_t *ses_softc;
+
+ CAM_DEBUG(enc->periph->path, CAM_DEBUG_SUBTRACE,
+ ("entering enc_softc_init(%p)\n", enc));
+
+ enc->enc_vec = ses_enc_vec;
+ enc->enc_fsm_states = enc_fsm_states;
+
+ if (enc->enc_private == NULL)
+ enc->enc_private = ENC_MALLOCZ(sizeof(ses_softc_t));
+ if (enc->enc_cache.private == NULL)
+ enc->enc_cache.private = ENC_MALLOCZ(sizeof(ses_cache_t));
+ if (enc->enc_daemon_cache.private == NULL)
+ enc->enc_daemon_cache.private =
+ ENC_MALLOCZ(sizeof(ses_cache_t));
+
+ if (enc->enc_private == NULL
+ || enc->enc_cache.private == NULL
+ || enc->enc_daemon_cache.private == NULL) {
+ ENC_FREE_AND_NULL(enc->enc_private);
+ ENC_FREE_AND_NULL(enc->enc_cache.private);
+ ENC_FREE_AND_NULL(enc->enc_daemon_cache.private);
+ return (ENOMEM);
+ }
+
+ ses_softc = enc->enc_private;
+ TAILQ_INIT(&ses_softc->ses_requests);
+ TAILQ_INIT(&ses_softc->ses_pending_requests);
+
+ enc_update_request(enc, SES_UPDATE_PAGES);
+
+ // XXX: Move this to the FSM so it doesn't hang init
+ if (0) (void) ses_set_timed_completion(enc, 1);
+
+ return (0);
+}
+
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_pass.c
--- a/head/sys/cam/scsi/scsi_pass.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/scsi/scsi_pass.c Wed Jul 25 16:45:04 2012 +0300
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_pass.c 223089 2011-06-14 17:10:32Z gibbs $");
+__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_pass.c 237328 2012-06-20 17:08:00Z ken $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -55,7 +55,8 @@
typedef enum {
PASS_FLAG_OPEN = 0x01,
PASS_FLAG_LOCKED = 0x02,
- PASS_FLAG_INVALID = 0x04
+ PASS_FLAG_INVALID = 0x04,
+ PASS_FLAG_INITIAL_PHYSPATH = 0x08
} pass_flags;
typedef enum {
@@ -111,7 +112,7 @@
static struct cdevsw pass_cdevsw = {
.d_version = D_VERSION,
- .d_flags = 0,
+ .d_flags = D_TRACKCLOSE,
.d_open = passopen,
.d_close = passclose,
.d_ioctl = passioctl,
@@ -133,7 +134,18 @@
printf("pass: Failed to attach master async callback "
"due to status 0x%x!\n", status);
}
-
+
+}
+
+static void
+passdevgonecb(void *arg)
+{
+ struct cam_periph *periph;
+
+ periph = (struct cam_periph *)arg;
+
+ xpt_print(periph->path, "%s: devfs entry is gone\n", __func__);
+ cam_periph_release(periph);
}
static void
@@ -151,6 +163,12 @@
softc->flags |= PASS_FLAG_INVALID;
/*
+ * Tell devfs this device has gone away, and ask for a callback
+ * when it has cleaned up its state.
+ */
+ destroy_dev_sched_cb(softc->dev, passdevgonecb, periph);
+
+ /*
* XXX Return all queued I/O with ENXIO.
* XXX Handle any transactions queued to the card
* with XPT_ABORT_CCB.
@@ -176,11 +194,6 @@
cam_periph_unlock(periph);
taskqueue_drain(taskqueue_thread, &softc->add_physpath_task);
- /*
- * passcleanup() is indirectly a d_close method via passclose,
- * so using destroy_dev(9) directly can result in deadlock.
- */
- destroy_dev_sched(softc->dev);
cam_periph_lock(periph);
free(softc, M_DEVBUF);
@@ -199,6 +212,12 @@
*/
periph = context;
softc = periph->softc;
+ cam_periph_lock(periph);
+ if (periph->flags & CAM_PERIPH_INVALID) {
+ cam_periph_unlock(periph);
+ return;
+ }
+ cam_periph_unlock(periph);
physpath = malloc(MAXPATHLEN, M_DEVBUF, M_WAITOK);
if (xpt_getattr(physpath, MAXPATHLEN,
"GEOM::physpath", periph->path) == 0
@@ -208,6 +227,19 @@
softc->dev, softc->alias_dev, physpath);
}
free(physpath, M_DEVBUF);
+
+ /*
+ * Now that we've made our alias, we no longer have to have a
+ * reference to the device.
+ */
+ cam_periph_lock(periph);
+ if ((softc->flags & PASS_FLAG_INITIAL_PHYSPATH) == 0) {
+ softc->flags |= PASS_FLAG_INITIAL_PHYSPATH;
+ cam_periph_unlock(periph);
+ dev_rel(softc->dev);
+ }
+ else
+ cam_periph_unlock(periph);
}
static void
@@ -281,12 +313,12 @@
cgd = (struct ccb_getdev *)arg;
if (periph == NULL) {
- printf("passregister: periph was NULL!!\n");
+ printf("%s: periph was NULL!!\n", __func__);
return(CAM_REQ_CMP_ERR);
}
if (cgd == NULL) {
- printf("passregister: no getdev CCB, can't register device\n");
+ printf("%s: no getdev CCB, can't register device\n", __func__);
return(CAM_REQ_CMP_ERR);
}
@@ -294,8 +326,8 @@
M_DEVBUF, M_NOWAIT);
if (softc == NULL) {
- printf("passregister: Unable to probe new device. "
- "Unable to allocate softc\n");
+ printf("%s: Unable to probe new device. "
+ "Unable to allocate softc\n", __func__);
return(CAM_REQ_CMP_ERR);
}
@@ -331,10 +363,31 @@
DEVSTAT_TYPE_PASS,
DEVSTAT_PRIORITY_PASS);
+ /*
+ * Acquire a reference to the periph before we create the devfs
+ * instance for it. We'll release this reference once the devfs
+ * instance has been freed.
+ */
+ if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
+ xpt_print(periph->path, "%s: lost periph during "
+ "registration!\n", __func__);
+ mtx_lock(periph->sim->mtx);
+ return (CAM_REQ_CMP_ERR);
+ }
+
/* Register the device */
softc->dev = make_dev(&pass_cdevsw, periph->unit_number,
UID_ROOT, GID_OPERATOR, 0600, "%s%d",
periph->periph_name, periph->unit_number);
+
+ /*
+ * Now that we have made the devfs instance, hold a reference to it
+ * until the task queue has run to setup the physical path alias.
+ * That way devfs won't get rid of the device before we add our
+ * alias.
+ */
+ dev_ref(softc->dev);
+
mtx_lock(periph->sim->mtx);
softc->dev->si_drv1 = periph;
@@ -377,8 +430,8 @@
softc = (struct pass_softc *)periph->softc;
if (softc->flags & PASS_FLAG_INVALID) {
+ cam_periph_release_locked(periph);
cam_periph_unlock(periph);
- cam_periph_release(periph);
return(ENXIO);
}
@@ -387,8 +440,8 @@
*/
error = securelevel_gt(td->td_ucred, 1);
if (error) {
+ cam_periph_release_locked(periph);
cam_periph_unlock(periph);
- cam_periph_release(periph);
return(error);
}
@@ -396,8 +449,8 @@
* Only allow read-write access.
*/
if (((flags & FWRITE) == 0) || ((flags & FREAD) == 0)) {
+ cam_periph_release_locked(periph);
cam_periph_unlock(periph);
- cam_periph_release(periph);
return(EPERM);
}
@@ -406,19 +459,12 @@
*/
if ((flags & O_NONBLOCK) != 0) {
xpt_print(periph->path, "can't do nonblocking access\n");
+ cam_periph_release_locked(periph);
cam_periph_unlock(periph);
- cam_periph_release(periph);
return(EINVAL);
}
- if ((softc->flags & PASS_FLAG_OPEN) == 0) {
- softc->flags |= PASS_FLAG_OPEN;
- cam_periph_unlock(periph);
- } else {
- /* Device closes aren't symmertical, so fix up the refcount */
- cam_periph_unlock(periph);
- cam_periph_release(periph);
- }
+ cam_periph_unlock(periph);
return (error);
}
@@ -427,18 +473,11 @@
passclose(struct cdev *dev, int flag, int fmt, struct thread *td)
{
struct cam_periph *periph;
- struct pass_softc *softc;
periph = (struct cam_periph *)dev->si_drv1;
if (periph == NULL)
return (ENXIO);
- cam_periph_lock(periph);
-
- softc = (struct pass_softc *)periph->softc;
- softc->flags &= ~PASS_FLAG_OPEN;
-
- cam_periph_unlock(periph);
cam_periph_release(periph);
return (0);
@@ -638,9 +677,9 @@
* that request. Otherwise, it's up to the user to perform any
* error recovery.
*/
- cam_periph_runccb(ccb,
- (ccb->ccb_h.flags & CAM_PASS_ERR_RECOVER) ? passerror : NULL,
- /* cam_flags */ CAM_RETRY_SELTO, /* sense_flags */SF_RETRY_UA,
+ cam_periph_runccb(ccb, passerror, /* cam_flags */ CAM_RETRY_SELTO,
+ /* sense_flags */ ((ccb->ccb_h.flags & CAM_PASS_ERR_RECOVER) ?
+ SF_RETRY_UA : SF_NO_RECOVERY) | SF_NO_PRINT,
softc->device_stats);
if (need_unmap != 0)
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_pt.c
--- a/head/sys/cam/scsi/scsi_pt.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/scsi/scsi_pt.c Wed Jul 25 16:45:04 2012 +0300
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_pt.c 220644 2011-04-14 21:25:32Z mav $");
+__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_pt.c 236602 2012-06-05 09:45:42Z mav $");
#include <sys/param.h>
#include <sys/queue.h>
@@ -148,8 +148,8 @@
cam_periph_lock(periph);
if (softc->flags & PT_FLAG_DEVICE_INVALID) {
+ cam_periph_release_locked(periph);
cam_periph_unlock(periph);
- cam_periph_release(periph);
return(ENXIO);
}
@@ -182,8 +182,8 @@
cam_periph_lock(periph);
softc->flags &= ~PT_FLAG_OPEN;
+ cam_periph_release_locked(periph);
cam_periph_unlock(periph);
- cam_periph_release(periph);
return (0);
}
@@ -425,12 +425,14 @@
softc = (struct pt_softc *)periph->softc;
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("ptstart\n"));
+
/*
* See if there is a buf with work for us to do..
*/
bp = bioq_first(&softc->bio_queue);
if (periph->immediate_priority <= periph->pinfo.priority) {
- CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
+ CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE,
("queuing for immediate ccb\n"));
start_ccb->ccb_h.ccb_state = PT_CCB_WAITING;
SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
@@ -483,6 +485,9 @@
struct ccb_scsiio *csio;
softc = (struct pt_softc *)periph->softc;
+
+ CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("ptdone\n"));
+
csio = &done_ccb->csio;
switch (csio->ccb_h.ccb_state) {
case PT_CCB_BUFFER_IO:
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_sa.c
--- a/head/sys/cam/scsi/scsi_sa.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/scsi/scsi_sa.c Wed Jul 25 16:45:04 2012 +0300
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_sa.c 229288 2012-01-02 17:02:45Z mav $");
+__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_sa.c 236712 2012-06-07 10:05:51Z mav $");
#include <sys/param.h>
#include <sys/queue.h>
@@ -1482,10 +1482,6 @@
softc->quirks = ((struct sa_quirk_entry *)match)->quirks;
softc->last_media_blksize =
((struct sa_quirk_entry *)match)->prefblk;
-#ifdef CAMDEBUG
- xpt_print(periph->path, "found quirk entry %d\n",
- (int) (((struct sa_quirk_entry *) match) - sa_quirk_table));
-#endif
} else
softc->quirks = SA_QUIRK_NONE;
@@ -1798,13 +1794,11 @@
*/
if (error || (softc->flags & SA_FLAG_ERR_PENDING))
cam_release_devq(done_ccb->ccb_h.path, 0, 0, 0, 0);
-#ifdef CAMDEBUG
if (error || bp->bio_resid) {
CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
("error %d resid %ld count %ld\n", error,
bp->bio_resid, bp->bio_bcount));
}
-#endif
biofinish(bp, softc->device_stats, 0);
break;
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_ses.c
--- a/head/sys/cam/scsi/scsi_ses.c Wed Jul 25 16:42:35 2012 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2533 +0,0 @@
-/*-
- * Copyright (c) 2000 Matthew Jacob
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification, immediately at the beginning of the file.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_ses.c 229288 2012-01-02 17:02:45Z mav $");
-
-#include <sys/param.h>
-#include <sys/queue.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/types.h>
-#include <sys/malloc.h>
-#include <sys/fcntl.h>
-#include <sys/conf.h>
-#include <sys/errno.h>
-#include <machine/stdarg.h>
-
-#include <cam/cam.h>
-#include <cam/cam_ccb.h>
-#include <cam/cam_periph.h>
-#include <cam/cam_xpt_periph.h>
-#include <cam/cam_debug.h>
-#include <cam/cam_sim.h>
-
-#include <cam/scsi/scsi_all.h>
-#include <cam/scsi/scsi_message.h>
-#include <sys/ioccom.h>
-#include <cam/scsi/scsi_ses.h>
-
-#include <opt_ses.h>
-
-static MALLOC_DEFINE(M_SCSISES, "SCSI SES", "SCSI SES buffers");
-
-/*
- * Platform Independent Driver Internal Definitions for SES devices.
- */
-typedef enum {
- SES_NONE,
- SES_SES_SCSI2,
- SES_SES,
- SES_SES_PASSTHROUGH,
- SES_SEN,
- SES_SAFT
-} enctyp;
-
-struct ses_softc;
-typedef struct ses_softc ses_softc_t;
-typedef struct {
- int (*softc_init)(ses_softc_t *, int);
- int (*init_enc)(ses_softc_t *);
- int (*get_encstat)(ses_softc_t *, int);
- int (*set_encstat)(ses_softc_t *, ses_encstat, int);
- int (*get_objstat)(ses_softc_t *, ses_objstat *, int);
- int (*set_objstat)(ses_softc_t *, ses_objstat *, int);
-} encvec;
-
-#define ENCI_SVALID 0x80
-
-typedef struct {
- uint32_t
- enctype : 8, /* enclosure type */
- subenclosure : 8, /* subenclosure id */
- svalid : 1, /* enclosure information valid */
- priv : 15; /* private data, per object */
- uint8_t encstat[4]; /* state && stats */
-} encobj;
-
-#define SEN_ID "UNISYS SUN_SEN"
-#define SEN_ID_LEN 24
-
-
-static enctyp ses_type(void *, int);
-
-
-/* Forward reference to Enclosure Functions */
-static int ses_softc_init(ses_softc_t *, int);
-static int ses_init_enc(ses_softc_t *);
-static int ses_get_encstat(ses_softc_t *, int);
-static int ses_set_encstat(ses_softc_t *, uint8_t, int);
-static int ses_get_objstat(ses_softc_t *, ses_objstat *, int);
-static int ses_set_objstat(ses_softc_t *, ses_objstat *, int);
-
-static int safte_softc_init(ses_softc_t *, int);
-static int safte_init_enc(ses_softc_t *);
-static int safte_get_encstat(ses_softc_t *, int);
-static int safte_set_encstat(ses_softc_t *, uint8_t, int);
-static int safte_get_objstat(ses_softc_t *, ses_objstat *, int);
-static int safte_set_objstat(ses_softc_t *, ses_objstat *, int);
-
-/*
- * Platform implementation defines/functions for SES internal kernel stuff
- */
-
-#define STRNCMP strncmp
-#define PRINTF printf
-#define SES_LOG ses_log
-#ifdef DEBUG
-#define SES_DLOG ses_log
-#else
-#define SES_DLOG if (0) ses_log
-#endif
-#define SES_VLOG if (bootverbose) ses_log
-#define SES_MALLOC(amt) malloc(amt, M_SCSISES, M_NOWAIT)
-#define SES_FREE(ptr, amt) free(ptr, M_SCSISES)
-#define MEMZERO bzero
-#define MEMCPY(dest, src, amt) bcopy(src, dest, amt)
-
-static int ses_runcmd(struct ses_softc *, char *, int, char *, int *);
-static void ses_log(struct ses_softc *, const char *, ...);
-
-/*
- * Gerenal FreeBSD kernel stuff.
- */
-
-
-#define ccb_state ppriv_field0
-#define ccb_bp ppriv_ptr1
-
-struct ses_softc {
- enctyp ses_type; /* type of enclosure */
- encvec ses_vec; /* vector to handlers */
- void * ses_private; /* per-type private data */
- encobj * ses_objmap; /* objects */
- uint32_t ses_nobjects; /* number of objects */
- ses_encstat ses_encstat; /* overall status */
- uint8_t ses_flags;
- union ccb ses_saved_ccb;
- struct cdev *ses_dev;
- struct cam_periph *periph;
-};
-#define SES_FLAG_INVALID 0x01
-#define SES_FLAG_OPEN 0x02
-#define SES_FLAG_INITIALIZED 0x04
-
-static d_open_t sesopen;
-static d_close_t sesclose;
-static d_ioctl_t sesioctl;
-static periph_init_t sesinit;
-static periph_ctor_t sesregister;
-static periph_oninv_t sesoninvalidate;
-static periph_dtor_t sescleanup;
-static periph_start_t sesstart;
-
-static void sesasync(void *, uint32_t, struct cam_path *, void *);
-static void sesdone(struct cam_periph *, union ccb *);
-static int seserror(union ccb *, uint32_t, uint32_t);
-
-static struct periph_driver sesdriver = {
- sesinit, "ses",
- TAILQ_HEAD_INITIALIZER(sesdriver.units), /* generation */ 0
-};
-
-PERIPHDRIVER_DECLARE(ses, sesdriver);
-
-static struct cdevsw ses_cdevsw = {
- .d_version = D_VERSION,
- .d_open = sesopen,
- .d_close = sesclose,
- .d_ioctl = sesioctl,
- .d_name = "ses",
- .d_flags = 0,
-};
-
-static void
-sesinit(void)
-{
- cam_status status;
-
- /*
- * Install a global async callback. This callback will
- * receive async callbacks like "new device found".
- */
- status = xpt_register_async(AC_FOUND_DEVICE, sesasync, NULL, NULL);
-
- if (status != CAM_REQ_CMP) {
- printf("ses: Failed to attach master async callback "
- "due to status 0x%x!\n", status);
- }
-}
-
-static void
-sesoninvalidate(struct cam_periph *periph)
-{
- struct ses_softc *softc;
-
- softc = (struct ses_softc *)periph->softc;
-
- /*
- * Unregister any async callbacks.
- */
- xpt_register_async(0, sesasync, periph, periph->path);
-
- softc->ses_flags |= SES_FLAG_INVALID;
-
- xpt_print(periph->path, "lost device\n");
-}
-
-static void
-sescleanup(struct cam_periph *periph)
-{
- struct ses_softc *softc;
-
- softc = (struct ses_softc *)periph->softc;
-
- xpt_print(periph->path, "removing device entry\n");
- cam_periph_unlock(periph);
- destroy_dev(softc->ses_dev);
- cam_periph_lock(periph);
- free(softc, M_SCSISES);
-}
-
-static void
-sesasync(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
-{
- struct cam_periph *periph;
-
- periph = (struct cam_periph *)callback_arg;
-
- switch(code) {
- case AC_FOUND_DEVICE:
- {
- cam_status status;
- struct ccb_getdev *cgd;
- int inq_len;
-
- cgd = (struct ccb_getdev *)arg;
- if (arg == NULL) {
- break;
- }
-
- if (cgd->protocol != PROTO_SCSI)
- break;
-
- inq_len = cgd->inq_data.additional_length + 4;
-
- /*
- * PROBLEM: WE NEED TO LOOK AT BYTES 48-53 TO SEE IF THIS IS
- * PROBLEM: IS A SAF-TE DEVICE.
- */
- switch (ses_type(&cgd->inq_data, inq_len)) {
- case SES_SES:
- case SES_SES_SCSI2:
- case SES_SES_PASSTHROUGH:
- case SES_SEN:
- case SES_SAFT:
- break;
- default:
- return;
- }
-
- status = cam_periph_alloc(sesregister, sesoninvalidate,
- sescleanup, sesstart, "ses", CAM_PERIPH_BIO,
- cgd->ccb_h.path, sesasync, AC_FOUND_DEVICE, cgd);
-
- if (status != CAM_REQ_CMP && status != CAM_REQ_INPROG) {
- printf("sesasync: Unable to probe new device due to "
- "status 0x%x\n", status);
- }
- break;
- }
- default:
- cam_periph_async(periph, code, path, arg);
- break;
- }
-}
-
-static cam_status
-sesregister(struct cam_periph *periph, void *arg)
-{
- struct ses_softc *softc;
- struct ccb_getdev *cgd;
- char *tname;
-
- cgd = (struct ccb_getdev *)arg;
- if (periph == NULL) {
- printf("sesregister: periph was NULL!!\n");
- return (CAM_REQ_CMP_ERR);
- }
-
- if (cgd == NULL) {
- printf("sesregister: no getdev CCB, can't register device\n");
- return (CAM_REQ_CMP_ERR);
- }
-
- softc = SES_MALLOC(sizeof (struct ses_softc));
- if (softc == NULL) {
- printf("sesregister: Unable to probe new device. "
- "Unable to allocate softc\n");
- return (CAM_REQ_CMP_ERR);
- }
- bzero(softc, sizeof (struct ses_softc));
- periph->softc = softc;
- softc->periph = periph;
-
- softc->ses_type = ses_type(&cgd->inq_data, sizeof (cgd->inq_data));
-
- switch (softc->ses_type) {
- case SES_SES:
- case SES_SES_SCSI2:
- case SES_SES_PASSTHROUGH:
- softc->ses_vec.softc_init = ses_softc_init;
- softc->ses_vec.init_enc = ses_init_enc;
- softc->ses_vec.get_encstat = ses_get_encstat;
- softc->ses_vec.set_encstat = ses_set_encstat;
- softc->ses_vec.get_objstat = ses_get_objstat;
- softc->ses_vec.set_objstat = ses_set_objstat;
- break;
- case SES_SAFT:
- softc->ses_vec.softc_init = safte_softc_init;
- softc->ses_vec.init_enc = safte_init_enc;
- softc->ses_vec.get_encstat = safte_get_encstat;
- softc->ses_vec.set_encstat = safte_set_encstat;
- softc->ses_vec.get_objstat = safte_get_objstat;
- softc->ses_vec.set_objstat = safte_set_objstat;
- break;
- case SES_SEN:
- break;
- case SES_NONE:
- default:
- free(softc, M_SCSISES);
- return (CAM_REQ_CMP_ERR);
- }
-
- cam_periph_unlock(periph);
- softc->ses_dev = make_dev(&ses_cdevsw, periph->unit_number,
- UID_ROOT, GID_OPERATOR, 0600, "%s%d",
- periph->periph_name, periph->unit_number);
- cam_periph_lock(periph);
- softc->ses_dev->si_drv1 = periph;
-
- /*
- * Add an async callback so that we get
- * notified if this device goes away.
- */
- xpt_register_async(AC_LOST_DEVICE, sesasync, periph, periph->path);
-
- switch (softc->ses_type) {
- default:
- case SES_NONE:
- tname = "No SES device";
- break;
- case SES_SES_SCSI2:
- tname = "SCSI-2 SES Device";
- break;
- case SES_SES:
- tname = "SCSI-3 SES Device";
- break;
- case SES_SES_PASSTHROUGH:
- tname = "SES Passthrough Device";
- break;
- case SES_SEN:
- tname = "UNISYS SEN Device (NOT HANDLED YET)";
- break;
- case SES_SAFT:
- tname = "SAF-TE Compliant Device";
- break;
- }
- xpt_announce_periph(periph, tname);
- return (CAM_REQ_CMP);
-}
-
-static int
-sesopen(struct cdev *dev, int flags, int fmt, struct thread *td)
-{
- struct cam_periph *periph;
- struct ses_softc *softc;
- int error = 0;
-
- periph = (struct cam_periph *)dev->si_drv1;
- if (periph == NULL) {
- return (ENXIO);
- }
-
- if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
- cam_periph_unlock(periph);
- return (ENXIO);
- }
-
- cam_periph_lock(periph);
-
- softc = (struct ses_softc *)periph->softc;
-
- if (softc->ses_flags & SES_FLAG_INVALID) {
- error = ENXIO;
- goto out;
- }
- if (softc->ses_flags & SES_FLAG_OPEN) {
- error = EBUSY;
- goto out;
- }
- if (softc->ses_vec.softc_init == NULL) {
- error = ENXIO;
- goto out;
- }
-
- softc->ses_flags |= SES_FLAG_OPEN;
- if ((softc->ses_flags & SES_FLAG_INITIALIZED) == 0) {
- error = (*softc->ses_vec.softc_init)(softc, 1);
- if (error)
- softc->ses_flags &= ~SES_FLAG_OPEN;
- else
- softc->ses_flags |= SES_FLAG_INITIALIZED;
- }
-
-out:
- cam_periph_unlock(periph);
- if (error) {
- cam_periph_release(periph);
- }
- return (error);
-}
-
-static int
-sesclose(struct cdev *dev, int flag, int fmt, struct thread *td)
-{
- struct cam_periph *periph;
- struct ses_softc *softc;
- int error;
-
- error = 0;
-
- periph = (struct cam_periph *)dev->si_drv1;
- if (periph == NULL)
- return (ENXIO);
-
- cam_periph_lock(periph);
-
- softc = (struct ses_softc *)periph->softc;
- softc->ses_flags &= ~SES_FLAG_OPEN;
-
- cam_periph_unlock(periph);
- cam_periph_release(periph);
-
- return (0);
-}
-
-static void
-sesstart(struct cam_periph *p, union ccb *sccb)
-{
- if (p->immediate_priority <= p->pinfo.priority) {
- SLIST_INSERT_HEAD(&p->ccb_list, &sccb->ccb_h, periph_links.sle);
- p->immediate_priority = CAM_PRIORITY_NONE;
- wakeup(&p->ccb_list);
- }
-}
-
-static void
-sesdone(struct cam_periph *periph, union ccb *dccb)
-{
- wakeup(&dccb->ccb_h.cbfcnp);
-}
-
-static int
-seserror(union ccb *ccb, uint32_t cflags, uint32_t sflags)
-{
- struct ses_softc *softc;
- struct cam_periph *periph;
-
- periph = xpt_path_periph(ccb->ccb_h.path);
- softc = (struct ses_softc *)periph->softc;
-
- return (cam_periph_error(ccb, cflags, sflags, &softc->ses_saved_ccb));
-}
-
-static int
-sesioctl(struct cdev *dev, u_long cmd, caddr_t arg_addr, int flag, struct thread *td)
-{
- struct cam_periph *periph;
- ses_encstat tmp;
- ses_objstat objs;
- ses_object *uobj;
- struct ses_softc *ssc;
- void *addr;
- int error, i;
-
-
- if (arg_addr)
- addr = *((caddr_t *) arg_addr);
- else
- addr = NULL;
-
- periph = (struct cam_periph *)dev->si_drv1;
- if (periph == NULL)
- return (ENXIO);
-
- CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering sesioctl\n"));
-
- cam_periph_lock(periph);
- ssc = (struct ses_softc *)periph->softc;
-
- /*
- * Now check to see whether we're initialized or not.
- * This actually should never fail as we're not supposed
- * to get past ses_open w/o successfully initializing
- * things.
- */
- if ((ssc->ses_flags & SES_FLAG_INITIALIZED) == 0) {
- cam_periph_unlock(periph);
- return (ENXIO);
- }
- cam_periph_unlock(periph);
-
- error = 0;
-
- CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
- ("trying to do ioctl %#lx\n", cmd));
-
- /*
- * If this command can change the device's state,
- * we must have the device open for writing.
- *
- * For commands that get information about the
- * device- we don't need to lock the peripheral
- * if we aren't running a command. The number
- * of objects and the contents will stay stable
- * after the first open that does initialization.
- * The periph also can't go away while a user
- * process has it open.
- */
- switch (cmd) {
- case SESIOC_GETNOBJ:
- case SESIOC_GETOBJMAP:
- case SESIOC_GETENCSTAT:
- case SESIOC_GETOBJSTAT:
- break;
- default:
- if ((flag & FWRITE) == 0) {
- return (EBADF);
- }
- }
-
- switch (cmd) {
- case SESIOC_GETNOBJ:
- error = copyout(&ssc->ses_nobjects, addr,
- sizeof (ssc->ses_nobjects));
- break;
-
- case SESIOC_GETOBJMAP:
- for (uobj = addr, i = 0; i != ssc->ses_nobjects; i++) {
- ses_object kobj;
- kobj.obj_id = i;
- kobj.subencid = ssc->ses_objmap[i].subenclosure;
- kobj.object_type = ssc->ses_objmap[i].enctype;
- error = copyout(&kobj, &uobj[i], sizeof (ses_object));
- if (error) {
- break;
- }
- }
- break;
-
- case SESIOC_GETENCSTAT:
- cam_periph_lock(periph);
- error = (*ssc->ses_vec.get_encstat)(ssc, 1);
- if (error) {
- cam_periph_unlock(periph);
- break;
- }
- tmp = ssc->ses_encstat & ~ENCI_SVALID;
- cam_periph_unlock(periph);
- error = copyout(&tmp, addr, sizeof (ses_encstat));
- ssc->ses_encstat = tmp;
- break;
-
- case SESIOC_SETENCSTAT:
- error = copyin(addr, &tmp, sizeof (ses_encstat));
- if (error)
- break;
- cam_periph_lock(periph);
- error = (*ssc->ses_vec.set_encstat)(ssc, tmp, 1);
- cam_periph_unlock(periph);
- break;
-
- case SESIOC_GETOBJSTAT:
- error = copyin(addr, &objs, sizeof (ses_objstat));
- if (error)
- break;
- if (objs.obj_id >= ssc->ses_nobjects) {
- error = EINVAL;
- break;
- }
- cam_periph_lock(periph);
- error = (*ssc->ses_vec.get_objstat)(ssc, &objs, 1);
- cam_periph_unlock(periph);
- if (error)
- break;
- error = copyout(&objs, addr, sizeof (ses_objstat));
- /*
- * Always (for now) invalidate entry.
- */
- ssc->ses_objmap[objs.obj_id].svalid = 0;
- break;
-
- case SESIOC_SETOBJSTAT:
- error = copyin(addr, &objs, sizeof (ses_objstat));
- if (error)
- break;
-
- if (objs.obj_id >= ssc->ses_nobjects) {
- error = EINVAL;
- break;
- }
- cam_periph_lock(periph);
- error = (*ssc->ses_vec.set_objstat)(ssc, &objs, 1);
- cam_periph_unlock(periph);
-
- /*
- * Always (for now) invalidate entry.
- */
- ssc->ses_objmap[objs.obj_id].svalid = 0;
- break;
-
- case SESIOC_INIT:
-
- cam_periph_lock(periph);
- error = (*ssc->ses_vec.init_enc)(ssc);
- cam_periph_unlock(periph);
- break;
-
- default:
- cam_periph_lock(periph);
- error = cam_periph_ioctl(periph, cmd, arg_addr, seserror);
- cam_periph_unlock(periph);
- break;
- }
- return (error);
-}
-
-#define SES_CFLAGS CAM_RETRY_SELTO
-#define SES_FLAGS SF_NO_PRINT | SF_RETRY_UA
-static int
-ses_runcmd(struct ses_softc *ssc, char *cdb, int cdbl, char *dptr, int *dlenp)
-{
- int error, dlen;
- ccb_flags ddf;
- union ccb *ccb;
-
- if (dptr) {
- if ((dlen = *dlenp) < 0) {
- dlen = -dlen;
- ddf = CAM_DIR_OUT;
- } else {
- ddf = CAM_DIR_IN;
- }
- } else {
- dlen = 0;
- ddf = CAM_DIR_NONE;
- }
-
- if (cdbl > IOCDBLEN) {
- cdbl = IOCDBLEN;
- }
-
- ccb = cam_periph_getccb(ssc->periph, 1);
- cam_fill_csio(&ccb->csio, 0, sesdone, ddf, MSG_SIMPLE_Q_TAG, dptr,
- dlen, sizeof (struct scsi_sense_data), cdbl, 60 * 1000);
- bcopy(cdb, ccb->csio.cdb_io.cdb_bytes, cdbl);
-
- error = cam_periph_runccb(ccb, seserror, SES_CFLAGS, SES_FLAGS, NULL);
- if (error) {
- if (dptr) {
- *dlenp = dlen;
- }
- } else {
- if (dptr) {
- *dlenp = ccb->csio.resid;
- }
- }
- xpt_release_ccb(ccb);
- return (error);
-}
-
-static void
-ses_log(struct ses_softc *ssc, const char *fmt, ...)
-{
- va_list ap;
-
- printf("%s%d: ", ssc->periph->periph_name, ssc->periph->unit_number);
- va_start(ap, fmt);
- vprintf(fmt, ap);
- va_end(ap);
-}
-
-/*
- * The code after this point runs on many platforms,
- * so forgive the slightly awkward and nonconforming
- * appearance.
- */
-
-/*
- * Is this a device that supports enclosure services?
- *
- * It's a pretty simple ruleset- if it is device type 0x0D (13), it's
- * an SES device. If it happens to be an old UNISYS SEN device, we can
- * handle that too.
- */
-
-#define SAFTE_START 44
-#define SAFTE_END 50
-#define SAFTE_LEN SAFTE_END-SAFTE_START
-
-static enctyp
-ses_type(void *buf, int buflen)
-{
- unsigned char *iqd = buf;
-
- if (buflen < 8+SEN_ID_LEN)
- return (SES_NONE);
-
- if ((iqd[0] & 0x1f) == T_ENCLOSURE) {
- if (STRNCMP(&iqd[8], SEN_ID, SEN_ID_LEN) == 0) {
- return (SES_SEN);
- } else if ((iqd[2] & 0x7) > 2) {
- return (SES_SES);
- } else {
- return (SES_SES_SCSI2);
- }
- return (SES_NONE);
- }
-
-#ifdef SES_ENABLE_PASSTHROUGH
- if ((iqd[6] & 0x40) && (iqd[2] & 0x7) >= 2) {
- /*
- * PassThrough Device.
- */
- return (SES_SES_PASSTHROUGH);
- }
-#endif
-
- /*
- * The comparison is short for a reason-
- * some vendors were chopping it short.
- */
-
- if (buflen < SAFTE_END - 2) {
- return (SES_NONE);
- }
-
- if (STRNCMP((char *)&iqd[SAFTE_START], "SAF-TE", SAFTE_LEN - 2) == 0) {
- return (SES_SAFT);
- }
- return (SES_NONE);
-}
-
-/*
- * SES Native Type Device Support
- */
-
-/*
- * SES Diagnostic Page Codes
- */
-
-typedef enum {
- SesConfigPage = 0x1,
- SesControlPage,
-#define SesStatusPage SesControlPage
- SesHelpTxt,
- SesStringOut,
-#define SesStringIn SesStringOut
- SesThresholdOut,
-#define SesThresholdIn SesThresholdOut
- SesArrayControl,
-#define SesArrayStatus SesArrayControl
- SesElementDescriptor,
- SesShortStatus
-} SesDiagPageCodes;
-
-/*
- * minimal amounts
- */
-
-/*
- * Minimum amount of data, starting from byte 0, to have
- * the config header.
- */
-#define SES_CFGHDR_MINLEN 12
-
-/*
- * Minimum amount of data, starting from byte 0, to have
- * the config header and one enclosure header.
- */
-#define SES_ENCHDR_MINLEN 48
-
-/*
- * Take this value, subtract it from VEnclen and you know
- * the length of the vendor unique bytes.
- */
-#define SES_ENCHDR_VMIN 36
-
-/*
- * SES Data Structures
- */
-
-typedef struct {
- uint32_t GenCode; /* Generation Code */
- uint8_t Nsubenc; /* Number of Subenclosures */
-} SesCfgHdr;
-
-typedef struct {
- uint8_t Subencid; /* SubEnclosure Identifier */
- uint8_t Ntypes; /* # of supported types */
- uint8_t VEnclen; /* Enclosure Descriptor Length */
-} SesEncHdr;
-
-typedef struct {
- uint8_t encWWN[8]; /* XXX- Not Right Yet */
- uint8_t encVid[8];
- uint8_t encPid[16];
- uint8_t encRev[4];
- uint8_t encVen[1];
-} SesEncDesc;
-
-typedef struct {
- uint8_t enc_type; /* type of element */
- uint8_t enc_maxelt; /* maximum supported */
- uint8_t enc_subenc; /* in SubEnc # N */
- uint8_t enc_tlen; /* Type Descriptor Text Length */
-} SesThdr;
-
-typedef struct {
- uint8_t comstatus;
- uint8_t comstat[3];
-} SesComStat;
-
-struct typidx {
- int ses_tidx;
- int ses_oidx;
-};
-
-struct sscfg {
- uint8_t ses_ntypes; /* total number of types supported */
-
- /*
- * We need to keep a type index as well as an
- * object index for each object in an enclosure.
- */
- struct typidx *ses_typidx;
-
- /*
- * We also need to keep track of the number of elements
- * per type of element. This is needed later so that we
- * can find precisely in the returned status data the
- * status for the Nth element of the Kth type.
- */
- uint8_t * ses_eltmap;
-};
-
-
-/*
- * (de)canonicalization defines
- */
-#define sbyte(x, byte) ((((uint32_t)(x)) >> (byte * 8)) & 0xff)
-#define sbit(x, bit) (((uint32_t)(x)) << bit)
-#define sset8(outp, idx, sval) (((uint8_t *)(outp))[idx++]) = sbyte(sval, 0)
-
-#define sset16(outp, idx, sval) \
- (((uint8_t *)(outp))[idx++]) = sbyte(sval, 1), \
- (((uint8_t *)(outp))[idx++]) = sbyte(sval, 0)
-
-
-#define sset24(outp, idx, sval) \
- (((uint8_t *)(outp))[idx++]) = sbyte(sval, 2), \
- (((uint8_t *)(outp))[idx++]) = sbyte(sval, 1), \
- (((uint8_t *)(outp))[idx++]) = sbyte(sval, 0)
-
-
-#define sset32(outp, idx, sval) \
- (((uint8_t *)(outp))[idx++]) = sbyte(sval, 3), \
- (((uint8_t *)(outp))[idx++]) = sbyte(sval, 2), \
- (((uint8_t *)(outp))[idx++]) = sbyte(sval, 1), \
- (((uint8_t *)(outp))[idx++]) = sbyte(sval, 0)
-
-#define gbyte(x, byte) ((((uint32_t)(x)) & 0xff) << (byte * 8))
-#define gbit(lv, in, idx, shft, mask) lv = ((in[idx] >> shft) & mask)
-#define sget8(inp, idx, lval) lval = (((uint8_t *)(inp))[idx++])
-#define gget8(inp, idx, lval) lval = (((uint8_t *)(inp))[idx])
-
-#define sget16(inp, idx, lval) \
- lval = gbyte((((uint8_t *)(inp))[idx]), 1) | \
- (((uint8_t *)(inp))[idx+1]), idx += 2
-
-#define gget16(inp, idx, lval) \
- lval = gbyte((((uint8_t *)(inp))[idx]), 1) | \
- (((uint8_t *)(inp))[idx+1])
-
-#define sget24(inp, idx, lval) \
- lval = gbyte((((uint8_t *)(inp))[idx]), 2) | \
- gbyte((((uint8_t *)(inp))[idx+1]), 1) | \
- (((uint8_t *)(inp))[idx+2]), idx += 3
-
-#define gget24(inp, idx, lval) \
- lval = gbyte((((uint8_t *)(inp))[idx]), 2) | \
- gbyte((((uint8_t *)(inp))[idx+1]), 1) | \
- (((uint8_t *)(inp))[idx+2])
-
-#define sget32(inp, idx, lval) \
- lval = gbyte((((uint8_t *)(inp))[idx]), 3) | \
- gbyte((((uint8_t *)(inp))[idx+1]), 2) | \
- gbyte((((uint8_t *)(inp))[idx+2]), 1) | \
- (((uint8_t *)(inp))[idx+3]), idx += 4
-
-#define gget32(inp, idx, lval) \
- lval = gbyte((((uint8_t *)(inp))[idx]), 3) | \
- gbyte((((uint8_t *)(inp))[idx+1]), 2) | \
- gbyte((((uint8_t *)(inp))[idx+2]), 1) | \
- (((uint8_t *)(inp))[idx+3])
-
-#define SCSZ 0x2000
-#define CFLEN (256 + SES_ENCHDR_MINLEN)
-
-/*
- * Routines specific && private to SES only
- */
-
-static int ses_getconfig(ses_softc_t *);
-static int ses_getputstat(ses_softc_t *, int, SesComStat *, int, int);
-static int ses_cfghdr(uint8_t *, int, SesCfgHdr *);
-static int ses_enchdr(uint8_t *, int, uint8_t, SesEncHdr *);
-static int ses_encdesc(uint8_t *, int, uint8_t, SesEncDesc *);
-static int ses_getthdr(uint8_t *, int, int, SesThdr *);
-static int ses_decode(char *, int, uint8_t *, int, int, SesComStat *);
-static int ses_encode(char *, int, uint8_t *, int, int, SesComStat *);
-
-static int
-ses_softc_init(ses_softc_t *ssc, int doinit)
-{
- if (doinit == 0) {
- struct sscfg *cc;
- if (ssc->ses_nobjects) {
- SES_FREE(ssc->ses_objmap,
- ssc->ses_nobjects * sizeof (encobj));
- ssc->ses_objmap = NULL;
- }
- if ((cc = ssc->ses_private) != NULL) {
- if (cc->ses_eltmap && cc->ses_ntypes) {
- SES_FREE(cc->ses_eltmap, cc->ses_ntypes);
- cc->ses_eltmap = NULL;
- cc->ses_ntypes = 0;
- }
- if (cc->ses_typidx && ssc->ses_nobjects) {
- SES_FREE(cc->ses_typidx,
- ssc->ses_nobjects * sizeof (struct typidx));
- cc->ses_typidx = NULL;
- }
- SES_FREE(cc, sizeof (struct sscfg));
- ssc->ses_private = NULL;
- }
- ssc->ses_nobjects = 0;
- return (0);
- }
- if (ssc->ses_private == NULL) {
- ssc->ses_private = SES_MALLOC(sizeof (struct sscfg));
- }
- if (ssc->ses_private == NULL) {
- return (ENOMEM);
- }
- ssc->ses_nobjects = 0;
- ssc->ses_encstat = 0;
- return (ses_getconfig(ssc));
-}
-
-static int
-ses_init_enc(ses_softc_t *ssc)
-{
- return (0);
-}
-
-static int
-ses_get_encstat(ses_softc_t *ssc, int slpflag)
-{
- SesComStat ComStat;
- int status;
-
- if ((status = ses_getputstat(ssc, -1, &ComStat, slpflag, 1)) != 0) {
- return (status);
- }
- ssc->ses_encstat = ComStat.comstatus | ENCI_SVALID;
- return (0);
-}
-
-static int
-ses_set_encstat(ses_softc_t *ssc, uint8_t encstat, int slpflag)
-{
- SesComStat ComStat;
- int status;
-
- ComStat.comstatus = encstat & 0xf;
- if ((status = ses_getputstat(ssc, -1, &ComStat, slpflag, 0)) != 0) {
- return (status);
- }
- ssc->ses_encstat = encstat & 0xf; /* note no SVALID set */
- return (0);
-}
-
-static int
-ses_get_objstat(ses_softc_t *ssc, ses_objstat *obp, int slpflag)
-{
- int i = (int)obp->obj_id;
-
- if (ssc->ses_objmap[i].svalid == 0) {
- SesComStat ComStat;
- int err = ses_getputstat(ssc, i, &ComStat, slpflag, 1);
- if (err)
- return (err);
- ssc->ses_objmap[i].encstat[0] = ComStat.comstatus;
- ssc->ses_objmap[i].encstat[1] = ComStat.comstat[0];
- ssc->ses_objmap[i].encstat[2] = ComStat.comstat[1];
- ssc->ses_objmap[i].encstat[3] = ComStat.comstat[2];
- ssc->ses_objmap[i].svalid = 1;
- }
- obp->cstat[0] = ssc->ses_objmap[i].encstat[0];
- obp->cstat[1] = ssc->ses_objmap[i].encstat[1];
- obp->cstat[2] = ssc->ses_objmap[i].encstat[2];
- obp->cstat[3] = ssc->ses_objmap[i].encstat[3];
- return (0);
-}
-
-static int
-ses_set_objstat(ses_softc_t *ssc, ses_objstat *obp, int slpflag)
-{
- SesComStat ComStat;
- int err;
- /*
- * If this is clear, we don't do diddly.
- */
- if ((obp->cstat[0] & SESCTL_CSEL) == 0) {
- return (0);
- }
- ComStat.comstatus = obp->cstat[0];
- ComStat.comstat[0] = obp->cstat[1];
- ComStat.comstat[1] = obp->cstat[2];
- ComStat.comstat[2] = obp->cstat[3];
- err = ses_getputstat(ssc, (int)obp->obj_id, &ComStat, slpflag, 0);
- ssc->ses_objmap[(int)obp->obj_id].svalid = 0;
- return (err);
-}
-
-static int
-ses_getconfig(ses_softc_t *ssc)
-{
- struct sscfg *cc;
- SesCfgHdr cf;
- SesEncHdr hd;
- SesEncDesc *cdp;
- SesThdr thdr;
- int err, amt, i, nobj, ntype, maxima;
- char storage[CFLEN], *sdata;
- static char cdb[6] = {
- RECEIVE_DIAGNOSTIC, 0x1, SesConfigPage, SCSZ >> 8, SCSZ & 0xff, 0
- };
-
- cc = ssc->ses_private;
- if (cc == NULL) {
- return (ENXIO);
- }
-
- sdata = SES_MALLOC(SCSZ);
- if (sdata == NULL)
- return (ENOMEM);
-
- amt = SCSZ;
- err = ses_runcmd(ssc, cdb, 6, sdata, &amt);
- if (err) {
- SES_FREE(sdata, SCSZ);
- return (err);
- }
- amt = SCSZ - amt;
-
- if (ses_cfghdr((uint8_t *) sdata, amt, &cf)) {
- SES_LOG(ssc, "Unable to parse SES Config Header\n");
- SES_FREE(sdata, SCSZ);
- return (EIO);
- }
- if (amt < SES_ENCHDR_MINLEN) {
- SES_LOG(ssc, "runt enclosure length (%d)\n", amt);
- SES_FREE(sdata, SCSZ);
- return (EIO);
- }
-
- SES_VLOG(ssc, "GenCode %x %d Subenclosures\n", cf.GenCode, cf.Nsubenc);
-
- /*
- * Now waltz through all the subenclosures toting up the
- * number of types available in each. For this, we only
- * really need the enclosure header. However, we get the
- * enclosure descriptor for debug purposes, as well
- * as self-consistency checking purposes.
- */
-
- maxima = cf.Nsubenc + 1;
- cdp = (SesEncDesc *) storage;
- for (ntype = i = 0; i < maxima; i++) {
- MEMZERO((caddr_t)cdp, sizeof (*cdp));
- if (ses_enchdr((uint8_t *) sdata, amt, i, &hd)) {
- SES_LOG(ssc, "Cannot Extract Enclosure Header %d\n", i);
- SES_FREE(sdata, SCSZ);
- return (EIO);
- }
- SES_VLOG(ssc, " SubEnclosure ID %d, %d Types With this ID, En"
- "closure Length %d\n", hd.Subencid, hd.Ntypes, hd.VEnclen);
-
- if (ses_encdesc((uint8_t *)sdata, amt, i, cdp)) {
- SES_LOG(ssc, "Can't get Enclosure Descriptor %d\n", i);
- SES_FREE(sdata, SCSZ);
- return (EIO);
- }
- SES_VLOG(ssc, " WWN: %02x%02x%02x%02x%02x%02x%02x%02x\n",
- cdp->encWWN[0], cdp->encWWN[1], cdp->encWWN[2],
- cdp->encWWN[3], cdp->encWWN[4], cdp->encWWN[5],
- cdp->encWWN[6], cdp->encWWN[7]);
- ntype += hd.Ntypes;
- }
-
- /*
- * Now waltz through all the types that are available, getting
- * the type header so we can start adding up the number of
- * objects available.
- */
- for (nobj = i = 0; i < ntype; i++) {
- if (ses_getthdr((uint8_t *)sdata, amt, i, &thdr)) {
- SES_LOG(ssc, "Can't get Enclosure Type Header %d\n", i);
- SES_FREE(sdata, SCSZ);
- return (EIO);
- }
- SES_LOG(ssc, " Type Desc[%d]: Type 0x%x, MaxElt %d, In Subenc "
- "%d, Text Length %d\n", i, thdr.enc_type, thdr.enc_maxelt,
- thdr.enc_subenc, thdr.enc_tlen);
- nobj += thdr.enc_maxelt;
- }
-
-
- /*
- * Now allocate the object array and type map.
- */
-
- ssc->ses_objmap = SES_MALLOC(nobj * sizeof (encobj));
- cc->ses_typidx = SES_MALLOC(nobj * sizeof (struct typidx));
- cc->ses_eltmap = SES_MALLOC(ntype);
-
- if (ssc->ses_objmap == NULL || cc->ses_typidx == NULL ||
- cc->ses_eltmap == NULL) {
- if (ssc->ses_objmap) {
- SES_FREE(ssc->ses_objmap, (nobj * sizeof (encobj)));
- ssc->ses_objmap = NULL;
- }
- if (cc->ses_typidx) {
- SES_FREE(cc->ses_typidx,
- (nobj * sizeof (struct typidx)));
- cc->ses_typidx = NULL;
- }
- if (cc->ses_eltmap) {
- SES_FREE(cc->ses_eltmap, ntype);
- cc->ses_eltmap = NULL;
- }
- SES_FREE(sdata, SCSZ);
- return (ENOMEM);
- }
- MEMZERO(ssc->ses_objmap, nobj * sizeof (encobj));
- MEMZERO(cc->ses_typidx, nobj * sizeof (struct typidx));
- MEMZERO(cc->ses_eltmap, ntype);
- cc->ses_ntypes = (uint8_t) ntype;
- ssc->ses_nobjects = nobj;
-
- /*
- * Now waltz through the # of types again to fill in the types
- * (and subenclosure ids) of the allocated objects.
- */
- nobj = 0;
- for (i = 0; i < ntype; i++) {
- int j;
- if (ses_getthdr((uint8_t *)sdata, amt, i, &thdr)) {
- continue;
- }
- cc->ses_eltmap[i] = thdr.enc_maxelt;
- for (j = 0; j < thdr.enc_maxelt; j++) {
- cc->ses_typidx[nobj].ses_tidx = i;
- cc->ses_typidx[nobj].ses_oidx = j;
- ssc->ses_objmap[nobj].subenclosure = thdr.enc_subenc;
- ssc->ses_objmap[nobj++].enctype = thdr.enc_type;
- }
- }
- SES_FREE(sdata, SCSZ);
- return (0);
-}
-
-static int
-ses_getputstat(ses_softc_t *ssc, int objid, SesComStat *sp, int slp, int in)
-{
- struct sscfg *cc;
- int err, amt, bufsiz, tidx, oidx;
- char cdb[6], *sdata;
-
- cc = ssc->ses_private;
- if (cc == NULL) {
- return (ENXIO);
- }
-
- /*
- * If we're just getting overall enclosure status,
- * we only need 2 bytes of data storage.
- *
- * If we're getting anything else, we know how much
- * storage we need by noting that starting at offset
- * 8 in returned data, all object status bytes are 4
- * bytes long, and are stored in chunks of types(M)
- * and nth+1 instances of type M.
- */
- if (objid == -1) {
- bufsiz = 2;
- } else {
- bufsiz = (ssc->ses_nobjects * 4) + (cc->ses_ntypes * 4) + 8;
- }
- sdata = SES_MALLOC(bufsiz);
- if (sdata == NULL)
- return (ENOMEM);
-
- cdb[0] = RECEIVE_DIAGNOSTIC;
- cdb[1] = 1;
- cdb[2] = SesStatusPage;
- cdb[3] = bufsiz >> 8;
- cdb[4] = bufsiz & 0xff;
- cdb[5] = 0;
- amt = bufsiz;
- err = ses_runcmd(ssc, cdb, 6, sdata, &amt);
- if (err) {
- SES_FREE(sdata, bufsiz);
- return (err);
- }
- amt = bufsiz - amt;
-
- if (objid == -1) {
- tidx = -1;
- oidx = -1;
- } else {
- tidx = cc->ses_typidx[objid].ses_tidx;
- oidx = cc->ses_typidx[objid].ses_oidx;
- }
- if (in) {
- if (ses_decode(sdata, amt, cc->ses_eltmap, tidx, oidx, sp)) {
- err = ENODEV;
- }
- } else {
- if (ses_encode(sdata, amt, cc->ses_eltmap, tidx, oidx, sp)) {
- err = ENODEV;
- } else {
- cdb[0] = SEND_DIAGNOSTIC;
- cdb[1] = 0x10;
- cdb[2] = 0;
- cdb[3] = bufsiz >> 8;
- cdb[4] = bufsiz & 0xff;
- cdb[5] = 0;
- amt = -bufsiz;
- err = ses_runcmd(ssc, cdb, 6, sdata, &amt);
- }
- }
- SES_FREE(sdata, bufsiz);
- return (0);
-}
-
-
-/*
- * Routines to parse returned SES data structures.
- * Architecture and compiler independent.
- */
-
-static int
-ses_cfghdr(uint8_t *buffer, int buflen, SesCfgHdr *cfp)
-{
- if (buflen < SES_CFGHDR_MINLEN) {
- return (-1);
- }
- gget8(buffer, 1, cfp->Nsubenc);
- gget32(buffer, 4, cfp->GenCode);
- return (0);
-}
-
-static int
-ses_enchdr(uint8_t *buffer, int amt, uint8_t SubEncId, SesEncHdr *chp)
-{
- int s, off = 8;
- for (s = 0; s < SubEncId; s++) {
- if (off + 3 > amt)
- return (-1);
- off += buffer[off+3] + 4;
- }
- if (off + 3 > amt) {
- return (-1);
- }
- gget8(buffer, off+1, chp->Subencid);
- gget8(buffer, off+2, chp->Ntypes);
- gget8(buffer, off+3, chp->VEnclen);
- return (0);
-}
-
-static int
-ses_encdesc(uint8_t *buffer, int amt, uint8_t SubEncId, SesEncDesc *cdp)
-{
- int s, e, enclen, off = 8;
- for (s = 0; s < SubEncId; s++) {
- if (off + 3 > amt)
- return (-1);
- off += buffer[off+3] + 4;
- }
- if (off + 3 > amt) {
- return (-1);
- }
- gget8(buffer, off+3, enclen);
- off += 4;
- if (off >= amt)
- return (-1);
-
- e = off + enclen;
- if (e > amt) {
- e = amt;
- }
- MEMCPY(cdp, &buffer[off], e - off);
- return (0);
-}
-
-static int
-ses_getthdr(uint8_t *buffer, int amt, int nth, SesThdr *thp)
-{
- int s, off = 8;
-
- if (amt < SES_CFGHDR_MINLEN) {
- return (-1);
- }
- for (s = 0; s < buffer[1]; s++) {
- if (off + 3 > amt)
- return (-1);
- off += buffer[off+3] + 4;
- }
- if (off + 3 > amt) {
- return (-1);
- }
- off += buffer[off+3] + 4 + (nth * 4);
- if (amt < (off + 4))
- return (-1);
-
- gget8(buffer, off++, thp->enc_type);
- gget8(buffer, off++, thp->enc_maxelt);
- gget8(buffer, off++, thp->enc_subenc);
- gget8(buffer, off, thp->enc_tlen);
- return (0);
-}
-
-/*
- * This function needs a little explanation.
- *
- * The arguments are:
- *
- *
- * char *b, int amt
- *
- * These describes the raw input SES status data and length.
- *
- * uint8_t *ep
- *
- * This is a map of the number of types for each element type
- * in the enclosure.
- *
- * int elt
- *
- * This is the element type being sought. If elt is -1,
- * then overall enclosure status is being sought.
- *
- * int elm
- *
- * This is the ordinal Mth element of type elt being sought.
- *
- * SesComStat *sp
- *
- * This is the output area to store the status for
- * the Mth element of type Elt.
- */
-
-static int
-ses_decode(char *b, int amt, uint8_t *ep, int elt, int elm, SesComStat *sp)
-{
- int idx, i;
-
- /*
- * If it's overall enclosure status being sought, get that.
- * We need at least 2 bytes of status data to get that.
- */
- if (elt == -1) {
- if (amt < 2)
- return (-1);
- gget8(b, 1, sp->comstatus);
- sp->comstat[0] = 0;
- sp->comstat[1] = 0;
- sp->comstat[2] = 0;
- return (0);
- }
-
- /*
- * Check to make sure that the Mth element is legal for type Elt.
- */
-
- if (elm >= ep[elt])
- return (-1);
-
- /*
- * Starting at offset 8, start skipping over the storage
- * for the element types we're not interested in.
- */
- for (idx = 8, i = 0; i < elt; i++) {
- idx += ((ep[i] + 1) * 4);
- }
-
- /*
- * Skip over Overall status for this element type.
- */
- idx += 4;
-
- /*
- * And skip to the index for the Mth element that we're going for.
- */
- idx += (4 * elm);
-
- /*
- * Make sure we haven't overflowed the buffer.
- */
- if (idx+4 > amt)
- return (-1);
-
- /*
- * Retrieve the status.
- */
- gget8(b, idx++, sp->comstatus);
- gget8(b, idx++, sp->comstat[0]);
- gget8(b, idx++, sp->comstat[1]);
- gget8(b, idx++, sp->comstat[2]);
-#if 0
- PRINTF("Get Elt 0x%x Elm 0x%x (idx %d)\n", elt, elm, idx-4);
-#endif
- return (0);
-}
-
-/*
- * This is the mirror function to ses_decode, but we set the 'select'
- * bit for the object which we're interested in. All other objects,
- * after a status fetch, should have that bit off. Hmm. It'd be easy
- * enough to ensure this, so we will.
- */
-
-static int
-ses_encode(char *b, int amt, uint8_t *ep, int elt, int elm, SesComStat *sp)
-{
- int idx, i;
-
- /*
- * If it's overall enclosure status being sought, get that.
- * We need at least 2 bytes of status data to get that.
- */
- if (elt == -1) {
- if (amt < 2)
- return (-1);
- i = 0;
- sset8(b, i, 0);
- sset8(b, i, sp->comstatus & 0xf);
-#if 0
- PRINTF("set EncStat %x\n", sp->comstatus);
-#endif
- return (0);
- }
-
- /*
- * Check to make sure that the Mth element is legal for type Elt.
- */
-
- if (elm >= ep[elt])
- return (-1);
-
- /*
- * Starting at offset 8, start skipping over the storage
- * for the element types we're not interested in.
- */
- for (idx = 8, i = 0; i < elt; i++) {
- idx += ((ep[i] + 1) * 4);
- }
-
- /*
- * Skip over Overall status for this element type.
- */
- idx += 4;
-
- /*
- * And skip to the index for the Mth element that we're going for.
- */
- idx += (4 * elm);
-
- /*
- * Make sure we haven't overflowed the buffer.
- */
- if (idx+4 > amt)
- return (-1);
-
- /*
- * Set the status.
- */
- sset8(b, idx, sp->comstatus);
- sset8(b, idx, sp->comstat[0]);
- sset8(b, idx, sp->comstat[1]);
- sset8(b, idx, sp->comstat[2]);
- idx -= 4;
-
-#if 0
- PRINTF("Set Elt 0x%x Elm 0x%x (idx %d) with %x %x %x %x\n",
- elt, elm, idx, sp->comstatus, sp->comstat[0],
- sp->comstat[1], sp->comstat[2]);
-#endif
-
- /*
- * Now make sure all other 'Select' bits are off.
- */
- for (i = 8; i < amt; i += 4) {
- if (i != idx)
- b[i] &= ~0x80;
- }
- /*
- * And make sure the INVOP bit is clear.
- */
- b[2] &= ~0x10;
-
- return (0);
-}
-
-/*
- * SAF-TE Type Device Emulation
- */
-
-static int safte_getconfig(ses_softc_t *);
-static int safte_rdstat(ses_softc_t *, int);
-static int set_objstat_sel(ses_softc_t *, ses_objstat *, int);
-static int wrbuf16(ses_softc_t *, uint8_t, uint8_t, uint8_t, uint8_t, int);
-static void wrslot_stat(ses_softc_t *, int);
-static int perf_slotop(ses_softc_t *, uint8_t, uint8_t, int);
-
-#define ALL_ENC_STAT (SES_ENCSTAT_CRITICAL | SES_ENCSTAT_UNRECOV | \
- SES_ENCSTAT_NONCRITICAL | SES_ENCSTAT_INFO)
-/*
- * SAF-TE specific defines- Mandatory ones only...
- */
-
-/*
- * READ BUFFER ('get' commands) IDs- placed in offset 2 of cdb
- */
-#define SAFTE_RD_RDCFG 0x00 /* read enclosure configuration */
-#define SAFTE_RD_RDESTS 0x01 /* read enclosure status */
-#define SAFTE_RD_RDDSTS 0x04 /* read drive slot status */
-
-/*
- * WRITE BUFFER ('set' commands) IDs- placed in offset 0 of databuf
- */
-#define SAFTE_WT_DSTAT 0x10 /* write device slot status */
-#define SAFTE_WT_SLTOP 0x12 /* perform slot operation */
-#define SAFTE_WT_FANSPD 0x13 /* set fan speed */
-#define SAFTE_WT_ACTPWS 0x14 /* turn on/off power supply */
-#define SAFTE_WT_GLOBAL 0x15 /* send global command */
-
-
-#define SAFT_SCRATCH 64
-#define NPSEUDO_THERM 16
-#define NPSEUDO_ALARM 1
-struct scfg {
- /*
- * Cached Configuration
- */
- uint8_t Nfans; /* Number of Fans */
- uint8_t Npwr; /* Number of Power Supplies */
- uint8_t Nslots; /* Number of Device Slots */
- uint8_t DoorLock; /* Door Lock Installed */
- uint8_t Ntherm; /* Number of Temperature Sensors */
- uint8_t Nspkrs; /* Number of Speakers */
- uint8_t Nalarm; /* Number of Alarms (at least one) */
- /*
- * Cached Flag Bytes for Global Status
- */
- uint8_t flag1;
- uint8_t flag2;
- /*
- * What object index ID is where various slots start.
- */
- uint8_t pwroff;
- uint8_t slotoff;
-#define SAFT_ALARM_OFFSET(cc) (cc)->slotoff - 1
-};
-
-#define SAFT_FLG1_ALARM 0x1
-#define SAFT_FLG1_GLOBFAIL 0x2
-#define SAFT_FLG1_GLOBWARN 0x4
-#define SAFT_FLG1_ENCPWROFF 0x8
-#define SAFT_FLG1_ENCFANFAIL 0x10
-#define SAFT_FLG1_ENCPWRFAIL 0x20
-#define SAFT_FLG1_ENCDRVFAIL 0x40
-#define SAFT_FLG1_ENCDRVWARN 0x80
-
-#define SAFT_FLG2_LOCKDOOR 0x4
-#define SAFT_PRIVATE sizeof (struct scfg)
-
-static char *safte_2little = "Too Little Data Returned (%d) at line %d\n";
-#define SAFT_BAIL(r, x, k, l) \
- if ((r) >= (x)) { \
- SES_LOG(ssc, safte_2little, x, __LINE__);\
- SES_FREE((k), (l)); \
- return (EIO); \
- }
-
-
-static int
-safte_softc_init(ses_softc_t *ssc, int doinit)
-{
- int err, i, r;
- struct scfg *cc;
-
- if (doinit == 0) {
- if (ssc->ses_nobjects) {
- if (ssc->ses_objmap) {
- SES_FREE(ssc->ses_objmap,
- ssc->ses_nobjects * sizeof (encobj));
- ssc->ses_objmap = NULL;
- }
- ssc->ses_nobjects = 0;
- }
- if (ssc->ses_private) {
- SES_FREE(ssc->ses_private, SAFT_PRIVATE);
- ssc->ses_private = NULL;
- }
- return (0);
- }
-
- if (ssc->ses_private == NULL) {
- ssc->ses_private = SES_MALLOC(SAFT_PRIVATE);
- if (ssc->ses_private == NULL) {
- return (ENOMEM);
- }
- MEMZERO(ssc->ses_private, SAFT_PRIVATE);
- }
-
- ssc->ses_nobjects = 0;
- ssc->ses_encstat = 0;
-
- if ((err = safte_getconfig(ssc)) != 0) {
- return (err);
- }
-
- /*
- * The number of objects here, as well as that reported by the
- * READ_BUFFER/GET_CONFIG call, are the over-temperature flags (15)
- * that get reported during READ_BUFFER/READ_ENC_STATUS.
- */
- cc = ssc->ses_private;
- ssc->ses_nobjects = cc->Nfans + cc->Npwr + cc->Nslots + cc->DoorLock +
- cc->Ntherm + cc->Nspkrs + NPSEUDO_THERM + NPSEUDO_ALARM;
- ssc->ses_objmap = (encobj *)
- SES_MALLOC(ssc->ses_nobjects * sizeof (encobj));
- if (ssc->ses_objmap == NULL) {
- return (ENOMEM);
- }
- MEMZERO(ssc->ses_objmap, ssc->ses_nobjects * sizeof (encobj));
-
- r = 0;
- /*
- * Note that this is all arranged for the convenience
- * in later fetches of status.
- */
- for (i = 0; i < cc->Nfans; i++)
- ssc->ses_objmap[r++].enctype = SESTYP_FAN;
- cc->pwroff = (uint8_t) r;
- for (i = 0; i < cc->Npwr; i++)
- ssc->ses_objmap[r++].enctype = SESTYP_POWER;
- for (i = 0; i < cc->DoorLock; i++)
- ssc->ses_objmap[r++].enctype = SESTYP_DOORLOCK;
- for (i = 0; i < cc->Nspkrs; i++)
- ssc->ses_objmap[r++].enctype = SESTYP_ALARM;
- for (i = 0; i < cc->Ntherm; i++)
- ssc->ses_objmap[r++].enctype = SESTYP_THERM;
- for (i = 0; i < NPSEUDO_THERM; i++)
- ssc->ses_objmap[r++].enctype = SESTYP_THERM;
- ssc->ses_objmap[r++].enctype = SESTYP_ALARM;
- cc->slotoff = (uint8_t) r;
- for (i = 0; i < cc->Nslots; i++)
- ssc->ses_objmap[r++].enctype = SESTYP_DEVICE;
- return (0);
-}
-
-static int
-safte_init_enc(ses_softc_t *ssc)
-{
- int err;
- static char cdb0[6] = { SEND_DIAGNOSTIC };
-
- err = ses_runcmd(ssc, cdb0, 6, NULL, 0);
- if (err) {
- return (err);
- }
- DELAY(5000);
- err = wrbuf16(ssc, SAFTE_WT_GLOBAL, 0, 0, 0, 1);
- return (err);
-}
-
-static int
-safte_get_encstat(ses_softc_t *ssc, int slpflg)
-{
- return (safte_rdstat(ssc, slpflg));
-}
-
-static int
-safte_set_encstat(ses_softc_t *ssc, uint8_t encstat, int slpflg)
-{
- struct scfg *cc = ssc->ses_private;
- if (cc == NULL)
- return (0);
- /*
- * Since SAF-TE devices aren't necessarily sticky in terms
- * of state, make our soft copy of enclosure status 'sticky'-
- * that is, things set in enclosure status stay set (as implied
- * by conditions set in reading object status) until cleared.
- */
- ssc->ses_encstat &= ~ALL_ENC_STAT;
- ssc->ses_encstat |= (encstat & ALL_ENC_STAT);
- ssc->ses_encstat |= ENCI_SVALID;
- cc->flag1 &= ~(SAFT_FLG1_ALARM|SAFT_FLG1_GLOBFAIL|SAFT_FLG1_GLOBWARN);
- if ((encstat & (SES_ENCSTAT_CRITICAL|SES_ENCSTAT_UNRECOV)) != 0) {
- cc->flag1 |= SAFT_FLG1_ALARM|SAFT_FLG1_GLOBFAIL;
- } else if ((encstat & SES_ENCSTAT_NONCRITICAL) != 0) {
- cc->flag1 |= SAFT_FLG1_GLOBWARN;
- }
- return (wrbuf16(ssc, SAFTE_WT_GLOBAL, cc->flag1, cc->flag2, 0, slpflg));
-}
-
-static int
-safte_get_objstat(ses_softc_t *ssc, ses_objstat *obp, int slpflg)
-{
- int i = (int)obp->obj_id;
-
- if ((ssc->ses_encstat & ENCI_SVALID) == 0 ||
- (ssc->ses_objmap[i].svalid) == 0) {
- int err = safte_rdstat(ssc, slpflg);
- if (err)
- return (err);
- }
- obp->cstat[0] = ssc->ses_objmap[i].encstat[0];
- obp->cstat[1] = ssc->ses_objmap[i].encstat[1];
- obp->cstat[2] = ssc->ses_objmap[i].encstat[2];
- obp->cstat[3] = ssc->ses_objmap[i].encstat[3];
- return (0);
-}
-
-
-static int
-safte_set_objstat(ses_softc_t *ssc, ses_objstat *obp, int slp)
-{
- int idx, err;
- encobj *ep;
- struct scfg *cc;
-
-
- SES_DLOG(ssc, "safte_set_objstat(%d): %x %x %x %x\n",
- (int)obp->obj_id, obp->cstat[0], obp->cstat[1], obp->cstat[2],
- obp->cstat[3]);
-
- /*
- * If this is clear, we don't do diddly.
- */
- if ((obp->cstat[0] & SESCTL_CSEL) == 0) {
- return (0);
- }
-
- err = 0;
- /*
- * Check to see if the common bits are set and do them first.
- */
- if (obp->cstat[0] & ~SESCTL_CSEL) {
- err = set_objstat_sel(ssc, obp, slp);
- if (err)
- return (err);
- }
-
- cc = ssc->ses_private;
- if (cc == NULL)
- return (0);
-
- idx = (int)obp->obj_id;
- ep = &ssc->ses_objmap[idx];
-
- switch (ep->enctype) {
- case SESTYP_DEVICE:
- {
- uint8_t slotop = 0;
- /*
- * XXX: I should probably cache the previous state
- * XXX: of SESCTL_DEVOFF so that when it goes from
- * XXX: true to false I can then set PREPARE FOR OPERATION
- * XXX: flag in PERFORM SLOT OPERATION write buffer command.
- */
- if (obp->cstat[2] & (SESCTL_RQSINS|SESCTL_RQSRMV)) {
- slotop |= 0x2;
- }
- if (obp->cstat[2] & SESCTL_RQSID) {
- slotop |= 0x4;
- }
- err = perf_slotop(ssc, (uint8_t) idx - (uint8_t) cc->slotoff,
- slotop, slp);
- if (err)
- return (err);
- if (obp->cstat[3] & SESCTL_RQSFLT) {
- ep->priv |= 0x2;
- } else {
- ep->priv &= ~0x2;
- }
- if (ep->priv & 0xc6) {
- ep->priv &= ~0x1;
- } else {
- ep->priv |= 0x1; /* no errors */
- }
- wrslot_stat(ssc, slp);
- break;
- }
- case SESTYP_POWER:
- if (obp->cstat[3] & SESCTL_RQSTFAIL) {
- cc->flag1 |= SAFT_FLG1_ENCPWRFAIL;
- } else {
- cc->flag1 &= ~SAFT_FLG1_ENCPWRFAIL;
- }
- err = wrbuf16(ssc, SAFTE_WT_GLOBAL, cc->flag1,
- cc->flag2, 0, slp);
- if (err)
- return (err);
- if (obp->cstat[3] & SESCTL_RQSTON) {
- (void) wrbuf16(ssc, SAFTE_WT_ACTPWS,
- idx - cc->pwroff, 0, 0, slp);
- } else {
- (void) wrbuf16(ssc, SAFTE_WT_ACTPWS,
- idx - cc->pwroff, 0, 1, slp);
- }
- break;
- case SESTYP_FAN:
- if (obp->cstat[3] & SESCTL_RQSTFAIL) {
- cc->flag1 |= SAFT_FLG1_ENCFANFAIL;
- } else {
- cc->flag1 &= ~SAFT_FLG1_ENCFANFAIL;
- }
- err = wrbuf16(ssc, SAFTE_WT_GLOBAL, cc->flag1,
- cc->flag2, 0, slp);
- if (err)
- return (err);
- if (obp->cstat[3] & SESCTL_RQSTON) {
- uint8_t fsp;
- if ((obp->cstat[3] & 0x7) == 7) {
- fsp = 4;
- } else if ((obp->cstat[3] & 0x7) == 6) {
- fsp = 3;
- } else if ((obp->cstat[3] & 0x7) == 4) {
- fsp = 2;
- } else {
- fsp = 1;
- }
- (void) wrbuf16(ssc, SAFTE_WT_FANSPD, idx, fsp, 0, slp);
- } else {
- (void) wrbuf16(ssc, SAFTE_WT_FANSPD, idx, 0, 0, slp);
- }
- break;
- case SESTYP_DOORLOCK:
- if (obp->cstat[3] & 0x1) {
- cc->flag2 &= ~SAFT_FLG2_LOCKDOOR;
- } else {
- cc->flag2 |= SAFT_FLG2_LOCKDOOR;
- }
- (void) wrbuf16(ssc, SAFTE_WT_GLOBAL, cc->flag1,
- cc->flag2, 0, slp);
- break;
- case SESTYP_ALARM:
- /*
- * On all nonzero but the 'muted' bit, we turn on the alarm,
- */
- obp->cstat[3] &= ~0xa;
- if (obp->cstat[3] & 0x40) {
- cc->flag2 &= ~SAFT_FLG1_ALARM;
- } else if (obp->cstat[3] != 0) {
- cc->flag2 |= SAFT_FLG1_ALARM;
- } else {
- cc->flag2 &= ~SAFT_FLG1_ALARM;
- }
- ep->priv = obp->cstat[3];
- (void) wrbuf16(ssc, SAFTE_WT_GLOBAL, cc->flag1,
- cc->flag2, 0, slp);
- break;
- default:
- break;
- }
- ep->svalid = 0;
- return (0);
-}
-
-static int
-safte_getconfig(ses_softc_t *ssc)
-{
- struct scfg *cfg;
- int err, amt;
- char *sdata;
- static char cdb[10] =
- { READ_BUFFER, 1, SAFTE_RD_RDCFG, 0, 0, 0, 0, 0, SAFT_SCRATCH, 0 };
-
- cfg = ssc->ses_private;
- if (cfg == NULL)
- return (ENXIO);
-
- sdata = SES_MALLOC(SAFT_SCRATCH);
- if (sdata == NULL)
- return (ENOMEM);
-
- amt = SAFT_SCRATCH;
- err = ses_runcmd(ssc, cdb, 10, sdata, &amt);
- if (err) {
- SES_FREE(sdata, SAFT_SCRATCH);
- return (err);
- }
- amt = SAFT_SCRATCH - amt;
- if (amt < 6) {
- SES_LOG(ssc, "too little data (%d) for configuration\n", amt);
- SES_FREE(sdata, SAFT_SCRATCH);
- return (EIO);
- }
- SES_VLOG(ssc, "Nfans %d Npwr %d Nslots %d Lck %d Ntherm %d Nspkrs %d\n",
- sdata[0], sdata[1], sdata[2], sdata[3], sdata[4], sdata[5]);
- cfg->Nfans = sdata[0];
- cfg->Npwr = sdata[1];
- cfg->Nslots = sdata[2];
- cfg->DoorLock = sdata[3];
- cfg->Ntherm = sdata[4];
- cfg->Nspkrs = sdata[5];
- cfg->Nalarm = NPSEUDO_ALARM;
- SES_FREE(sdata, SAFT_SCRATCH);
- return (0);
-}
-
-static int
-safte_rdstat(ses_softc_t *ssc, int slpflg)
-{
- int err, oid, r, i, hiwater, nitems, amt;
- uint16_t tempflags;
- size_t buflen;
- uint8_t status, oencstat;
- char *sdata, cdb[10];
- struct scfg *cc = ssc->ses_private;
-
-
- /*
- * The number of objects overstates things a bit,
- * both for the bogus 'thermometer' entries and
- * the drive status (which isn't read at the same
- * time as the enclosure status), but that's okay.
- */
- buflen = 4 * cc->Nslots;
- if (ssc->ses_nobjects > buflen)
- buflen = ssc->ses_nobjects;
- sdata = SES_MALLOC(buflen);
- if (sdata == NULL)
- return (ENOMEM);
-
- cdb[0] = READ_BUFFER;
- cdb[1] = 1;
- cdb[2] = SAFTE_RD_RDESTS;
- cdb[3] = 0;
- cdb[4] = 0;
- cdb[5] = 0;
- cdb[6] = 0;
- cdb[7] = (buflen >> 8) & 0xff;
- cdb[8] = buflen & 0xff;
- cdb[9] = 0;
- amt = buflen;
- err = ses_runcmd(ssc, cdb, 10, sdata, &amt);
- if (err) {
- SES_FREE(sdata, buflen);
- return (err);
- }
- hiwater = buflen - amt;
-
-
- /*
- * invalidate all status bits.
- */
- for (i = 0; i < ssc->ses_nobjects; i++)
- ssc->ses_objmap[i].svalid = 0;
- oencstat = ssc->ses_encstat & ALL_ENC_STAT;
- ssc->ses_encstat = 0;
-
-
- /*
- * Now parse returned buffer.
- * If we didn't get enough data back,
- * that's considered a fatal error.
- */
- oid = r = 0;
-
- for (nitems = i = 0; i < cc->Nfans; i++) {
- SAFT_BAIL(r, hiwater, sdata, buflen);
- /*
- * 0 = Fan Operational
- * 1 = Fan is malfunctioning
- * 2 = Fan is not present
- * 0x80 = Unknown or Not Reportable Status
- */
- ssc->ses_objmap[oid].encstat[1] = 0; /* resvd */
- ssc->ses_objmap[oid].encstat[2] = 0; /* resvd */
- switch ((int)(uint8_t)sdata[r]) {
- case 0:
- nitems++;
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_OK;
- /*
- * We could get fancier and cache
- * fan speeds that we have set, but
- * that isn't done now.
- */
- ssc->ses_objmap[oid].encstat[3] = 7;
- break;
-
- case 1:
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_CRIT;
- /*
- * FAIL and FAN STOPPED synthesized
- */
- ssc->ses_objmap[oid].encstat[3] = 0x40;
- /*
- * Enclosure marked with CRITICAL error
- * if only one fan or no thermometers,
- * else the NONCRITICAL error is set.
- */
- if (cc->Nfans == 1 || cc->Ntherm == 0)
- ssc->ses_encstat |= SES_ENCSTAT_CRITICAL;
- else
- ssc->ses_encstat |= SES_ENCSTAT_NONCRITICAL;
- break;
- case 2:
- ssc->ses_objmap[oid].encstat[0] =
- SES_OBJSTAT_NOTINSTALLED;
- ssc->ses_objmap[oid].encstat[3] = 0;
- /*
- * Enclosure marked with CRITICAL error
- * if only one fan or no thermometers,
- * else the NONCRITICAL error is set.
- */
- if (cc->Nfans == 1)
- ssc->ses_encstat |= SES_ENCSTAT_CRITICAL;
- else
- ssc->ses_encstat |= SES_ENCSTAT_NONCRITICAL;
- break;
- case 0x80:
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_UNKNOWN;
- ssc->ses_objmap[oid].encstat[3] = 0;
- ssc->ses_encstat |= SES_ENCSTAT_INFO;
- break;
- default:
- ssc->ses_objmap[oid].encstat[0] =
- SES_OBJSTAT_UNSUPPORTED;
- SES_LOG(ssc, "Unknown fan%d status 0x%x\n", i,
- sdata[r] & 0xff);
- break;
- }
- ssc->ses_objmap[oid++].svalid = 1;
- r++;
- }
-
- /*
- * No matter how you cut it, no cooling elements when there
- * should be some there is critical.
- */
- if (cc->Nfans && nitems == 0) {
- ssc->ses_encstat |= SES_ENCSTAT_CRITICAL;
- }
-
-
- for (i = 0; i < cc->Npwr; i++) {
- SAFT_BAIL(r, hiwater, sdata, buflen);
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_UNKNOWN;
- ssc->ses_objmap[oid].encstat[1] = 0; /* resvd */
- ssc->ses_objmap[oid].encstat[2] = 0; /* resvd */
- ssc->ses_objmap[oid].encstat[3] = 0x20; /* requested on */
- switch ((uint8_t)sdata[r]) {
- case 0x00: /* pws operational and on */
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_OK;
- break;
- case 0x01: /* pws operational and off */
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_OK;
- ssc->ses_objmap[oid].encstat[3] = 0x10;
- ssc->ses_encstat |= SES_ENCSTAT_INFO;
- break;
- case 0x10: /* pws is malfunctioning and commanded on */
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_CRIT;
- ssc->ses_objmap[oid].encstat[3] = 0x61;
- ssc->ses_encstat |= SES_ENCSTAT_NONCRITICAL;
- break;
-
- case 0x11: /* pws is malfunctioning and commanded off */
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_NONCRIT;
- ssc->ses_objmap[oid].encstat[3] = 0x51;
- ssc->ses_encstat |= SES_ENCSTAT_NONCRITICAL;
- break;
- case 0x20: /* pws is not present */
- ssc->ses_objmap[oid].encstat[0] =
- SES_OBJSTAT_NOTINSTALLED;
- ssc->ses_objmap[oid].encstat[3] = 0;
- ssc->ses_encstat |= SES_ENCSTAT_INFO;
- break;
- case 0x21: /* pws is present */
- /*
- * This is for enclosures that cannot tell whether the
- * device is on or malfunctioning, but know that it is
- * present. Just fall through.
- */
- /* FALLTHROUGH */
- case 0x80: /* Unknown or Not Reportable Status */
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_UNKNOWN;
- ssc->ses_objmap[oid].encstat[3] = 0;
- ssc->ses_encstat |= SES_ENCSTAT_INFO;
- break;
- default:
- SES_LOG(ssc, "unknown power supply %d status (0x%x)\n",
- i, sdata[r] & 0xff);
- break;
- }
- ssc->ses_objmap[oid++].svalid = 1;
- r++;
- }
-
- /*
- * Skip over Slot SCSI IDs
- */
- r += cc->Nslots;
-
- /*
- * We always have doorlock status, no matter what,
- * but we only save the status if we have one.
- */
- SAFT_BAIL(r, hiwater, sdata, buflen);
- if (cc->DoorLock) {
- /*
- * 0 = Door Locked
- * 1 = Door Unlocked, or no Lock Installed
- * 0x80 = Unknown or Not Reportable Status
- */
- ssc->ses_objmap[oid].encstat[1] = 0;
- ssc->ses_objmap[oid].encstat[2] = 0;
- switch ((uint8_t)sdata[r]) {
- case 0:
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_OK;
- ssc->ses_objmap[oid].encstat[3] = 0;
- break;
- case 1:
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_OK;
- ssc->ses_objmap[oid].encstat[3] = 1;
- break;
- case 0x80:
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_UNKNOWN;
- ssc->ses_objmap[oid].encstat[3] = 0;
- ssc->ses_encstat |= SES_ENCSTAT_INFO;
- break;
- default:
- ssc->ses_objmap[oid].encstat[0] =
- SES_OBJSTAT_UNSUPPORTED;
- SES_LOG(ssc, "unknown lock status 0x%x\n",
- sdata[r] & 0xff);
- break;
- }
- ssc->ses_objmap[oid++].svalid = 1;
- }
- r++;
-
- /*
- * We always have speaker status, no matter what,
- * but we only save the status if we have one.
- */
- SAFT_BAIL(r, hiwater, sdata, buflen);
- if (cc->Nspkrs) {
- ssc->ses_objmap[oid].encstat[1] = 0;
- ssc->ses_objmap[oid].encstat[2] = 0;
- if (sdata[r] == 1) {
- /*
- * We need to cache tone urgency indicators.
- * Someday.
- */
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_NONCRIT;
- ssc->ses_objmap[oid].encstat[3] = 0x8;
- ssc->ses_encstat |= SES_ENCSTAT_NONCRITICAL;
- } else if (sdata[r] == 0) {
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_OK;
- ssc->ses_objmap[oid].encstat[3] = 0;
- } else {
- ssc->ses_objmap[oid].encstat[0] =
- SES_OBJSTAT_UNSUPPORTED;
- ssc->ses_objmap[oid].encstat[3] = 0;
- SES_LOG(ssc, "unknown spkr status 0x%x\n",
- sdata[r] & 0xff);
- }
- ssc->ses_objmap[oid++].svalid = 1;
- }
- r++;
-
- for (i = 0; i < cc->Ntherm; i++) {
- SAFT_BAIL(r, hiwater, sdata, buflen);
- /*
- * Status is a range from -10 to 245 deg Celsius,
- * which we need to normalize to -20 to -245 according
- * to the latest SCSI spec, which makes little
- * sense since this would overflow an 8bit value.
- * Well, still, the base normalization is -20,
- * not -10, so we have to adjust.
- *
- * So what's over and under temperature?
- * Hmm- we'll state that 'normal' operating
- * is 10 to 40 deg Celsius.
- */
-
- /*
- * Actually.... All of the units that people out in the world
- * seem to have do not come even close to setting a value that
- * complies with this spec.
- *
- * The closest explanation I could find was in an
- * LSI-Logic manual, which seemed to indicate that
- * this value would be set by whatever the I2C code
- * would interpolate from the output of an LM75
- * temperature sensor.
- *
- * This means that it is impossible to use the actual
- * numeric value to predict anything. But we don't want
- * to lose the value. So, we'll propagate the *uncorrected*
- * value and set SES_OBJSTAT_NOTAVAIL. We'll depend on the
- * temperature flags for warnings.
- */
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_NOTAVAIL;
- ssc->ses_objmap[oid].encstat[1] = 0;
- ssc->ses_objmap[oid].encstat[2] = sdata[r];
- ssc->ses_objmap[oid].encstat[3] = 0;
- ssc->ses_objmap[oid++].svalid = 1;
- r++;
- }
-
- /*
- * Now, for "pseudo" thermometers, we have two bytes
- * of information in enclosure status- 16 bits. Actually,
- * the MSB is a single TEMP ALERT flag indicating whether
- * any other bits are set, but, thanks to fuzzy thinking,
- * in the SAF-TE spec, this can also be set even if no
- * other bits are set, thus making this really another
- * binary temperature sensor.
- */
-
- SAFT_BAIL(r, hiwater, sdata, buflen);
- tempflags = sdata[r++];
- SAFT_BAIL(r, hiwater, sdata, buflen);
- tempflags |= (tempflags << 8) | sdata[r++];
-
- for (i = 0; i < NPSEUDO_THERM; i++) {
- ssc->ses_objmap[oid].encstat[1] = 0;
- if (tempflags & (1 << (NPSEUDO_THERM - i - 1))) {
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_CRIT;
- ssc->ses_objmap[4].encstat[2] = 0xff;
- /*
- * Set 'over temperature' failure.
- */
- ssc->ses_objmap[oid].encstat[3] = 8;
- ssc->ses_encstat |= SES_ENCSTAT_CRITICAL;
- } else {
- /*
- * We used to say 'not available' and synthesize a
- * nominal 30 deg (C)- that was wrong. Actually,
- * Just say 'OK', and use the reserved value of
- * zero.
- */
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_OK;
- ssc->ses_objmap[oid].encstat[2] = 0;
- ssc->ses_objmap[oid].encstat[3] = 0;
- }
- ssc->ses_objmap[oid++].svalid = 1;
- }
-
- /*
- * Get alarm status.
- */
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_OK;
- ssc->ses_objmap[oid].encstat[3] = ssc->ses_objmap[oid].priv;
- ssc->ses_objmap[oid++].svalid = 1;
-
- /*
- * Now get drive slot status
- */
- cdb[2] = SAFTE_RD_RDDSTS;
- amt = buflen;
- err = ses_runcmd(ssc, cdb, 10, sdata, &amt);
- if (err) {
- SES_FREE(sdata, buflen);
- return (err);
- }
- hiwater = buflen - amt;
- for (r = i = 0; i < cc->Nslots; i++, r += 4) {
- SAFT_BAIL(r+3, hiwater, sdata, buflen);
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_UNSUPPORTED;
- ssc->ses_objmap[oid].encstat[1] = (uint8_t) i;
- ssc->ses_objmap[oid].encstat[2] = 0;
- ssc->ses_objmap[oid].encstat[3] = 0;
- status = sdata[r+3];
- if ((status & 0x1) == 0) { /* no device */
- ssc->ses_objmap[oid].encstat[0] =
- SES_OBJSTAT_NOTINSTALLED;
- } else {
- ssc->ses_objmap[oid].encstat[0] = SES_OBJSTAT_OK;
- }
- if (status & 0x2) {
- ssc->ses_objmap[oid].encstat[2] = 0x8;
- }
- if ((status & 0x4) == 0) {
- ssc->ses_objmap[oid].encstat[3] = 0x10;
- }
- ssc->ses_objmap[oid++].svalid = 1;
- }
- /* see comment below about sticky enclosure status */
- ssc->ses_encstat |= ENCI_SVALID | oencstat;
- SES_FREE(sdata, buflen);
- return (0);
-}
-
-static int
-set_objstat_sel(ses_softc_t *ssc, ses_objstat *obp, int slp)
-{
- int idx;
- encobj *ep;
- struct scfg *cc = ssc->ses_private;
-
- if (cc == NULL)
- return (0);
-
- idx = (int)obp->obj_id;
- ep = &ssc->ses_objmap[idx];
-
- switch (ep->enctype) {
- case SESTYP_DEVICE:
- if (obp->cstat[0] & SESCTL_PRDFAIL) {
- ep->priv |= 0x40;
- }
- /* SESCTL_RSTSWAP has no correspondence in SAF-TE */
- if (obp->cstat[0] & SESCTL_DISABLE) {
- ep->priv |= 0x80;
- /*
- * Hmm. Try to set the 'No Drive' flag.
- * Maybe that will count as a 'disable'.
- */
- }
- if (ep->priv & 0xc6) {
- ep->priv &= ~0x1;
- } else {
- ep->priv |= 0x1; /* no errors */
- }
- wrslot_stat(ssc, slp);
- break;
- case SESTYP_POWER:
- /*
- * Okay- the only one that makes sense here is to
- * do the 'disable' for a power supply.
- */
- if (obp->cstat[0] & SESCTL_DISABLE) {
- (void) wrbuf16(ssc, SAFTE_WT_ACTPWS,
- idx - cc->pwroff, 0, 0, slp);
- }
- break;
- case SESTYP_FAN:
- /*
- * Okay- the only one that makes sense here is to
- * set fan speed to zero on disable.
- */
- if (obp->cstat[0] & SESCTL_DISABLE) {
- /* remember- fans are the first items, so idx works */
- (void) wrbuf16(ssc, SAFTE_WT_FANSPD, idx, 0, 0, slp);
- }
- break;
- case SESTYP_DOORLOCK:
- /*
- * Well, we can 'disable' the lock.
- */
- if (obp->cstat[0] & SESCTL_DISABLE) {
- cc->flag2 &= ~SAFT_FLG2_LOCKDOOR;
- (void) wrbuf16(ssc, SAFTE_WT_GLOBAL, cc->flag1,
- cc->flag2, 0, slp);
- }
- break;
- case SESTYP_ALARM:
- /*
- * Well, we can 'disable' the alarm.
- */
- if (obp->cstat[0] & SESCTL_DISABLE) {
- cc->flag2 &= ~SAFT_FLG1_ALARM;
- ep->priv |= 0x40; /* Muted */
- (void) wrbuf16(ssc, SAFTE_WT_GLOBAL, cc->flag1,
- cc->flag2, 0, slp);
- }
- break;
- default:
- break;
- }
- ep->svalid = 0;
- return (0);
-}
-
-/*
- * This function handles all of the 16 byte WRITE BUFFER commands.
- */
-static int
-wrbuf16(ses_softc_t *ssc, uint8_t op, uint8_t b1, uint8_t b2,
- uint8_t b3, int slp)
-{
- int err, amt;
- char *sdata;
- struct scfg *cc = ssc->ses_private;
- static char cdb[10] = { WRITE_BUFFER, 1, 0, 0, 0, 0, 0, 0, 16, 0 };
-
- if (cc == NULL)
- return (0);
-
- sdata = SES_MALLOC(16);
- if (sdata == NULL)
- return (ENOMEM);
-
- SES_DLOG(ssc, "saf_wrbuf16 %x %x %x %x\n", op, b1, b2, b3);
-
- sdata[0] = op;
- sdata[1] = b1;
- sdata[2] = b2;
- sdata[3] = b3;
- MEMZERO(&sdata[4], 12);
- amt = -16;
- err = ses_runcmd(ssc, cdb, 10, sdata, &amt);
- SES_FREE(sdata, 16);
- return (err);
-}
-
-/*
- * This function updates the status byte for the device slot described.
- *
- * Since this is an optional SAF-TE command, there's no point in
- * returning an error.
- */
-static void
-wrslot_stat(ses_softc_t *ssc, int slp)
-{
- int i, amt;
- encobj *ep;
- char cdb[10], *sdata;
- struct scfg *cc = ssc->ses_private;
-
- if (cc == NULL)
- return;
-
- SES_DLOG(ssc, "saf_wrslot\n");
- cdb[0] = WRITE_BUFFER;
- cdb[1] = 1;
- cdb[2] = 0;
- cdb[3] = 0;
- cdb[4] = 0;
- cdb[5] = 0;
- cdb[6] = 0;
- cdb[7] = 0;
- cdb[8] = cc->Nslots * 3 + 1;
- cdb[9] = 0;
-
- sdata = SES_MALLOC(cc->Nslots * 3 + 1);
- if (sdata == NULL)
- return;
- MEMZERO(sdata, cc->Nslots * 3 + 1);
-
- sdata[0] = SAFTE_WT_DSTAT;
- for (i = 0; i < cc->Nslots; i++) {
- ep = &ssc->ses_objmap[cc->slotoff + i];
- SES_DLOG(ssc, "saf_wrslot %d <- %x\n", i, ep->priv & 0xff);
- sdata[1 + (3 * i)] = ep->priv & 0xff;
- }
- amt = -(cc->Nslots * 3 + 1);
- (void) ses_runcmd(ssc, cdb, 10, sdata, &amt);
- SES_FREE(sdata, cc->Nslots * 3 + 1);
-}
-
-/*
- * This function issues the "PERFORM SLOT OPERATION" command.
- */
-static int
-perf_slotop(ses_softc_t *ssc, uint8_t slot, uint8_t opflag, int slp)
-{
- int err, amt;
- char *sdata;
- struct scfg *cc = ssc->ses_private;
- static char cdb[10] =
- { WRITE_BUFFER, 1, 0, 0, 0, 0, 0, 0, SAFT_SCRATCH, 0 };
-
- if (cc == NULL)
- return (0);
-
- sdata = SES_MALLOC(SAFT_SCRATCH);
- if (sdata == NULL)
- return (ENOMEM);
- MEMZERO(sdata, SAFT_SCRATCH);
-
- sdata[0] = SAFTE_WT_SLTOP;
- sdata[1] = slot;
- sdata[2] = opflag;
- SES_DLOG(ssc, "saf_slotop slot %d op %x\n", slot, opflag);
- amt = -SAFT_SCRATCH;
- err = ses_runcmd(ssc, cdb, 10, sdata, &amt);
- SES_FREE(sdata, SAFT_SCRATCH);
- return (err);
-}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_ses.h
--- a/head/sys/cam/scsi/scsi_ses.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/scsi/scsi_ses.h Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
-/* $FreeBSD: head/sys/cam/scsi/scsi_ses.h 222339 2011-05-27 03:44:47Z mav $ */
+/* $FreeBSD: head/sys/cam/scsi/scsi_ses.h 238740 2012-07-24 13:32:49Z mav $ */
/*-
* Copyright (c) 2000 by Matthew Jacob
* All rights reserved.
@@ -29,107 +29,2131 @@
*
*/
-#define SESIOC ('s' - 040)
-#define SESIOC_GETNOBJ _IO(SESIOC, 1)
-#define SESIOC_GETOBJMAP _IO(SESIOC, 2)
-#define SESIOC_GETENCSTAT _IO(SESIOC, 3)
-#define SESIOC_SETENCSTAT _IO(SESIOC, 4)
-#define SESIOC_GETOBJSTAT _IO(SESIOC, 5)
-#define SESIOC_SETOBJSTAT _IO(SESIOC, 6)
-#define SESIOC_GETTEXT _IO(SESIOC, 7)
-#define SESIOC_INIT _IO(SESIOC, 8)
+#ifndef _SCSI_SES_H_
+#define _SCSI_SES_H_
+#include <cam/scsi/scsi_all.h>
+
+/*========================== Field Extraction Macros =========================*/
+#define MK_ENUM(S, F, SUFFIX) S ## _ ## F ## SUFFIX
+
+#define GEN_GETTER(LS, US, LF, UF) \
+static inline int \
+LS ## _get_ ## LF(struct LS *elem) { \
+ return ((elem->bytes[MK_ENUM(US,UF,_BYTE)] & MK_ENUM(US,UF,_MASK)) \
+ >> MK_ENUM(US,UF,_SHIFT)); \
+}
+
+#define GEN_SETTER(LS, US, LF, UF) \
+static inline void \
+LS ## _set_ ## LF(struct LS *elem, int val) { \
+ elem->bytes[MK_ENUM(US,UF,_BYTE)] &= ~MK_ENUM(US,UF,_MASK); \
+ elem->bytes[MK_ENUM(US,UF,_BYTE)] |= \
+ (val << MK_ENUM(US,UF,_SHIFT)) & MK_ENUM(US,UF,_MASK); \
+}
+
+#define GEN_HDR_GETTER(LS, US, LF, UF) \
+static inline int \
+LS ## _get_ ## LF(struct LS *page) { \
+ return ((page->hdr.page_specific_flags & MK_ENUM(US,UF,_MASK)) \
+ >> MK_ENUM(US,UF,_SHIFT)); \
+}
+
+#define GEN_HDR_SETTER(LS, US, LF, UF) \
+static inline void \
+LS ## _set_ ## LF(struct LS *page, int val) { \
+ page->hdr.page_specific_flags &= ~MK_ENUM(US,UF,_MASK); \
+ page->hdr.page_specific_flags |= \
+ (val << MK_ENUM(US,UF,_SHIFT)) & MK_ENUM(US,UF,_MASK); \
+}
+
+#define GEN_ACCESSORS(LS, US, LF, UF) \
+GEN_GETTER(LS, US, LF, UF) \
+GEN_SETTER(LS, US, LF, UF)
+
+#define GEN_HDR_ACCESSORS(LS, US, LF, UF) \
+GEN_HDR_GETTER(LS, US, LF, UF) \
+GEN_HDR_SETTER(LS, US, LF, UF)
+
+/*=============== Common SCSI ENC Diagnostic Page Structures ===============*/
+struct ses_page_hdr {
+ uint8_t page_code;
+ uint8_t page_specific_flags;
+ uint8_t length[2];
+ uint8_t gen_code[4];
+};
+
+static inline size_t
+ses_page_length(const struct ses_page_hdr *hdr)
+{
+ /*
+ * The page length as received only accounts for bytes that
+ * follow the length field, namely starting with the generation
+ * code field.
+ */
+ return (scsi_2btoul(hdr->length)
+ + offsetof(struct ses_page_hdr, gen_code));
+}
+
+/*============= SCSI ENC Configuration Diagnostic Page Structures ============*/
+struct ses_enc_desc {
+ uint8_t byte0;
+ /*
+ * reserved0 : 1,
+ * rel_id : 3, relative enclosure process id
+ * reserved1 : 1,
+ * num_procs : 3; number of enclosure procesenc
+ */
+ uint8_t subenc_id; /* Sub-enclosure Identifier */
+ uint8_t num_types; /* # of supported types */
+ uint8_t length; /* Enclosure Descriptor Length */
+ uint8_t logical_id[8]; /* formerly wwn */
+ uint8_t vendor_id[8];
+ uint8_t product_id[16];
+ uint8_t product_rev[4];
+ uint8_t vendor_bytes[];
+};
+
+static inline uint8_t *
+ses_enc_desc_last_byte(struct ses_enc_desc *encdesc)
+{
+ return (&encdesc->length + encdesc->length);
+}
+
+static inline struct ses_enc_desc *
+ses_enc_desc_next(struct ses_enc_desc *encdesc)
+{
+ return ((struct ses_enc_desc *)(ses_enc_desc_last_byte(encdesc) + 1));
+}
+
+static inline int
+ses_enc_desc_is_complete(struct ses_enc_desc *encdesc, uint8_t *last_buf_byte)
+{
+ return (&encdesc->length <= last_buf_byte
+ && ses_enc_desc_last_byte(encdesc) <= last_buf_byte);
+}
+
+struct ses_elm_type_desc {
+ uint8_t etype_elm_type; /* type of element */
+ uint8_t etype_maxelt; /* maximum supported */
+ uint8_t etype_subenc; /* in sub-enclosure #n */
+ uint8_t etype_txt_len; /* Type Descriptor Text Length */
+};
+
+struct ses_cfg_page {
+ struct ses_page_hdr hdr;
+ struct ses_enc_desc subencs[];
+ /* type descriptors */
+ /* type text */
+};
+
+static inline int
+ses_cfg_page_get_num_subenc(struct ses_cfg_page *page)
+{
+ return (page->hdr.page_specific_flags + 1);
+}
+
+
+/*================ SCSI SES Control Diagnostic Page Structures ==============*/
+struct ses_ctrl_common {
+ uint8_t bytes[1];
+};
+
+enum ses_ctrl_common_field_data {
+ SES_CTRL_COMMON_SELECT_BYTE = 0,
+ SES_CTRL_COMMON_SELECT_MASK = 0x80,
+ SES_CTRL_COMMON_SELECT_SHIFT = 7,
+
+ SES_CTRL_COMMON_PRDFAIL_BYTE = 0,
+ SES_CTRL_COMMON_PRDFAIL_MASK = 0x40,
+ SES_CTRL_COMMON_PRDFAIL_SHIFT = 6,
+
+ SES_CTRL_COMMON_DISABLE_BYTE = 0,
+ SES_CTRL_COMMON_DISABLE_MASK = 0x20,
+ SES_CTRL_COMMON_DISABLE_SHIFT = 5,
+
+ SES_CTRL_COMMON_RST_SWAP_BYTE = 0,
+ SES_CTRL_COMMON_RST_SWAP_MASK = 0x10,
+ SES_CTRL_COMMON_RST_SWAP_SHIFT = 4
+};
+
+#define GEN_SES_CTRL_COMMON_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_common, SES_CTRL_COMMON, LCASE, UCASE)
+GEN_SES_CTRL_COMMON_ACCESSORS(select, SELECT)
+GEN_SES_CTRL_COMMON_ACCESSORS(prdfail, PRDFAIL)
+GEN_SES_CTRL_COMMON_ACCESSORS(disable, DISABLE)
+GEN_SES_CTRL_COMMON_ACCESSORS(rst_swap, RST_SWAP)
+#undef GEN_SES_CTRL_COMMON_ACCESSORS
+
+/*------------------------ Device Slot Control Element ----------------------*/
+struct ses_ctrl_dev_slot {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_dev_slot_field_data {
+ SES_CTRL_DEV_SLOT_RQST_ACTIVE_BYTE = 1,
+ SES_CTRL_DEV_SLOT_RQST_ACTIVE_MASK = 0x80,
+ SES_CTRL_DEV_SLOT_RQST_ACTIVE_SHIFT = 7,
+
+ SES_CTRL_DEV_SLOT_DO_NOT_REMOVE_BYTE = 1,
+ SES_CTRL_DEV_SLOT_DO_NOT_REMOVE_MASK = 0x40,
+ SES_CTRL_DEV_SLOT_DO_NOT_REMOVE_SHIFT = 6,
+
+ SES_CTRL_DEV_SLOT_RQST_MISSING_BYTE = 1,
+ SES_CTRL_DEV_SLOT_RQST_MISSING_MASK = 0x10,
+ SES_CTRL_DEV_SLOT_RQST_MISSING_SHIFT = 4,
+
+ SES_CTRL_DEV_SLOT_RQST_INSERT_BYTE = 1,
+ SES_CTRL_DEV_SLOT_RQST_INSERT_MASK = 0x08,
+ SES_CTRL_DEV_SLOT_RQST_INSERT_SHIFT = 3,
+
+ SES_CTRL_DEV_SLOT_RQST_REMOVE_BYTE = 1,
+ SES_CTRL_DEV_SLOT_RQST_REMOVE_MASK = 0x04,
+ SES_CTRL_DEV_SLOT_RQST_REMOVE_SHIFT = 2,
+
+ SES_CTRL_DEV_SLOT_RQST_IDENT_BYTE = 1,
+ SES_CTRL_DEV_SLOT_RQST_IDENT_MASK = 0x02,
+ SES_CTRL_DEV_SLOT_RQST_IDENT_SHIFT = 1,
+
+ SES_CTRL_DEV_SLOT_RQST_FAULT_BYTE = 2,
+ SES_CTRL_DEV_SLOT_RQST_FAULT_MASK = 0x20,
+ SES_CTRL_DEV_SLOT_RQST_FAULT_SHIFT = 5,
+
+ SES_CTRL_DEV_SLOT_DEVICE_OFF_BYTE = 2,
+ SES_CTRL_DEV_SLOT_DEVICE_OFF_MASK = 0x10,
+ SES_CTRL_DEV_SLOT_DEVICE_OFF_SHIFT = 4,
+
+ SES_CTRL_DEV_SLOT_ENABLE_BYP_A_BYTE = 2,
+ SES_CTRL_DEV_SLOT_ENABLE_BYP_A_MASK = 0x08,
+ SES_CTRL_DEV_SLOT_ENABLE_BYP_A_SHIFT = 3,
+
+ SES_CTRL_DEV_SLOT_ENABLE_BYP_B_BYTE = 2,
+ SES_CTRL_DEV_SLOT_ENABLE_BYP_B_MASK = 0x04,
+ SES_CTRL_DEV_SLOT_ENABLE_BYP_B_SHIFT = 2
+};
+#define GEN_SES_CTRL_DEV_SLOT_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_dev_slot, SES_CTRL_DEV_SLOT, LCASE, UCASE)
+
+GEN_SES_CTRL_DEV_SLOT_ACCESSORS(rqst_active, RQST_ACTIVE)
+GEN_SES_CTRL_DEV_SLOT_ACCESSORS(do_not_remove, DO_NOT_REMOVE)
+GEN_SES_CTRL_DEV_SLOT_ACCESSORS(rqst_missing, RQST_MISSING)
+GEN_SES_CTRL_DEV_SLOT_ACCESSORS(rqst_insert, RQST_INSERT)
+GEN_SES_CTRL_DEV_SLOT_ACCESSORS(rqst_remove, RQST_REMOVE)
+GEN_SES_CTRL_DEV_SLOT_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_DEV_SLOT_ACCESSORS(rqst_fault, RQST_FAULT)
+GEN_SES_CTRL_DEV_SLOT_ACCESSORS(device_off, DEVICE_OFF)
+GEN_SES_CTRL_DEV_SLOT_ACCESSORS(enable_byp_a, ENABLE_BYP_A)
+GEN_SES_CTRL_DEV_SLOT_ACCESSORS(enable_byp_b, ENABLE_BYP_B)
+#undef GEN_SES_CTRL_DEV_SLOT_ACCESSORS
+
+/*--------------------- Array Device Slot Control Element --------------------*/
+struct ses_ctrl_array_dev_slot {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_array_dev_slot_field_data {
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_OK_BYTE = 0,
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_OK_MASK = 0x80,
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_OK_SHIFT = 7,
+
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_RSVD_DEVICE_BYTE = 0,
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_RSVD_DEVICE_MASK = 0x40,
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_RSVD_DEVICE_SHIFT = 6,
+
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_HOT_SPARE_BYTE = 0,
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_HOT_SPARE_MASK = 0x20,
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_HOT_SPARE_SHIFT = 5,
+
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_CONS_CHECK_BYTE = 0,
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_CONS_CHECK_MASK = 0x10,
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_CONS_CHECK_SHIFT = 4,
+
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_IN_CRIT_ARRAY_BYTE = 0,
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_IN_CRIT_ARRAY_MASK = 0x08,
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_IN_CRIT_ARRAY_SHIFT = 3,
+
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_IN_FAILED_ARRAY_BYTE = 0,
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_IN_FAILED_ARRAY_MASK = 0x04,
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_IN_FAILED_ARRAY_SHIFT = 2,
+
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_REBUILD_REMAP_BYTE = 0,
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_REBUILD_REMAP_MASK = 0x02,
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_REBUILD_REMAP_SHIFT = 1,
+
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_REBUILD_REMAP_ABORT_BYTE = 0,
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_REBUILD_REMAP_ABORT_MASK = 0x01,
+ SES_CTRL_ARRAY_DEV_SLOT_RQST_REBUILD_REMAP_ABORT_SHIFT = 0
+
+ /*
+ * The remaining fields are identical to the device
+ * slot element type. Access them through the device slot
+ * element type and its accessors.
+ */
+};
+#define GEN_SES_CTRL_ARRAY_DEV_SLOT_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_array_dev_slot, SES_CTRL_ARRAY_DEV_SLOT, \
+ LCASE, UCASE)
+GEN_SES_CTRL_ARRAY_DEV_SLOT_ACCESSORS(rqst_ok, RQST_OK)
+GEN_SES_CTRL_ARRAY_DEV_SLOT_ACCESSORS(rqst_rsvd_device, RQST_RSVD_DEVICE)
+GEN_SES_CTRL_ARRAY_DEV_SLOT_ACCESSORS(rqst_hot_spare, RQST_HOT_SPARE)
+GEN_SES_CTRL_ARRAY_DEV_SLOT_ACCESSORS(rqst_cons_check, RQST_CONS_CHECK)
+GEN_SES_CTRL_ARRAY_DEV_SLOT_ACCESSORS(rqst_in_crit_array, RQST_IN_CRIT_ARRAY)
+GEN_SES_CTRL_ARRAY_DEV_SLOT_ACCESSORS(rqst_in_failed_array,
+ RQST_IN_FAILED_ARRAY)
+GEN_SES_CTRL_ARRAY_DEV_SLOT_ACCESSORS(rqst_rebuild_remap, RQST_REBUILD_REMAP)
+GEN_SES_CTRL_ARRAY_DEV_SLOT_ACCESSORS(rqst_rebuild_remap_abort,
+ RQST_REBUILD_REMAP_ABORT)
+#undef GEN_SES_CTRL_ARRAY_DEV_SLOT_ACCESSORS
+
+/*----------------------- Power Supply Control Element -----------------------*/
+struct ses_ctrl_power_supply {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_power_supply_field_data {
+ SES_CTRL_POWER_SUPPLY_RQST_IDENT_BYTE = 0,
+ SES_CTRL_POWER_SUPPLY_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_POWER_SUPPLY_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_POWER_SUPPLY_RQST_FAIL_BYTE = 2,
+ SES_CTRL_POWER_SUPPLY_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_POWER_SUPPLY_RQST_FAIL_SHIFT = 6,
+
+ SES_CTRL_POWER_SUPPLY_RQST_ON_BYTE = 2,
+ SES_CTRL_POWER_SUPPLY_RQST_ON_MASK = 0x20,
+ SES_CTRL_POWER_SUPPLY_RQST_ON_SHIFT = 5
+};
+
+#define GEN_SES_CTRL_POWER_SUPPLY_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_power_supply, SES_CTRL_POWER_SUPPLY, LCASE, UCASE)
+GEN_SES_CTRL_POWER_SUPPLY_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_POWER_SUPPLY_ACCESSORS(rqst_fail, RQST_FAIL)
+GEN_SES_CTRL_POWER_SUPPLY_ACCESSORS(rqst_on, RQST_ON)
+#undef GEN_SES_CTRL_POWER_SUPPLY_ACCESSORS
+
+/*-------------------------- Cooling Control Element -------------------------*/
+struct ses_ctrl_cooling {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_cooling_field_data {
+ SES_CTRL_COOLING_RQST_IDENT_BYTE = 0,
+ SES_CTRL_COOLING_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_COOLING_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_COOLING_RQST_FAIL_BYTE = 2,
+ SES_CTRL_COOLING_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_COOLING_RQST_FAIL_SHIFT = 6,
+
+ SES_CTRL_COOLING_RQST_ON_BYTE = 2,
+ SES_CTRL_COOLING_RQST_ON_MASK = 0x20,
+ SES_CTRL_COOLING_RQST_ON_SHIFT = 5,
+
+ SES_CTRL_COOLING_RQSTED_SPEED_CODE_BYTE = 2,
+ SES_CTRL_COOLING_RQSTED_SPEED_CODE_MASK = 0x07,
+ SES_CTRL_COOLING_RQSTED_SPEED_CODE_SHIFT = 2,
+ SES_CTRL_COOLING_RQSTED_SPEED_CODE_UNCHANGED = 0x00,
+ SES_CTRL_COOLING_RQSTED_SPEED_CODE_LOWEST = 0x01,
+ SES_CTRL_COOLING_RQSTED_SPEED_CODE_HIGHEST = 0x07
+};
+
+#define GEN_SES_CTRL_COOLING_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_cooling, SES_CTRL_COOLING, LCASE, UCASE)
+GEN_SES_CTRL_COOLING_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_COOLING_ACCESSORS(rqst_fail, RQST_FAIL)
+GEN_SES_CTRL_COOLING_ACCESSORS(rqst_on, RQST_ON)
+GEN_SES_CTRL_COOLING_ACCESSORS(rqsted_speed_code, RQSTED_SPEED_CODE)
+#undef GEN_SES_CTRL_COOLING_ACCESSORS
+
+/*-------------------- Temperature Sensor Control Element --------------------*/
+struct ses_ctrl_temp_sensor {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_temp_sensor_field_data {
+ SES_CTRL_TEMP_SENSOR_RQST_IDENT_BYTE = 0,
+ SES_CTRL_TEMP_SENSOR_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_TEMP_SENSOR_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_TEMP_SENSOR_RQST_FAIL_BYTE = 0,
+ SES_CTRL_TEMP_SENSOR_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_TEMP_SENSOR_RQST_FAIL_SHIFT = 6
+};
+
+#define GEN_SES_CTRL_TEMP_SENSOR_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_temp_sensor, SES_CTRL_TEMP_SENSOR, LCASE, UCASE)
+GEN_SES_CTRL_TEMP_SENSOR_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_TEMP_SENSOR_ACCESSORS(rqst_fail, RQST_FAIL)
+#undef GEN_SES_CTRL_TEMP_SENSOR_ACCESSORS
+
+/*------------------------- Door Lock Control Element ------------------------*/
+struct ses_ctrl_door_lock {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_door_lock_field_data {
+ SES_CTRL_DOOR_LOCK_RQST_IDENT_BYTE = 0,
+ SES_CTRL_DOOR_LOCK_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_DOOR_LOCK_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_DOOR_LOCK_RQST_FAIL_BYTE = 0,
+ SES_CTRL_DOOR_LOCK_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_DOOR_LOCK_RQST_FAIL_SHIFT = 6,
+
+ SES_CTRL_DOOR_LOCK_UNLOCK_BYTE = 2,
+ SES_CTRL_DOOR_LOCK_UNLOCK_MASK = 0x01,
+ SES_CTRL_DOOR_LOCK_UNLOCK_SHIFT = 0
+};
+
+#define GEN_SES_CTRL_DOOR_LOCK_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_door_lock, SES_CTRL_DOOR_LOCK, LCASE, UCASE)
+GEN_SES_CTRL_DOOR_LOCK_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_DOOR_LOCK_ACCESSORS(rqst_fail, RQST_FAIL)
+GEN_SES_CTRL_DOOR_LOCK_ACCESSORS(unlock, UNLOCK)
+#undef GEN_SES_CTRL_DOOR_LOCK_ACCESSORS
+
+/*----------------------- Audible Alarm Control Element ----------------------*/
+struct ses_ctrl_audible_alarm {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_audible_alarm_field_data {
+ SES_CTRL_AUDIBLE_ALARM_RQST_IDENT_BYTE = 0,
+ SES_CTRL_AUDIBLE_ALARM_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_AUDIBLE_ALARM_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_AUDIBLE_ALARM_RQST_FAIL_BYTE = 0,
+ SES_CTRL_AUDIBLE_ALARM_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_AUDIBLE_ALARM_RQST_FAIL_SHIFT = 6,
+
+ SES_CTRL_AUDIBLE_ALARM_SET_MUTE_BYTE = 2,
+ SES_CTRL_AUDIBLE_ALARM_SET_MUTE_MASK = 0x40,
+ SES_CTRL_AUDIBLE_ALARM_SET_MUTE_SHIFT = 6,
+
+ SES_CTRL_AUDIBLE_ALARM_SET_REMIND_BYTE = 2,
+ SES_CTRL_AUDIBLE_ALARM_SET_REMIND_MASK = 0x10,
+ SES_CTRL_AUDIBLE_ALARM_SET_REMIND_SHIFT = 4,
+
+ SES_CTRL_AUDIBLE_ALARM_TONE_CONTROL_BYTE = 2,
+ SES_CTRL_AUDIBLE_ALARM_TONE_CONTROL_MASK = 0x0F,
+ SES_CTRL_AUDIBLE_ALARM_TONE_CONTROL_SHIFT = 0,
+ SES_CTRL_AUDIBLE_ALARM_TONE_CONTROL_INFO = 0x08,
+ SES_CTRL_AUDIBLE_ALARM_TONE_CONTROL_NON_CRIT = 0x04,
+ SES_CTRL_AUDIBLE_ALARM_TONE_CONTROL_CRIT = 0x02,
+ SES_CTRL_AUDIBLE_ALARM_TONE_CONTROL_UNRECOV = 0x01
+};
+
+#define GEN_SES_CTRL_AUDIBLE_ALARM_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_audible_alarm, SES_CTRL_AUDIBLE_ALARM, LCASE, UCASE)
+GEN_SES_CTRL_AUDIBLE_ALARM_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_AUDIBLE_ALARM_ACCESSORS(rqst_fail, RQST_FAIL)
+GEN_SES_CTRL_AUDIBLE_ALARM_ACCESSORS(set_mute, SET_MUTE)
+GEN_SES_CTRL_AUDIBLE_ALARM_ACCESSORS(set_remind, SET_REMIND)
+GEN_SES_CTRL_AUDIBLE_ALARM_ACCESSORS(tone_control, TONE_CONTROL)
+#undef GEN_SES_CTRL_AUDIBLE_ALARM_ACCESSORS
+
+/*--------- Enclosure Services Controller Electronics Control Element --------*/
+struct ses_ctrl_ecc_electronics {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_ecc_electronics_field_data {
+ SES_CTRL_ECC_ELECTRONICS_RQST_IDENT_BYTE = 0,
+ SES_CTRL_ECC_ELECTRONICS_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_ECC_ELECTRONICS_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_ECC_ELECTRONICS_RQST_FAIL_BYTE = 0,
+ SES_CTRL_ECC_ELECTRONICS_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_ECC_ELECTRONICS_RQST_FAIL_SHIFT = 6,
+
+ SES_CTRL_ECC_ELECTRONICS_SELECT_ELEMENT_BYTE = 1,
+ SES_CTRL_ECC_ELECTRONICS_SELECT_ELEMENT_MASK = 0x01,
+ SES_CTRL_ECC_ELECTRONICS_SELECT_ELEMENT_SHIFT = 0
+};
+
+#define GEN_SES_CTRL_ECC_ELECTRONICS_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_ecc_electronics, SES_CTRL_ECC_ELECTRONICS, \
+ LCASE, UCASE)
+GEN_SES_CTRL_ECC_ELECTRONICS_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_ECC_ELECTRONICS_ACCESSORS(rqst_fail, RQST_FAIL)
+GEN_SES_CTRL_ECC_ELECTRONICS_ACCESSORS(select_element, SELECT_ELEMENT)
+#undef GEN_SES_CTRL_ECC_ELECTRONICS_ACCESSORS
+
+/*----------- SCSI Services Controller Electronics Control Element -----------*/
+struct ses_ctrl_scc_electronics {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_scc_electronics_field_data {
+ SES_CTRL_SCC_ELECTRONICS_RQST_IDENT_BYTE = 0,
+ SES_CTRL_SCC_ELECTRONICS_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_SCC_ELECTRONICS_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_SCC_ELECTRONICS_RQST_FAIL_BYTE = 0,
+ SES_CTRL_SCC_ELECTRONICS_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_SCC_ELECTRONICS_RQST_FAIL_SHIFT = 6
+};
+
+#define GEN_SES_CTRL_SCC_ELECTRONICS_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_scc_electronics, SES_CTRL_SCC_ELECTRONICS, \
+ LCASE, UCASE)
+GEN_SES_CTRL_SCC_ELECTRONICS_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_SCC_ELECTRONICS_ACCESSORS(rqst_fail, RQST_FAIL)
+#undef GEN_SES_CTRL_SCC_ELECTRONICS_ACCESSORS
+
+/*--------------------- Nonvolatile Cache Control Element --------------------*/
+struct ses_ctrl_nv_cache {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_nv_cache_field_data {
+ SES_CTRL_NV_CACHE_RQST_IDENT_BYTE = 0,
+ SES_CTRL_NV_CACHE_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_NV_CACHE_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_NV_CACHE_RQST_FAIL_BYTE = 0,
+ SES_CTRL_NV_CACHE_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_NV_CACHE_RQST_FAIL_SHIFT = 6
+};
+
+#define GEN_SES_CTRL_NV_CACHE_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_nv_cache, SES_CTRL_NV_CACHE, LCASE, UCASE)
+GEN_SES_CTRL_NV_CACHE_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_NV_CACHE_ACCESSORS(rqst_fail, RQST_FAIL)
+#undef GEN_SES_CTRL_NV_CACHE_ACCESSORS
+
+/*----------------- Invalid Operation Reason Control Element -----------------*/
+struct ses_ctrl_invalid_op_reason {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+/* There are no element specific fields currently defined in the spec. */
+
+/*--------------- Uninterruptible Power Supply Control Element ---------------*/
+struct ses_ctrl_ups {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_ups_field_data {
+ SES_CTRL_UPS_RQST_IDENT_BYTE = 2,
+ SES_CTRL_UPS_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_UPS_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_UPS_RQST_FAIL_BYTE = 2,
+ SES_CTRL_UPS_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_UPS_RQST_FAIL_SHIFT = 6
+};
+
+#define GEN_SES_CTRL_UPS_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_ups, SES_CTRL_UPS, LCASE, UCASE)
+GEN_SES_CTRL_UPS_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_UPS_ACCESSORS(rqst_fail, RQST_FAIL)
+#undef GEN_SES_CTRL_UPS_ACCESSORS
+
+/*-------------------------- Display Control Element -------------------------*/
+struct ses_ctrl_display {
+ struct ses_ctrl_common common;
+ uint8_t bytes[1];
+ uint8_t display_character[2];
+};
+
+enum ses_ctrl_display_field_data {
+ SES_CTRL_DISPLAY_RQST_IDENT_BYTE = 0,
+ SES_CTRL_DISPLAY_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_DISPLAY_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_DISPLAY_RQST_FAIL_BYTE = 0,
+ SES_CTRL_DISPLAY_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_DISPLAY_RQST_FAIL_SHIFT = 6,
+
+ SES_CTRL_DISPLAY_DISPLAY_MODE_BYTE = 0,
+ SES_CTRL_DISPLAY_DISPLAY_MODE_MASK = 0x03,
+ SES_CTRL_DISPLAY_DISPLAY_MODE_SHIFT = 6,
+ SES_CTRL_DISPLAY_DISPLAY_MODE_UNCHANGED = 0x0,
+ SES_CTRL_DISPLAY_DISPLAY_MODE_ESP = 0x1,
+ SES_CTRL_DISPLAY_DISPLAY_MODE_DC_FIELD = 0x2
+};
+
+#define GEN_SES_CTRL_DISPLAY_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_display, SES_CTRL_DISPLAY, LCASE, UCASE)
+GEN_SES_CTRL_DISPLAY_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_DISPLAY_ACCESSORS(rqst_fail, RQST_FAIL)
+GEN_SES_CTRL_DISPLAY_ACCESSORS(display_mode, DISPLAY_MODE)
+#undef GEN_SES_CTRL_DISPLAY_ACCESSORS
+
+/*----------------------- Key Pad Entry Control Element ----------------------*/
+struct ses_ctrl_key_pad_entry {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_key_pad_entry_field_data {
+ SES_CTRL_KEY_PAD_ENTRY_RQST_IDENT_BYTE = 0,
+ SES_CTRL_KEY_PAD_ENTRY_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_KEY_PAD_ENTRY_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_KEY_PAD_ENTRY_RQST_FAIL_BYTE = 0,
+ SES_CTRL_KEY_PAD_ENTRY_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_KEY_PAD_ENTRY_RQST_FAIL_SHIFT = 6
+};
+
+#define GEN_SES_CTRL_KEY_PAD_ENTRY_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_key_pad_entry, SES_CTRL_KEY_PAD_ENTRY, LCASE, UCASE)
+GEN_SES_CTRL_KEY_PAD_ENTRY_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_KEY_PAD_ENTRY_ACCESSORS(rqst_fail, RQST_FAIL)
+#undef GEN_SES_CTRL_KEY_PAD_ENTRY_ACCESSORS
+
+/*------------------------- Enclosure Control Element ------------------------*/
+struct ses_ctrl_enclosure {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_enclosure_field_data {
+ SES_CTRL_ENCLOSURE_RQST_IDENT_BYTE = 0,
+ SES_CTRL_ENCLOSURE_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_ENCLOSURE_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_ENCLOSURE_POWER_CYCLE_RQST_BYTE = 1,
+ SES_CTRL_ENCLOSURE_POWER_CYCLE_RQST_MASK = 0xC0,
+ SES_CTRL_ENCLOSURE_POWER_CYCLE_RQST_SHIFT = 6,
+ SES_CTRL_ENCLOSURE_POWER_CYCLE_RQST_NONE = 0x0,
+ SES_CTRL_ENCLOSURE_POWER_CYCLE_RQST_AFTER_DELAY = 0x1,
+ SES_CTRL_ENCLOSURE_POWER_CYCLE_RQST_CANCEL = 0x2,
+
+ SES_CTRL_ENCLOSURE_POWER_CYCLE_DELAY_BYTE = 1,
+ SES_CTRL_ENCLOSURE_POWER_CYCLE_DELAY_MASK = 0x3F,
+ SES_CTRL_ENCLOSURE_POWER_CYCLE_DELAY_SHIFT = 0,
+ SES_CTRL_ENCLOSURE_POWER_CYCLE_DELAY_MAX = 60,/*minutes*/
+
+ SES_CTRL_ENCLOSURE_POWER_OFF_DURATION_BYTE = 2,
+ SES_CTRL_ENCLOSURE_POWER_OFF_DURATION_MASK = 0xFC,
+ SES_CTRL_ENCLOSURE_POWER_OFF_DURATION_SHIFT = 2,
+ SES_CTRL_ENCLOSURE_POWER_OFF_DURATION_MAX_AUTO = 60,
+ SES_CTRL_ENCLOSURE_POWER_OFF_DURATION_MANUAL = 63,
+
+ SES_CTRL_ENCLOSURE_RQST_FAIL_BYTE = 2,
+ SES_CTRL_ENCLOSURE_RQST_FAIL_MASK = 0x02,
+ SES_CTRL_ENCLOSURE_RQST_FAIL_SHIFT = 1,
+
+ SES_CTRL_ENCLOSURE_RQST_WARN_BYTE = 2,
+ SES_CTRL_ENCLOSURE_RQST_WARN_MASK = 0x01,
+ SES_CTRL_ENCLOSURE_RQST_WARN_SHIFT = 0
+};
+
+#define GEN_SES_CTRL_ENCLOSURE_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_enclosure, SES_CTRL_ENCLOSURE, LCASE, UCASE)
+GEN_SES_CTRL_ENCLOSURE_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_ENCLOSURE_ACCESSORS(power_cycle_rqst, POWER_CYCLE_RQST)
+GEN_SES_CTRL_ENCLOSURE_ACCESSORS(power_cycle_delay, POWER_CYCLE_DELAY)
+GEN_SES_CTRL_ENCLOSURE_ACCESSORS(power_off_duration, POWER_OFF_DURATION)
+GEN_SES_CTRL_ENCLOSURE_ACCESSORS(rqst_fail, RQST_FAIL)
+GEN_SES_CTRL_ENCLOSURE_ACCESSORS(rqst_warn, RQST_WARN)
+#undef GEN_SES_CTRL_ENCLOSURE_ACCESSORS
+
+/*------------------- SCSI Port/Transceiver Control Element ------------------*/
+struct ses_ctrl_scsi_port_or_xcvr {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_scsi_port_or_xcvr_field_data {
+ SES_CTRL_SCSI_PORT_OR_XCVR_RQST_IDENT_BYTE = 0,
+ SES_CTRL_SCSI_PORT_OR_XCVR_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_SCSI_PORT_OR_XCVR_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_SCSI_PORT_OR_XCVR_RQST_FAIL_BYTE = 0,
+ SES_CTRL_SCSI_PORT_OR_XCVR_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_SCSI_PORT_OR_XCVR_RQST_FAIL_SHIFT = 6,
+
+ SES_CTRL_SCSI_PORT_OR_XCVR_DISABLE_BYTE = 2,
+ SES_CTRL_SCSI_PORT_OR_XCVR_DISABLE_MASK = 0x10,
+ SES_CTRL_SCSI_PORT_OR_XCVR_DISABLE_SHIFT = 4
+};
+
+#define GEN_SES_CTRL_SCSI_PORT_OR_XCVR_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_scsi_port_or_xcvr, SES_CTRL_SCSI_PORT_OR_XCVR,\
+ LCASE, UCASE)
+GEN_SES_CTRL_SCSI_PORT_OR_XCVR_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_SCSI_PORT_OR_XCVR_ACCESSORS(disable, DISABLE)
+GEN_SES_CTRL_SCSI_PORT_OR_XCVR_ACCESSORS(rqst_fail, RQST_FAIL)
+#undef GEN_SES_CTRL_SCSI_PORT_OR_XCVR_ACCESSORS
+
+/*------------------------- Language Control Element -------------------------*/
+struct ses_ctrl_language {
+ struct ses_ctrl_common common;
+ uint8_t bytes[1];
+ uint8_t language_code[2];
+};
+
+enum ses_ctrl_language_field_data {
+ SES_CTRL_LANGUAGE_RQST_IDENT_BYTE = 0,
+ SES_CTRL_LANGUAGE_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_LANGUAGE_RQST_IDENT_SHIFT = 7
+};
+
+#define GEN_SES_CTRL_LANGUAGE_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_language, SES_CTRL_LANGUAGE, LCASE, UCASE)
+GEN_SES_CTRL_LANGUAGE_ACCESSORS(rqst_ident, RQST_IDENT)
+#undef GEN_SES_CTRL_LANGUAGE_ACCESSORS
+
+/*-------------------- Communication Port Control Element --------------------*/
+struct ses_ctrl_comm_port {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_comm_port_field_data {
+ SES_CTRL_COMM_PORT_RQST_IDENT_BYTE = 0,
+ SES_CTRL_COMM_PORT_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_COMM_PORT_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_COMM_PORT_RQST_FAIL_BYTE = 0,
+ SES_CTRL_COMM_PORT_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_COMM_PORT_RQST_FAIL_SHIFT = 6,
+
+ SES_CTRL_COMM_PORT_DISABLE_BYTE = 2,
+ SES_CTRL_COMM_PORT_DISABLE_MASK = 0x01,
+ SES_CTRL_COMM_PORT_DISABLE_SHIFT = 0
+};
+
+#define GEN_SES_CTRL_COMM_PORT_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_comm_port, SES_CTRL_COMM_PORT, LCASE, UCASE)
+GEN_SES_CTRL_COMM_PORT_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_COMM_PORT_ACCESSORS(rqst_fail, RQST_FAIL)
+GEN_SES_CTRL_COMM_PORT_ACCESSORS(disable, DISABLE)
+#undef GEN_SES_CTRL_COMM_PORT_ACCESSORS
+
+/*---------------------- Voltage Sensor Control Element ----------------------*/
+struct ses_ctrl_voltage_sensor {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_voltage_sensor_field_data {
+ SES_CTRL_VOLTAGE_SENSOR_RQST_IDENT_BYTE = 0,
+ SES_CTRL_VOLTAGE_SENSOR_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_VOLTAGE_SENSOR_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_VOLTAGE_SENSOR_RQST_FAIL_BYTE = 0,
+ SES_CTRL_VOLTAGE_SENSOR_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_VOLTAGE_SENSOR_RQST_FAIL_SHIFT = 6
+};
+
+#define GEN_SES_CTRL_VOLTAGE_SENSOR_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_voltage_sensor, SES_CTRL_VOLTAGE_SENSOR, \
+ LCASE, UCASE)
+GEN_SES_CTRL_VOLTAGE_SENSOR_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_VOLTAGE_SENSOR_ACCESSORS(rqst_fail, RQST_FAIL)
+#undef GEN_SES_CTRL_VOLTAGE_SENSOR_ACCESSORS
+
+/*---------------------- Current Sensor Control Element ----------------------*/
+struct ses_ctrl_current_sensor {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_current_sensor_field_data {
+ SES_CTRL_CURRENT_SENSOR_RQST_IDENT_BYTE = 0,
+ SES_CTRL_CURRENT_SENSOR_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_CURRENT_SENSOR_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_CURRENT_SENSOR_RQST_FAIL_BYTE = 0,
+ SES_CTRL_CURRENT_SENSOR_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_CURRENT_SENSOR_RQST_FAIL_SHIFT = 6
+};
+
+#define GEN_SES_CTRL_CURRENT_SENSOR_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_current_sensor, SES_CTRL_CURRENT_SENSOR, \
+ LCASE, UCASE)
+GEN_SES_CTRL_CURRENT_SENSOR_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_CURRENT_SENSOR_ACCESSORS(rqst_fail, RQST_FAIL)
+#undef GEN_SES_CTRL_CURRENT_SENSOR_ACCESSORS
+
+/*--------------------- SCSI Target Port Control Element ---------------------*/
+struct ses_ctrl_target_port {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_scsi_target_port_field_data {
+ SES_CTRL_TARGET_PORT_RQST_IDENT_BYTE = 0,
+ SES_CTRL_TARGET_PORT_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_TARGET_PORT_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_TARGET_PORT_RQST_FAIL_BYTE = 0,
+ SES_CTRL_TARGET_PORT_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_TARGET_PORT_RQST_FAIL_SHIFT = 6,
+
+ SES_CTRL_TARGET_PORT_ENABLE_BYTE = 2,
+ SES_CTRL_TARGET_PORT_ENABLE_MASK = 0x01,
+ SES_CTRL_TARGET_PORT_ENABLE_SHIFT = 0
+};
+
+#define GEN_SES_CTRL_TARGET_PORT_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_target_port, SES_CTRL_TARGET_PORT, LCASE, UCASE)
+GEN_SES_CTRL_TARGET_PORT_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_TARGET_PORT_ACCESSORS(rqst_fail, RQST_FAIL)
+GEN_SES_CTRL_TARGET_PORT_ACCESSORS(enable, ENABLE)
+#undef GEN_SES_CTRL_TARGET_PORT_ACCESSORS
+
+/*-------------------- SCSI Initiator Port Control Element -------------------*/
+struct ses_ctrl_initiator_port {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_initiator_port_field_data {
+ SES_CTRL_INITIATOR_PORT_RQST_IDENT_BYTE = 0,
+ SES_CTRL_INITIATOR_PORT_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_INITIATOR_PORT_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_INITIATOR_PORT_RQST_FAIL_BYTE = 0,
+ SES_CTRL_INITIATOR_PORT_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_INITIATOR_PORT_RQST_FAIL_SHIFT = 6,
+
+ SES_CTRL_INITIATOR_PORT_ENABLE_BYTE = 2,
+ SES_CTRL_INITIATOR_PORT_ENABLE_MASK = 0x01,
+ SES_CTRL_INITIATOR_PORT_ENABLE_SHIFT = 0
+};
+
+#define GEN_SES_CTRL_INITIATOR_PORT_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_initiator_port, SES_CTRL_INITIATOR_PORT, \
+ LCASE, UCASE)
+GEN_SES_CTRL_INITIATOR_PORT_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_INITIATOR_PORT_ACCESSORS(rqst_fail, RQST_FAIL)
+GEN_SES_CTRL_INITIATOR_PORT_ACCESSORS(enable, ENABLE)
+#undef GEN_SES_CTRL_INITIATOR_PORT_ACCESSORS
+
+/*-------------------- Simple Subenclosure Control Element -------------------*/
+struct ses_ctrl_simple_subenc {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_simple_subenc_field_data {
+ SES_CTRL_SIMPlE_SUBSES_RQST_IDENT_BYTE = 0,
+ SES_CTRL_SIMPlE_SUBSES_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_SIMPlE_SUBSES_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_SIMPlE_SUBSES_RQST_FAIL_BYTE = 0,
+ SES_CTRL_SIMPlE_SUBSES_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_SIMPlE_SUBSES_RQST_FAIL_SHIFT = 6
+};
+
+#define GEN_SES_CTRL_SIMPlE_SUBSES_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_simple_subenc, SES_CTRL_SIMPlE_SUBSES, \
+ LCASE, UCASE)
+GEN_SES_CTRL_SIMPlE_SUBSES_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_SIMPlE_SUBSES_ACCESSORS(rqst_fail, RQST_FAIL)
+#undef GEN_SES_CTRL_SIMPlE_SUBSES_ACCESSORS
+
+/*----------------------- SAS Expander Control Element -----------------------*/
+struct ses_ctrl_sas_expander {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_sas_expander_field_data {
+ SES_CTRL_SAS_EXPANDER_RQST_IDENT_BYTE = 0,
+ SES_CTRL_SAS_EXPANDER_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_SAS_EXPANDER_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_SAS_EXPANDER_RQST_FAIL_BYTE = 0,
+ SES_CTRL_SAS_EXPANDER_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_SAS_EXPANDER_RQST_FAIL_SHIFT = 6
+};
+
+#define GEN_SES_CTRL_SAS_EXPANDER_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_sas_expander, SES_CTRL_SAS_EXPANDER, LCASE, UCASE)
+GEN_SES_CTRL_SAS_EXPANDER_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_SAS_EXPANDER_ACCESSORS(rqst_fail, RQST_FAIL)
+#undef GEN_SES_CTRL_SAS_EXPANDER_ACCESSORS
+
+/*----------------------- SAS Connector Control Element ----------------------*/
+struct ses_ctrl_sas_connector {
+ struct ses_ctrl_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_ctrl_sas_connector_field_data {
+ SES_CTRL_SAS_CONNECTOR_RQST_IDENT_BYTE = 0,
+ SES_CTRL_SAS_CONNECTOR_RQST_IDENT_MASK = 0x80,
+ SES_CTRL_SAS_CONNECTOR_RQST_IDENT_SHIFT = 7,
+
+ SES_CTRL_SAS_CONNECTOR_RQST_FAIL_BYTE = 2,
+ SES_CTRL_SAS_CONNECTOR_RQST_FAIL_MASK = 0x40,
+ SES_CTRL_SAS_CONNECTOR_RQST_FAIL_SHIFT = 6
+};
+
+#define GEN_SES_CTRL_SAS_CONNECTOR_ACCESSORS(LCASE, UCASE) \
+ GEN_ACCESSORS(ses_ctrl_sas_connector, SES_CTRL_SAS_CONNECTOR, \
+ LCASE, UCASE)
+GEN_SES_CTRL_SAS_CONNECTOR_ACCESSORS(rqst_ident, RQST_IDENT)
+GEN_SES_CTRL_SAS_CONNECTOR_ACCESSORS(rqst_fail, RQST_FAIL)
+#undef GEN_SES_CTRL_SAS_CONNECTOR_ACCESSORS
+
+/*------------------------- Universal Control Element ------------------------*/
+union ses_ctrl_element {
+ struct ses_ctrl_common common;
+ struct ses_ctrl_dev_slot dev_slot;
+ struct ses_ctrl_array_dev_slot array_dev_slot;
+ struct ses_ctrl_power_supply power_supply;
+ struct ses_ctrl_cooling cooling;
+ struct ses_ctrl_temp_sensor temp_sensor;
+ struct ses_ctrl_door_lock door_lock;
+ struct ses_ctrl_audible_alarm audible_alarm;
+ struct ses_ctrl_ecc_electronics ecc_electronics;
+ struct ses_ctrl_scc_electronics scc_electronics;
+ struct ses_ctrl_nv_cache nv_cache;
+ struct ses_ctrl_invalid_op_reason invalid_op_reason;
+ struct ses_ctrl_ups ups;
+ struct ses_ctrl_display display;
+ struct ses_ctrl_key_pad_entry key_pad_entry;
+ struct ses_ctrl_scsi_port_or_xcvr scsi_port_or_xcvr;
+ struct ses_ctrl_language language;
+ struct ses_ctrl_comm_port comm_port;
+ struct ses_ctrl_voltage_sensor voltage_sensor;
+ struct ses_ctrl_current_sensor current_sensor;
+ struct ses_ctrl_target_port target_port;
+ struct ses_ctrl_initiator_port initiator_port;
+ struct ses_ctrl_simple_subenc simple_subenc;
+ struct ses_ctrl_sas_expander sas_expander;
+ struct ses_ctrl_sas_connector sas_connector;
+};
+
+/*--------------------- SCSI SES Control Diagnostic Page ---------------------*/
+struct ses_ctrl_page {
+ struct ses_page_hdr hdr;
+ union ses_ctrl_element elements[];
+};
+
+enum ses_ctrl_page_field_data {
+ SES_CTRL_PAGE_INFO_MASK = 0x08,
+ SES_CTRL_PAGE_INFO_SHIFT = 3,
+
+ SES_CTRL_PAGE_NON_CRIT_MASK = 0x04,
+ SES_CTRL_PAGE_NON_CRIT_SHIFT = 2,
+
+ SES_CTRL_PAGE_CRIT_MASK = 0x02,
+ SES_CTRL_PAGE_CRIT_SHIFT = 1,
+
+ SES_CTRL_PAGE_UNRECOV_MASK = 0x01,
+ SES_CTRL_PAGE_UNRECOV_SHIFT = 0
+};
+
+#define GEN_SES_CTRL_PAGE_ACCESSORS(LCASE, UCASE) \
+ GEN_HDR_ACCESSORS(ses_ctrl_page, SES_CTRL_PAGE, LCASE, UCASE)
+
+GEN_SES_CTRL_PAGE_ACCESSORS(info, INFO)
+GEN_SES_CTRL_PAGE_ACCESSORS(non_crit, NON_CRIT)
+GEN_SES_CTRL_PAGE_ACCESSORS(crit, CRIT)
+GEN_SES_CTRL_PAGE_ACCESSORS(unrecov, UNRECOV)
+#undef GEN_SES_CTRL_PAGE_ACCESSORS
+
+/*================= SCSI SES Status Diagnostic Page Structures ===============*/
+struct ses_status_common {
+ uint8_t bytes[1];
+};
+
+enum ses_status_common_field_data {
+ SES_STATUS_COMMON_PRDFAIL_BYTE = 0,
+ SES_STATUS_COMMON_PRDFAIL_MASK = 0x40,
+ SES_STATUS_COMMON_PRDFAIL_SHIFT = 6,
+
+ SES_STATUS_COMMON_DISABLED_BYTE = 0,
+ SES_STATUS_COMMON_DISABLED_MASK = 0x20,
+ SES_STATUS_COMMON_DISABLED_SHIFT = 5,
+
+ SES_STATUS_COMMON_SWAP_BYTE = 0,
+ SES_STATUS_COMMON_SWAP_MASK = 0x10,
+ SES_STATUS_COMMON_SWAP_SHIFT = 4,
+
+ SES_STATUS_COMMON_ELEMENT_STATUS_CODE_BYTE = 0,
+ SES_STATUS_COMMON_ELEMENT_STATUS_CODE_MASK = 0x0F,
+ SES_STATUS_COMMON_ELEMENT_STATUS_CODE_SHIFT = 0
+};
+
+#define GEN_SES_STATUS_COMMON_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_common, SES_STATUS_COMMON, LCASE, UCASE)
+
+GEN_SES_STATUS_COMMON_ACCESSORS(prdfail, PRDFAIL)
+GEN_SES_STATUS_COMMON_ACCESSORS(disabled, DISABLED)
+GEN_SES_STATUS_COMMON_ACCESSORS(swap, SWAP)
+GEN_SES_STATUS_COMMON_ACCESSORS(element_status_code, ELEMENT_STATUS_CODE)
+#undef GEN_SES_STATUS_COMMON_ACCESSORS
+
+/*------------------------- Device Slot Status Element -----------------------*/
+struct ses_status_dev_slot {
+ struct ses_status_common common;
+ uint8_t slot_address;
+ uint8_t bytes[2];
+};
+
+enum ses_status_dev_slot_field_data {
+ SES_STATUS_DEV_SLOT_APP_CLIENT_BYPED_A_BYTE = 0,
+ SES_STATUS_DEV_SLOT_APP_CLIENT_BYPED_A_MASK = 0x80,
+ SES_STATUS_DEV_SLOT_APP_CLIENT_BYPED_A_SHIFT = 7,
+
+ SES_STATUS_DEV_SLOT_DO_NOT_REMOVE_BYTE = 0,
+ SES_STATUS_DEV_SLOT_DO_NOT_REMOVE_MASK = 0x40,
+ SES_STATUS_DEV_SLOT_DO_NOT_REMOVE_SHIFT = 6,
+
+ SES_STATUS_DEV_SLOT_ENCLOSURE_BYPED_A_BYTE = 0,
+ SES_STATUS_DEV_SLOT_ENCLOSURE_BYPED_A_MASK = 0x20,
+ SES_STATUS_DEV_SLOT_ENCLOSURE_BYPED_A_SHIFT = 5,
+
+ SES_STATUS_DEV_SLOT_ENCLOSURE_BYPED_B_BYTE = 0,
+ SES_STATUS_DEV_SLOT_ENCLOSURE_BYPED_B_MASK = 0x10,
+ SES_STATUS_DEV_SLOT_ENCLOSURE_BYPED_B_SHIFT = 4,
+
+ SES_STATUS_DEV_SLOT_INSERT_READY_BYTE = 0,
+ SES_STATUS_DEV_SLOT_INSERT_READY_MASK = 0x08,
+ SES_STATUS_DEV_SLOT_INSERT_READY_SHIFT = 3,
+
+ SES_STATUS_DEV_SLOT_REMOVE_BYTE = 0,
+ SES_STATUS_DEV_SLOT_REMOVE_MASK = 0x04,
+ SES_STATUS_DEV_SLOT_REMOVE_SHIFT = 2,
+
+ SES_STATUS_DEV_SLOT_IDENT_BYTE = 0,
+ SES_STATUS_DEV_SLOT_IDENT_MASK = 0x02,
+ SES_STATUS_DEV_SLOT_IDENT_SHIFT = 1,
+
+ SES_STATUS_DEV_SLOT_REPORT_BYTE = 0,
+ SES_STATUS_DEV_SLOT_REPORT_MASK = 0x01,
+ SES_STATUS_DEV_SLOT_REPORT_SHIFT = 0,
+
+ SES_STATUS_DEV_SLOT_APP_CLIENT_BYPED_B_BYTE = 1,
+ SES_STATUS_DEV_SLOT_APP_CLIENT_BYPED_B_MASK = 0x80,
+ SES_STATUS_DEV_SLOT_APP_CLIENT_BYPED_B_SHIFT = 7,
+
+ SES_STATUS_DEV_SLOT_FAULT_SENSED_BYTE = 1,
+ SES_STATUS_DEV_SLOT_FAULT_SENSED_MASK = 0x40,
+ SES_STATUS_DEV_SLOT_FAULT_SENSED_SHIFT = 6,
+
+ SES_STATUS_DEV_SLOT_FAULT_REQUESTED_BYTE = 1,
+ SES_STATUS_DEV_SLOT_FAULT_REQUESTED_MASK = 0x20,
+ SES_STATUS_DEV_SLOT_FAULT_REQUESTED_SHIFT = 5,
+
+ SES_STATUS_DEV_SLOT_DEVICE_OFF_BYTE = 1,
+ SES_STATUS_DEV_SLOT_DEVICE_OFF_MASK = 0x10,
+ SES_STATUS_DEV_SLOT_DEVICE_OFF_SHIFT = 4,
+
+ SES_STATUS_DEV_SLOT_BYPED_A_BYTE = 1,
+ SES_STATUS_DEV_SLOT_BYPED_A_MASK = 0x08,
+ SES_STATUS_DEV_SLOT_BYPED_A_SHIFT = 3,
+
+ SES_STATUS_DEV_SLOT_BYPED_B_BYTE = 1,
+ SES_STATUS_DEV_SLOT_BYPED_B_MASK = 0x04,
+ SES_STATUS_DEV_SLOT_BYPED_B_SHIFT = 2,
+
+ SES_STATUS_DEV_SLOT_DEVICE_BYPED_A_BYTE = 1,
+ SES_STATUS_DEV_SLOT_DEVICE_BYPED_A_MASK = 0x02,
+ SES_STATUS_DEV_SLOT_DEVICE_BYPED_A_SHIFT = 1,
+
+ SES_STATUS_DEV_SLOT_DEVICE_BYPED_B_BYTE = 1,
+ SES_STATUS_DEV_SLOT_DEVICE_BYPED_B_MASK = 0x01,
+ SES_STATUS_DEV_SLOT_DEVICE_BYPED_B_SHIFT = 0
+};
+#define GEN_SES_STATUS_DEV_SLOT_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_dev_slot, SES_STATUS_DEV_SLOT, LCASE, UCASE)
+
+GEN_SES_STATUS_DEV_SLOT_ACCESSORS(app_client_byped_a, APP_CLIENT_BYPED_A)
+GEN_SES_STATUS_DEV_SLOT_ACCESSORS(do_not_remove, DO_NOT_REMOVE)
+GEN_SES_STATUS_DEV_SLOT_ACCESSORS(enclosure_byped_a, ENCLOSURE_BYPED_A)
+GEN_SES_STATUS_DEV_SLOT_ACCESSORS(enclosure_byped_b, ENCLOSURE_BYPED_B)
+GEN_SES_STATUS_DEV_SLOT_ACCESSORS(insert_ready, INSERT_READY)
+GEN_SES_STATUS_DEV_SLOT_ACCESSORS(remove, REMOVE)
+GEN_SES_STATUS_DEV_SLOT_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_DEV_SLOT_ACCESSORS(report, REPORT)
+GEN_SES_STATUS_DEV_SLOT_ACCESSORS(app_client_byped_b, APP_CLIENT_BYPED_B)
+GEN_SES_STATUS_DEV_SLOT_ACCESSORS(fault_sensed, FAULT_SENSED)
+GEN_SES_STATUS_DEV_SLOT_ACCESSORS(fault_requested, FAULT_REQUESTED)
+GEN_SES_STATUS_DEV_SLOT_ACCESSORS(device_off, DEVICE_OFF)
+GEN_SES_STATUS_DEV_SLOT_ACCESSORS(byped_a, BYPED_A)
+GEN_SES_STATUS_DEV_SLOT_ACCESSORS(byped_b, BYPED_B)
+GEN_SES_STATUS_DEV_SLOT_ACCESSORS(device_byped_a, DEVICE_BYPED_A)
+GEN_SES_STATUS_DEV_SLOT_ACCESSORS(device_byped_b, DEVICE_BYPED_B)
+#undef GEN_SES_STATUS_DEV_SLOT_ACCESSORS
+
+/*---------------------- Array Device Slot Status Element --------------------*/
+struct ses_status_array_dev_slot {
+ struct ses_status_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_status_array_dev_slot_field_data {
+ SES_STATUS_ARRAY_DEV_SLOT_OK_BYTE = 0,
+ SES_STATUS_ARRAY_DEV_SLOT_OK_MASK = 0x80,
+ SES_STATUS_ARRAY_DEV_SLOT_OK_SHIFT = 7,
+
+ SES_STATUS_ARRAY_DEV_SLOT_RSVD_DEVICE_BYTE = 0,
+ SES_STATUS_ARRAY_DEV_SLOT_RSVD_DEVICE_MASK = 0x40,
+ SES_STATUS_ARRAY_DEV_SLOT_RSVD_DEVICE_SHIFT = 6,
+
+ SES_STATUS_ARRAY_DEV_SLOT_HOT_SPARE_BYTE = 0,
+ SES_STATUS_ARRAY_DEV_SLOT_HOT_SPARE_MASK = 0x20,
+ SES_STATUS_ARRAY_DEV_SLOT_HOT_SPARE_SHIFT = 5,
+
+ SES_STATUS_ARRAY_DEV_SLOT_CONS_CHECK_BYTE = 0,
+ SES_STATUS_ARRAY_DEV_SLOT_CONS_CHECK_MASK = 0x10,
+ SES_STATUS_ARRAY_DEV_SLOT_CONS_CHECK_SHIFT = 4,
+
+ SES_STATUS_ARRAY_DEV_SLOT_IN_CRIT_ARRAY_BYTE = 0,
+ SES_STATUS_ARRAY_DEV_SLOT_IN_CRIT_ARRAY_MASK = 0x08,
+ SES_STATUS_ARRAY_DEV_SLOT_IN_CRIT_ARRAY_SHIFT = 3,
+
+ SES_STATUS_ARRAY_DEV_SLOT_IN_FAILED_ARRAY_BYTE = 0,
+ SES_STATUS_ARRAY_DEV_SLOT_IN_FAILED_ARRAY_MASK = 0x04,
+ SES_STATUS_ARRAY_DEV_SLOT_IN_FAILED_ARRAY_SHIFT = 2,
+
+ SES_STATUS_ARRAY_DEV_SLOT_REBUILD_REMAP_BYTE = 0,
+ SES_STATUS_ARRAY_DEV_SLOT_REBUILD_REMAP_MASK = 0x02,
+ SES_STATUS_ARRAY_DEV_SLOT_REBUILD_REMAP_SHIFT = 1,
+
+ SES_STATUS_ARRAY_DEV_SLOT_REBUILD_REMAP_ABORT_BYTE = 0,
+ SES_STATUS_ARRAY_DEV_SLOT_REBUILD_REMAP_ABORT_MASK = 0x01,
+ SES_STATUS_ARRAY_DEV_SLOT_REBUILD_REMAP_ABORT_SHIFT = 0
+
+ /*
+ * The remaining fields are identical to the device
+ * slot element type. Access them through the device slot
+ * element type and its accessors.
+ */
+};
+#define GEN_SES_STATUS_ARRAY_DEV_SLOT_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_array_dev_slot, SES_STATUS_ARRAY_DEV_SLOT, \
+ LCASE, UCASE)
+GEN_SES_STATUS_ARRAY_DEV_SLOT_ACCESSORS(ok, OK)
+GEN_SES_STATUS_ARRAY_DEV_SLOT_ACCESSORS(rsvd_device, RSVD_DEVICE)
+GEN_SES_STATUS_ARRAY_DEV_SLOT_ACCESSORS(hot_spare, HOT_SPARE)
+GEN_SES_STATUS_ARRAY_DEV_SLOT_ACCESSORS(cons_check, CONS_CHECK)
+GEN_SES_STATUS_ARRAY_DEV_SLOT_ACCESSORS(in_crit_array, IN_CRIT_ARRAY)
+GEN_SES_STATUS_ARRAY_DEV_SLOT_ACCESSORS(in_failed_array, IN_FAILED_ARRAY)
+GEN_SES_STATUS_ARRAY_DEV_SLOT_ACCESSORS(rebuild_remap, REBUILD_REMAP)
+GEN_SES_STATUS_ARRAY_DEV_SLOT_ACCESSORS(rebuild_remap_abort,
+ REBUILD_REMAP_ABORT)
+#undef GEN_SES_STATUS_ARRAY_DEV_SLOT_ACCESSORS
+
+/*----------------------- Power Supply Status Element ------------------------*/
+struct ses_status_power_supply {
+ struct ses_status_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_status_power_supply_field_data {
+ SES_STATUS_POWER_SUPPLY_IDENT_BYTE = 0,
+ SES_STATUS_POWER_SUPPLY_IDENT_MASK = 0x80,
+ SES_STATUS_POWER_SUPPLY_IDENT_SHIFT = 7,
+
+ SES_STATUS_POWER_SUPPLY_DC_OVER_VOLTAGE_BYTE = 1,
+ SES_STATUS_POWER_SUPPLY_DC_OVER_VOLTAGE_MASK = 0x08,
+ SES_STATUS_POWER_SUPPLY_DC_OVER_VOLTAGE_SHIFT = 3,
+
+ SES_STATUS_POWER_SUPPLY_DC_UNDER_VOLTAGE_BYTE = 1,
+ SES_STATUS_POWER_SUPPLY_DC_UNDER_VOLTAGE_MASK = 0x04,
+ SES_STATUS_POWER_SUPPLY_DC_UNDER_VOLTAGE_SHIFT = 2,
+
+ SES_STATUS_POWER_SUPPLY_DC_OVER_CURRENT_BYTE = 1,
+ SES_STATUS_POWER_SUPPLY_DC_OVER_CURRENT_MASK = 0x02,
+ SES_STATUS_POWER_SUPPLY_DC_OVER_CURRENT_SHIFT = 1,
+
+ SES_STATUS_POWER_SUPPLY_HOT_SWAP_BYTE = 2,
+ SES_STATUS_POWER_SUPPLY_HOT_SWAP_MASK = 0x80,
+ SES_STATUS_POWER_SUPPLY_HOT_SWAP_SHIFT = 7,
+
+ SES_STATUS_POWER_SUPPLY_FAIL_BYTE = 2,
+ SES_STATUS_POWER_SUPPLY_FAIL_MASK = 0x40,
+ SES_STATUS_POWER_SUPPLY_FAIL_SHIFT = 6,
+
+ SES_STATUS_POWER_SUPPLY_REQUESTED_ON_BYTE = 2,
+ SES_STATUS_POWER_SUPPLY_REQUESTED_ON_MASK = 0x20,
+ SES_STATUS_POWER_SUPPLY_REQUESTED_ON_SHIFT = 5,
+
+ SES_STATUS_POWER_SUPPLY_OFF_BYTE = 2,
+ SES_STATUS_POWER_SUPPLY_OFF_MASK = 0x10,
+ SES_STATUS_POWER_SUPPLY_OFF_SHIFT = 4,
+
+ SES_STATUS_POWER_SUPPLY_OVERTMP_FAIL_BYTE = 2,
+ SES_STATUS_POWER_SUPPLY_OVERTMP_FAIL_MASK = 0x08,
+ SES_STATUS_POWER_SUPPLY_OVERTMP_FAIL_SHIFT = 3,
+
+ SES_STATUS_POWER_SUPPLY_TEMP_WARN_BYTE = 2,
+ SES_STATUS_POWER_SUPPLY_TEMP_WARN_MASK = 0x04,
+ SES_STATUS_POWER_SUPPLY_TEMP_WARN_SHIFT = 2,
+
+ SES_STATUS_POWER_SUPPLY_AC_FAIL_BYTE = 2,
+ SES_STATUS_POWER_SUPPLY_AC_FAIL_MASK = 0x02,
+ SES_STATUS_POWER_SUPPLY_AC_FAIL_SHIFT = 1,
+
+ SES_STATUS_POWER_SUPPLY_DC_FAIL_BYTE = 2,
+ SES_STATUS_POWER_SUPPLY_DC_FAIL_MASK = 0x01,
+ SES_STATUS_POWER_SUPPLY_DC_FAIL_SHIFT = 0
+};
+
+#define GEN_SES_STATUS_POWER_SUPPLY_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_power_supply, SES_STATUS_POWER_SUPPLY, LCASE, UCASE)
+GEN_SES_STATUS_POWER_SUPPLY_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_POWER_SUPPLY_ACCESSORS(dc_over_voltage, DC_OVER_VOLTAGE)
+GEN_SES_STATUS_POWER_SUPPLY_ACCESSORS(dc_under_voltage, DC_UNDER_VOLTAGE)
+GEN_SES_STATUS_POWER_SUPPLY_ACCESSORS(dc_over_current, DC_OVER_CURRENT)
+GEN_SES_STATUS_POWER_SUPPLY_ACCESSORS(hot_swap, HOT_SWAP)
+GEN_SES_STATUS_POWER_SUPPLY_ACCESSORS(fail, FAIL)
+GEN_SES_STATUS_POWER_SUPPLY_ACCESSORS(requested_on, REQUESTED_ON)
+GEN_SES_STATUS_POWER_SUPPLY_ACCESSORS(off, OFF)
+GEN_SES_STATUS_POWER_SUPPLY_ACCESSORS(overtmp_fail, OVERTMP_FAIL)
+GEN_SES_STATUS_POWER_SUPPLY_ACCESSORS(temp_warn, TEMP_WARN)
+GEN_SES_STATUS_POWER_SUPPLY_ACCESSORS(ac_fail, AC_FAIL)
+GEN_SES_STATUS_POWER_SUPPLY_ACCESSORS(dc_fail, DC_FAIL)
+#undef GEN_SES_STATUS_POWER_SUPPLY_ACCESSORS
+
+/*-------------------------- Cooling Status Element --------------------------*/
+struct ses_status_cooling {
+ struct ses_status_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_status_cooling_field_data {
+ SES_STATUS_COOLING_IDENT_BYTE = 0,
+ SES_STATUS_COOLING_IDENT_MASK = 0x80,
+ SES_STATUS_COOLING_IDENT_SHIFT = 7,
+
+ SES_STATUS_COOLING_ACTUAL_FAN_SPEED_MSB_BYTE = 0,
+ SES_STATUS_COOLING_ACTUAL_FAN_SPEED_MSB_MASK = 0x07,
+ SES_STATUS_COOLING_ACTUAL_FAN_SPEED_MSB_SHIFT = 0,
+
+ SES_STATUS_COOLING_ACTUAL_FAN_SPEED_LSB_BYTE = 1,
+ SES_STATUS_COOLING_ACTUAL_FAN_SPEED_LSB_MASK = 0xFF,
+ SES_STATUS_COOLING_ACTUAL_FAN_SPEED_LSB_SHIFT = 0,
+
+ SES_STATUS_COOLING_HOT_SWAP_BYTE = 2,
+ SES_STATUS_COOLING_HOT_SWAP_MASK = 0x40,
+ SES_STATUS_COOLING_HOT_SWAP_SHIFT = 6,
+
+ SES_STATUS_COOLING_FAIL_BYTE = 2,
+ SES_STATUS_COOLING_FAIL_MASK = 0x40,
+ SES_STATUS_COOLING_FAIL_SHIFT = 6,
+
+ SES_STATUS_COOLING_REQUESTED_ON_BYTE = 2,
+ SES_STATUS_COOLING_REQUESTED_ON_MASK = 0x20,
+ SES_STATUS_COOLING_REQUESTED_ON_SHIFT = 5,
+
+ SES_STATUS_COOLING_OFF_BYTE = 2,
+ SES_STATUS_COOLING_OFF_MASK = 0x20,
+ SES_STATUS_COOLING_OFF_SHIFT = 5,
+
+ SES_STATUS_COOLING_ACTUAL_SPEED_CODE_BYTE = 2,
+ SES_STATUS_COOLING_ACTUAL_SPEED_CODE_MASK = 0x07,
+ SES_STATUS_COOLING_ACTUAL_SPEED_CODE_SHIFT = 2,
+ SES_STATUS_COOLING_ACTUAL_SPEED_CODE_STOPPED = 0x00,
+ SES_STATUS_COOLING_ACTUAL_SPEED_CODE_LOWEST = 0x01,
+ SES_STATUS_COOLING_ACTUAL_SPEED_CODE_HIGHEST = 0x07
+};
+
+#define GEN_SES_STATUS_COOLING_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_cooling, SES_STATUS_COOLING, LCASE, UCASE)
+GEN_SES_STATUS_COOLING_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_COOLING_ACCESSORS(actual_fan_speed_msb, ACTUAL_FAN_SPEED_MSB)
+GEN_SES_STATUS_COOLING_ACCESSORS(actual_fan_speed_lsb, ACTUAL_FAN_SPEED_LSB)
+GEN_SES_STATUS_COOLING_ACCESSORS(hot_swap, HOT_SWAP)
+GEN_SES_STATUS_COOLING_ACCESSORS(fail, FAIL)
+GEN_SES_STATUS_COOLING_ACCESSORS(requested_on, REQUESTED_ON)
+GEN_SES_STATUS_COOLING_ACCESSORS(off, OFF)
+GEN_SES_STATUS_COOLING_ACCESSORS(actual_speed_code, ACTUAL_SPEED_CODE)
+#undef GEN_SES_STATUS_COOLING_ACCESSORS
+
+static inline int
+ses_status_cooling_get_actual_fan_speed(struct ses_status_cooling *elem)
+{
+ return (ses_status_cooling_get_actual_fan_speed_msb(elem) << 8
+ | ses_status_cooling_get_actual_fan_speed_lsb(elem));
+}
+
+/*-------------------- Temperature Sensor Status Element ---------------------*/
+struct ses_status_temp_sensor {
+ struct ses_status_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_status_temp_sensor_field_data {
+ SES_STATUS_TEMP_SENSOR_IDENT_BYTE = 0,
+ SES_STATUS_TEMP_SENSOR_IDENT_MASK = 0x80,
+ SES_STATUS_TEMP_SENSOR_IDENT_SHIFT = 7,
+
+ SES_STATUS_TEMP_SENSOR_FAIL_BYTE = 0,
+ SES_STATUS_TEMP_SENSOR_FAIL_MASK = 0x40,
+ SES_STATUS_TEMP_SENSOR_FAIL_SHIFT = 6,
+
+ SES_STATUS_TEMP_SENSOR_TEMPERATURE_BYTE = 1,
+ SES_STATUS_TEMP_SENSOR_TEMPERATURE_MASK = 0xFF,
+ SES_STATUS_TEMP_SENSOR_TEMPERATURE_SHIFT = 0,
+
+ SES_STATUS_TEMP_SENSOR_OT_FAILURE_BYTE = 2,
+ SES_STATUS_TEMP_SENSOR_OT_FAILURE_MASK = 0x08,
+ SES_STATUS_TEMP_SENSOR_OT_FAILURE_SHIFT = 3,
+
+ SES_STATUS_TEMP_SENSOR_OT_WARNING_BYTE = 2,
+ SES_STATUS_TEMP_SENSOR_OT_WARNING_MASK = 0x04,
+ SES_STATUS_TEMP_SENSOR_OT_WARNING_SHIFT = 2,
+
+ SES_STATUS_TEMP_SENSOR_UT_FAILURE_BYTE = 2,
+ SES_STATUS_TEMP_SENSOR_UT_FAILURE_MASK = 0x02,
+ SES_STATUS_TEMP_SENSOR_UT_FAILURE_SHIFT = 1,
+
+ SES_STATUS_TEMP_SENSOR_UT_WARNING_BYTE = 2,
+ SES_STATUS_TEMP_SENSOR_UT_WARNING_MASK = 0x01,
+ SES_STATUS_TEMP_SENSOR_UT_WARNING_SHIFT = 0
+};
+
+#define GEN_SES_STATUS_TEMP_SENSOR_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_temp_sensor, SES_STATUS_TEMP_SENSOR, LCASE, UCASE)
+GEN_SES_STATUS_TEMP_SENSOR_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_TEMP_SENSOR_ACCESSORS(fail, FAIL)
+GEN_SES_STATUS_TEMP_SENSOR_ACCESSORS(temperature, TEMPERATURE)
+GEN_SES_STATUS_TEMP_SENSOR_ACCESSORS(ot_failure, OT_FAILURE)
+GEN_SES_STATUS_TEMP_SENSOR_ACCESSORS(ot_warning, OT_WARNING)
+GEN_SES_STATUS_TEMP_SENSOR_ACCESSORS(ut_failure, UT_FAILURE)
+GEN_SES_STATUS_TEMP_SENSOR_ACCESSORS(ut_warning, UT_WARNING)
+#undef GEN_SES_STATUS_TEMP_SENSOR_ACCESSORS
+
+/*------------------------- Door Lock Status Element -------------------------*/
+struct ses_status_door_lock {
+ struct ses_status_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_status_door_lock_field_data {
+ SES_STATUS_DOOR_LOCK_IDENT_BYTE = 0,
+ SES_STATUS_DOOR_LOCK_IDENT_MASK = 0x80,
+ SES_STATUS_DOOR_LOCK_IDENT_SHIFT = 7,
+
+ SES_STATUS_DOOR_LOCK_FAIL_BYTE = 0,
+ SES_STATUS_DOOR_LOCK_FAIL_MASK = 0x40,
+ SES_STATUS_DOOR_LOCK_FAIL_SHIFT = 6,
+
+ SES_STATUS_DOOR_LOCK_UNLOCKED_BYTE = 2,
+ SES_STATUS_DOOR_LOCK_UNLOCKED_MASK = 0x01,
+ SES_STATUS_DOOR_LOCK_UNLOCKED_SHIFT = 0
+};
+
+#define GEN_SES_STATUS_DOOR_LOCK_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_door_lock, SES_STATUS_DOOR_LOCK, LCASE, UCASE)
+GEN_SES_STATUS_DOOR_LOCK_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_DOOR_LOCK_ACCESSORS(fail, FAIL)
+GEN_SES_STATUS_DOOR_LOCK_ACCESSORS(unlocked, UNLOCKED)
+#undef GEN_SES_STATUS_DOOR_LOCK_ACCESSORS
+
+/*----------------------- Audible Alarm Status Element -----------------------*/
+struct ses_status_audible_alarm {
+ struct ses_status_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_status_audible_alarm_field_data {
+ SES_STATUS_AUDIBLE_ALARM_IDENT_BYTE = 0,
+ SES_STATUS_AUDIBLE_ALARM_IDENT_MASK = 0x80,
+ SES_STATUS_AUDIBLE_ALARM_IDENT_SHIFT = 7,
+
+ SES_STATUS_AUDIBLE_ALARM_FAIL_BYTE = 0,
+ SES_STATUS_AUDIBLE_ALARM_FAIL_MASK = 0x40,
+ SES_STATUS_AUDIBLE_ALARM_FAIL_SHIFT = 6,
+
+ SES_STATUS_AUDIBLE_ALARM_RQST_MUTE_BYTE = 2,
+ SES_STATUS_AUDIBLE_ALARM_RQST_MUTE_MASK = 0x80,
+ SES_STATUS_AUDIBLE_ALARM_RQST_MUTE_SHIFT = 7,
+
+ SES_STATUS_AUDIBLE_ALARM_MUTED_BYTE = 2,
+ SES_STATUS_AUDIBLE_ALARM_MUTED_MASK = 0x40,
+ SES_STATUS_AUDIBLE_ALARM_MUTED_SHIFT = 6,
+
+ SES_STATUS_AUDIBLE_ALARM_REMIND_BYTE = 2,
+ SES_STATUS_AUDIBLE_ALARM_REMIND_MASK = 0x10,
+ SES_STATUS_AUDIBLE_ALARM_REMIND_SHIFT = 4,
+
+ SES_STATUS_AUDIBLE_ALARM_TONE_INDICATOR_BYTE = 2,
+ SES_STATUS_AUDIBLE_ALARM_TONE_INDICATOR_MASK = 0x0F,
+ SES_STATUS_AUDIBLE_ALARM_TONE_INDICATOR_SHIFT = 0,
+ SES_STATUS_AUDIBLE_ALARM_TONE_INDICATOR_INFO = 0x08,
+ SES_STATUS_AUDIBLE_ALARM_TONE_INDICATOR_NON_CRIT = 0x04,
+ SES_STATUS_AUDIBLE_ALARM_TONE_INDICATOR_CRIT = 0x02,
+ SES_STATUS_AUDIBLE_ALARM_TONE_INDICATOR_UNRECOV = 0x01
+};
+
+#define GEN_SES_STATUS_AUDIBLE_ALARM_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_audible_alarm, SES_STATUS_AUDIBLE_ALARM, LCASE, UCASE)
+GEN_SES_STATUS_AUDIBLE_ALARM_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_AUDIBLE_ALARM_ACCESSORS(fail, FAIL)
+GEN_SES_STATUS_AUDIBLE_ALARM_ACCESSORS(rqst_mute, RQST_MUTE)
+GEN_SES_STATUS_AUDIBLE_ALARM_ACCESSORS(muted, MUTED)
+GEN_SES_STATUS_AUDIBLE_ALARM_ACCESSORS(remind, REMIND)
+GEN_SES_STATUS_AUDIBLE_ALARM_ACCESSORS(tone_indicator, TONE_INDICATOR)
+#undef GEN_SES_STATUS_AUDIBLE_ALARM_ACCESSORS
+
+/*---------- Enclosure Services Statusler Electronics Status Element ---------*/
+struct ses_status_ecc_electronics {
+ struct ses_status_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_status_ecc_electronics_field_data {
+ SES_STATUS_ECC_ELECTRONICS_IDENT_BYTE = 0,
+ SES_STATUS_ECC_ELECTRONICS_IDENT_MASK = 0x80,
+ SES_STATUS_ECC_ELECTRONICS_IDENT_SHIFT = 7,
+
+ SES_STATUS_ECC_ELECTRONICS_FAIL_BYTE = 0,
+ SES_STATUS_ECC_ELECTRONICS_FAIL_MASK = 0x40,
+ SES_STATUS_ECC_ELECTRONICS_FAIL_SHIFT = 6,
+
+ SES_STATUS_ECC_ELECTRONICS_REPORT_BYTE = 1,
+ SES_STATUS_ECC_ELECTRONICS_REPORT_MASK = 0x01,
+ SES_STATUS_ECC_ELECTRONICS_REPORT_SHIFT = 0,
+
+ SES_STATUS_ECC_ELECTRONICS_HOT_SWAP_BYTE = 2,
+ SES_STATUS_ECC_ELECTRONICS_HOT_SWAP_MASK = 0x80,
+ SES_STATUS_ECC_ELECTRONICS_HOT_SWAP_SHIFT = 7
+};
+
+#define GEN_SES_STATUS_ECC_ELECTRONICS_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_ecc_electronics, SES_STATUS_ECC_ELECTRONICS, \
+ LCASE, UCASE)
+GEN_SES_STATUS_ECC_ELECTRONICS_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_ECC_ELECTRONICS_ACCESSORS(fail, FAIL)
+GEN_SES_STATUS_ECC_ELECTRONICS_ACCESSORS(report, REPORT)
+GEN_SES_STATUS_ECC_ELECTRONICS_ACCESSORS(hot_swap, HOT_SWAP)
+#undef GEN_SES_STATUS_ECC_ELECTRONICS_ACCESSORS
+
+/*------------ SCSI Services Statusler Electronics Status Element ------------*/
+struct ses_status_scc_electronics {
+ struct ses_status_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_status_scc_electronics_field_data {
+ SES_STATUS_SCC_ELECTRONICS_IDENT_BYTE = 0,
+ SES_STATUS_SCC_ELECTRONICS_IDENT_MASK = 0x80,
+ SES_STATUS_SCC_ELECTRONICS_IDENT_SHIFT = 7,
+
+ SES_STATUS_SCC_ELECTRONICS_FAIL_BYTE = 0,
+ SES_STATUS_SCC_ELECTRONICS_FAIL_MASK = 0x40,
+ SES_STATUS_SCC_ELECTRONICS_FAIL_SHIFT = 6,
+
+ SES_STATUS_SCC_ELECTRONICS_REPORT_BYTE = 1,
+ SES_STATUS_SCC_ELECTRONICS_REPORT_MASK = 0x01,
+ SES_STATUS_SCC_ELECTRONICS_REPORT_SHIFT = 0
+};
+
+#define GEN_SES_STATUS_SCC_ELECTRONICS_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_scc_electronics, SES_STATUS_SCC_ELECTRONICS, \
+ LCASE, UCASE)
+GEN_SES_STATUS_SCC_ELECTRONICS_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_SCC_ELECTRONICS_ACCESSORS(fail, FAIL)
+GEN_SES_STATUS_SCC_ELECTRONICS_ACCESSORS(report, REPORT)
+#undef GEN_SES_STATUS_SCC_ELECTRONICS_ACCESSORS
+
+/*--------------------- Nonvolatile Cache Status Element ---------------------*/
+struct ses_status_nv_cache {
+ struct ses_status_common common;
+ uint8_t bytes[1];
+ uint8_t cache_size[2];
+};
+
+enum ses_status_nv_cache_field_data {
+ SES_STATUS_NV_CACHE_IDENT_BYTE = 0,
+ SES_STATUS_NV_CACHE_IDENT_MASK = 0x80,
+ SES_STATUS_NV_CACHE_IDENT_SHIFT = 7,
+
+ SES_STATUS_NV_CACHE_FAIL_BYTE = 0,
+ SES_STATUS_NV_CACHE_FAIL_MASK = 0x40,
+ SES_STATUS_NV_CACHE_FAIL_SHIFT = 6,
+
+ SES_STATUS_NV_CACHE_SIZE_MULTIPLIER_BYTE = 0,
+ SES_STATUS_NV_CACHE_SIZE_MULTIPLIER_MASK = 0x03,
+ SES_STATUS_NV_CACHE_SIZE_MULTIPLIER_SHIFT = 0,
+ SES_STATUS_NV_CACHE_SIZE_MULTIPLIER_BYTES = 0x0,
+ SES_STATUS_NV_CACHE_SIZE_MULTIPLIER_KBYTES = 0x1,
+ SES_STATUS_NV_CACHE_SIZE_MULTIPLIER_MBYTES = 0x2,
+ SES_STATUS_NV_CACHE_SIZE_MULTIPLIER_GBYTES = 0x3
+};
+
+#define GEN_SES_STATUS_NV_CACHE_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_nv_cache, SES_STATUS_NV_CACHE, LCASE, UCASE)
+GEN_SES_STATUS_NV_CACHE_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_NV_CACHE_ACCESSORS(fail, FAIL)
+GEN_SES_STATUS_NV_CACHE_ACCESSORS(size_multiplier, SIZE_MULTIPLIER)
+#undef GEN_SES_STATUS_NV_CACHE_ACCESSORS
+
+static inline uintmax_t
+ses_status_nv_cache_get_cache_size(struct ses_status_nv_cache *elem)
+{
+ uintmax_t cache_size;
+ int multiplier;
+
+ /* Multiplier is in units of 2^10 */
+ cache_size = scsi_2btoul(elem->cache_size);
+ multiplier = 10 * ses_status_nv_cache_get_size_multiplier(elem);
+ return (cache_size << multiplier);
+}
+
+/*----------------- Invalid Operation Reason Status Element ------------------*/
+struct ses_status_invalid_op_reason {
+ struct ses_status_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_status_invalid_op_field_data {
+ SES_STATUS_INVALID_OP_REASON_TYPE_BYTE = 0,
+ SES_STATUS_INVALID_OP_REASON_TYPE_MASK = 0xC0,
+ SES_STATUS_INVALID_OP_REASON_TYPE_SHIFT = 6,
+ SES_STATUS_INVALID_OP_REASON_TYPE_PC_ERROR = 0x00,
+ SES_STATUS_INVALID_OP_REASON_TYPE_PF_ERROR = 0x01,
+ SES_STATUS_INVALID_OP_REASON_TYPE_VS_ERROR = 0x03,
+
+ SES_STATUS_INVALID_OP_REASON_PC_ERROR_PC_NOT_SUPPORTED_BYTE = 0,
+ SES_STATUS_INVALID_OP_REASON_PC_ERROR_PC_NOT_SUPPORTED_MASK = 0x01,
+ SES_STATUS_INVALID_OP_REASON_PC_ERROR_PC_NOT_SUPPORTED_SHIFT = 0,
+
+ SES_STATUS_INVALID_OP_REASON_PF_ERROR_BIT_NUMBER_BYTE = 0,
+ SES_STATUS_INVALID_OP_REASON_PF_ERROR_BIT_NUMBER_MASK = 0x03,
+ SES_STATUS_INVALID_OP_REASON_PF_ERROR_BIT_NUMBER_SHIFT = 0
+};
+
+#define GEN_SES_STATUS_INVALID_OP_REASON_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_invalid_op_reason, SES_STATUS_INVALID_OP_REASON, \
+ LCASE, UCASE)
+GEN_SES_STATUS_INVALID_OP_REASON_ACCESSORS(type, TYPE)
+GEN_SES_STATUS_INVALID_OP_REASON_ACCESSORS(pc_error_pc_not_supported,
+ PC_ERROR_PC_NOT_SUPPORTED)
+GEN_SES_STATUS_INVALID_OP_REASON_ACCESSORS(pf_error_bit_number,
+ PF_ERROR_BIT_NUMBER)
+#undef GEN_SES_STATUS_INVALID_OP_ACCESSORS
+
+/*--------------- Uninterruptible Power Supply Status Element ----------------*/
+struct ses_status_ups {
+ struct ses_status_common common;
+ /* Minutes of remaining capacity. */
+ uint8_t battery_status;
+ uint8_t bytes[2];
+};
+
+enum ses_status_ups_field_data {
+ SES_STATUS_UPS_AC_LO_BYTE = 0,
+ SES_STATUS_UPS_AC_LO_MASK = 0x80,
+ SES_STATUS_UPS_AC_LO_SHIFT = 7,
+
+ SES_STATUS_UPS_AC_HI_BYTE = 0,
+ SES_STATUS_UPS_AC_HI_MASK = 0x40,
+ SES_STATUS_UPS_AC_HI_SHIFT = 6,
+
+ SES_STATUS_UPS_AC_QUAL_BYTE = 0,
+ SES_STATUS_UPS_AC_QUAL_MASK = 0x20,
+ SES_STATUS_UPS_AC_QUAL_SHIFT = 5,
+
+ SES_STATUS_UPS_AC_FAIL_BYTE = 0,
+ SES_STATUS_UPS_AC_FAIL_MASK = 0x10,
+ SES_STATUS_UPS_AC_FAIL_SHIFT = 4,
+
+ SES_STATUS_UPS_DC_FAIL_BYTE = 0,
+ SES_STATUS_UPS_DC_FAIL_MASK = 0x08,
+ SES_STATUS_UPS_DC_FAIL_SHIFT = 3,
+
+ SES_STATUS_UPS_UPS_FAIL_BYTE = 0,
+ SES_STATUS_UPS_UPS_FAIL_MASK = 0x04,
+ SES_STATUS_UPS_UPS_FAIL_SHIFT = 2,
+
+ SES_STATUS_UPS_WARN_BYTE = 0,
+ SES_STATUS_UPS_WARN_MASK = 0x02,
+ SES_STATUS_UPS_WARN_SHIFT = 1,
+
+ SES_STATUS_UPS_INTF_FAIL_BYTE = 0,
+ SES_STATUS_UPS_INTF_FAIL_MASK = 0x01,
+ SES_STATUS_UPS_INTF_FAIL_SHIFT = 0,
+
+ SES_STATUS_UPS_IDENT_BYTE = 0,
+ SES_STATUS_UPS_IDENT_MASK = 0x80,
+ SES_STATUS_UPS_IDENT_SHIFT = 7,
+
+ SES_STATUS_UPS_FAIL_BYTE = 1,
+ SES_STATUS_UPS_FAIL_MASK = 0x40,
+ SES_STATUS_UPS_FAIL_SHIFT = 6,
+
+ SES_STATUS_UPS_BATT_FAIL_BYTE = 1,
+ SES_STATUS_UPS_BATT_FAIL_MASK = 0x02,
+ SES_STATUS_UPS_BATT_FAIL_SHIFT = 1,
+
+ SES_STATUS_UPS_BPF_BYTE = 1,
+ SES_STATUS_UPS_BPF_MASK = 0x01,
+ SES_STATUS_UPS_BPF_SHIFT = 0
+};
+
+#define GEN_SES_STATUS_UPS_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_ups, SES_STATUS_UPS, LCASE, UCASE)
+GEN_SES_STATUS_UPS_ACCESSORS(ac_lo, AC_LO)
+GEN_SES_STATUS_UPS_ACCESSORS(ac_hi, AC_HI)
+GEN_SES_STATUS_UPS_ACCESSORS(ac_qual, AC_QUAL)
+GEN_SES_STATUS_UPS_ACCESSORS(ac_fail, AC_FAIL)
+GEN_SES_STATUS_UPS_ACCESSORS(dc_fail, DC_FAIL)
+GEN_SES_STATUS_UPS_ACCESSORS(ups_fail, UPS_FAIL)
+GEN_SES_STATUS_UPS_ACCESSORS(warn, WARN)
+GEN_SES_STATUS_UPS_ACCESSORS(intf_fail, INTF_FAIL)
+GEN_SES_STATUS_UPS_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_UPS_ACCESSORS(fail, FAIL)
+GEN_SES_STATUS_UPS_ACCESSORS(batt_fail, BATT_FAIL)
+GEN_SES_STATUS_UPS_ACCESSORS(bpf, BPF)
+#undef GEN_SES_STATUS_UPS_ACCESSORS
+
+/*-------------------------- Display Status Element --------------------------*/
+struct ses_status_display {
+ struct ses_status_common common;
+ uint8_t bytes[1];
+ uint8_t display_character[2];
+};
+
+enum ses_status_display_field_data {
+ SES_STATUS_DISPLAY_IDENT_BYTE = 0,
+ SES_STATUS_DISPLAY_IDENT_MASK = 0x80,
+ SES_STATUS_DISPLAY_IDENT_SHIFT = 7,
+
+ SES_STATUS_DISPLAY_FAIL_BYTE = 0,
+ SES_STATUS_DISPLAY_FAIL_MASK = 0x40,
+ SES_STATUS_DISPLAY_FAIL_SHIFT = 6,
+
+ SES_STATUS_DISPLAY_DISPLAY_MODE_BYTE = 0,
+ SES_STATUS_DISPLAY_DISPLAY_MODE_MASK = 0x03,
+ SES_STATUS_DISPLAY_DISPLAY_MODE_SHIFT = 6,
+ SES_STATUS_DISPLAY_DISPLAY_MODE_DC_FIELD_UNSUPP = 0x0,
+ SES_STATUS_DISPLAY_DISPLAY_MODE_DC_FIELD_SUPP = 0x1,
+ SES_STATUS_DISPLAY_DISPLAY_MODE_DC_FIELD = 0x2
+};
+
+#define GEN_SES_STATUS_DISPLAY_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_display, SES_STATUS_DISPLAY, LCASE, UCASE)
+GEN_SES_STATUS_DISPLAY_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_DISPLAY_ACCESSORS(fail, FAIL)
+GEN_SES_STATUS_DISPLAY_ACCESSORS(display_mode, DISPLAY_MODE)
+#undef GEN_SES_STATUS_DISPLAY_ACCESSORS
+
+/*----------------------- Key Pad Entry Status Element -----------------------*/
+struct ses_status_key_pad_entry {
+ struct ses_status_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_status_key_pad_entry_field_data {
+ SES_STATUS_KEY_PAD_ENTRY_IDENT_BYTE = 0,
+ SES_STATUS_KEY_PAD_ENTRY_IDENT_MASK = 0x80,
+ SES_STATUS_KEY_PAD_ENTRY_IDENT_SHIFT = 7,
+
+ SES_STATUS_KEY_PAD_ENTRY_FAIL_BYTE = 0,
+ SES_STATUS_KEY_PAD_ENTRY_FAIL_MASK = 0x40,
+ SES_STATUS_KEY_PAD_ENTRY_FAIL_SHIFT = 6
+};
+
+#define GEN_SES_STATUS_KEY_PAD_ENTRY_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_key_pad_entry, SES_STATUS_KEY_PAD_ENTRY, LCASE, UCASE)
+GEN_SES_STATUS_KEY_PAD_ENTRY_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_KEY_PAD_ENTRY_ACCESSORS(fail, FAIL)
+#undef GEN_SES_STATUS_KEY_PAD_ENTRY_ACCESSORS
+
+/*------------------------- Enclosure Status Element -------------------------*/
+struct ses_status_enclosure {
+ struct ses_status_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_status_enclosure_field_data {
+ SES_STATUS_ENCLOSURE_IDENT_BYTE = 0,
+ SES_STATUS_ENCLOSURE_IDENT_MASK = 0x80,
+ SES_STATUS_ENCLOSURE_IDENT_SHIFT = 7,
+
+ SES_STATUS_ENCLOSURE_TIME_UNTIL_POWER_CYCLE_BYTE = 1,
+ SES_STATUS_ENCLOSURE_TIME_UNTIL_POWER_CYCLE_MASK = 0xFC,
+ SES_STATUS_ENCLOSURE_TIME_UNTIL_POWER_CYCLE_SHIFT = 2,
+
+ SES_STATUS_ENCLOSURE_FAIL_BYTE = 1,
+ SES_STATUS_ENCLOSURE_FAIL_MASK = 0x02,
+ SES_STATUS_ENCLOSURE_FAIL_SHIFT = 1,
+
+ SES_STATUS_ENCLOSURE_WARN_BYTE = 1,
+ SES_STATUS_ENCLOSURE_WARN_MASK = 0x01,
+ SES_STATUS_ENCLOSURE_WARN_SHIFT = 0,
+
+ SES_STATUS_ENCLOSURE_REQUESTED_POWER_OFF_DURATION_BYTE = 2,
+ SES_STATUS_ENCLOSURE_REQUESTED_POWER_OFF_DURATION_MASK = 0xFC,
+ SES_STATUS_ENCLOSURE_REQUESTED_POWER_OFF_DURATION_SHIFT = 2,
+ SES_STATUS_ENCLOSURE_REQUESTED_POWER_OFF_DURATION_MAX_AUTO = 60,
+ SES_STATUS_ENCLOSURE_REQUESTED_POWER_OFF_DURATION_MANUAL = 63,
+
+ SES_STATUS_ENCLOSURE_REQUESTED_FAIL_BYTE = 2,
+ SES_STATUS_ENCLOSURE_REQUESTED_FAIL_MASK = 0x02,
+ SES_STATUS_ENCLOSURE_REQUESTED_FAIL_SHIFT = 1,
+
+ SES_STATUS_ENCLOSURE_REQUESTED_WARN_BYTE = 2,
+ SES_STATUS_ENCLOSURE_REQUESTED_WARN_MASK = 0x01,
+ SES_STATUS_ENCLOSURE_REQUESTED_WARN_SHIFT = 0
+};
+
+#define GEN_SES_STATUS_ENCLOSURE_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_enclosure, SES_STATUS_ENCLOSURE, LCASE, UCASE)
+GEN_SES_STATUS_ENCLOSURE_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_ENCLOSURE_ACCESSORS(time_until_power_cycle,
+ TIME_UNTIL_POWER_CYCLE)
+GEN_SES_STATUS_ENCLOSURE_ACCESSORS(fail, FAIL)
+GEN_SES_STATUS_ENCLOSURE_ACCESSORS(warn, WARN)
+GEN_SES_STATUS_ENCLOSURE_ACCESSORS(requested_power_off_duration,
+ REQUESTED_POWER_OFF_DURATION)
+GEN_SES_STATUS_ENCLOSURE_ACCESSORS(requested_fail, REQUESTED_FAIL)
+GEN_SES_STATUS_ENCLOSURE_ACCESSORS(requested_warn, REQUESTED_WARN)
+#undef GEN_SES_STATUS_ENCLOSURE_ACCESSORS
+
+/*------------------- SCSI Port/Transceiver Status Element -------------------*/
+struct ses_status_scsi_port_or_xcvr {
+ struct ses_status_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_status_scsi_port_or_xcvr_field_data {
+ SES_STATUS_SCSI_PORT_OR_XCVR_IDENT_BYTE = 0,
+ SES_STATUS_SCSI_PORT_OR_XCVR_IDENT_MASK = 0x80,
+ SES_STATUS_SCSI_PORT_OR_XCVR_IDENT_SHIFT = 7,
+
+ SES_STATUS_SCSI_PORT_OR_XCVR_FAIL_BYTE = 0,
+ SES_STATUS_SCSI_PORT_OR_XCVR_FAIL_MASK = 0x40,
+ SES_STATUS_SCSI_PORT_OR_XCVR_FAIL_SHIFT = 6,
+
+ SES_STATUS_SCSI_PORT_OR_XCVR_REPORT_BYTE = 1,
+ SES_STATUS_SCSI_PORT_OR_XCVR_REPORT_MASK = 0x01,
+ SES_STATUS_SCSI_PORT_OR_XCVR_REPORT_SHIFT = 0,
+
+ SES_STATUS_SCSI_PORT_OR_XCVR_DISABLED_BYTE = 2,
+ SES_STATUS_SCSI_PORT_OR_XCVR_DISABLED_MASK = 0x10,
+ SES_STATUS_SCSI_PORT_OR_XCVR_DISABLED_SHIFT = 4,
+
+ SES_STATUS_SCSI_PORT_OR_XCVR_LOL_BYTE = 2,
+ SES_STATUS_SCSI_PORT_OR_XCVR_LOL_MASK = 0x02,
+ SES_STATUS_SCSI_PORT_OR_XCVR_LOL_SHIFT = 1,
+
+ SES_STATUS_SCSI_PORT_OR_XCVR_XMIT_FAIL_BYTE = 2,
+ SES_STATUS_SCSI_PORT_OR_XCVR_XMIT_FAIL_MASK = 0x01,
+ SES_STATUS_SCSI_PORT_OR_XCVR_XMIT_FAIL_SHIFT = 0
+};
+
+#define GEN_SES_STATUS_SCSI_PORT_OR_XCVR_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_scsi_port_or_xcvr, SES_STATUS_SCSI_PORT_OR_XCVR,\
+ LCASE, UCASE)
+GEN_SES_STATUS_SCSI_PORT_OR_XCVR_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_SCSI_PORT_OR_XCVR_ACCESSORS(fail, FAIL)
+GEN_SES_STATUS_SCSI_PORT_OR_XCVR_ACCESSORS(report, REPORT)
+GEN_SES_STATUS_SCSI_PORT_OR_XCVR_ACCESSORS(disable, DISABLED)
+GEN_SES_STATUS_SCSI_PORT_OR_XCVR_ACCESSORS(lol, LOL)
+GEN_SES_STATUS_SCSI_PORT_OR_XCVR_ACCESSORS(xmit_fail, XMIT_FAIL)
+#undef GEN_SES_STATUS_SCSI_PORT_OR_XCVR_ACCESSORS
+
+/*------------------------- Language Status Element --------------------------*/
+struct ses_status_language {
+ struct ses_status_common common;
+ uint8_t bytes[1];
+ uint8_t language_code[2];
+};
+
+enum ses_status_language_field_data {
+ SES_STATUS_LANGUAGE_IDENT_BYTE = 0,
+ SES_STATUS_LANGUAGE_IDENT_MASK = 0x80,
+ SES_STATUS_LANGUAGE_IDENT_SHIFT = 7
+};
+
+#define GEN_SES_STATUS_LANGUAGE_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_language, SES_STATUS_LANGUAGE, LCASE, UCASE)
+GEN_SES_STATUS_LANGUAGE_ACCESSORS(ident, IDENT)
+#undef GEN_SES_STATUS_LANGUAGE_ACCESSORS
+
+/*-------------------- Communication Port Status Element ---------------------*/
+struct ses_status_comm_port {
+ struct ses_status_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_status_comm_port_field_data {
+ SES_STATUS_COMM_PORT_IDENT_BYTE = 0,
+ SES_STATUS_COMM_PORT_IDENT_MASK = 0x80,
+ SES_STATUS_COMM_PORT_IDENT_SHIFT = 7,
+
+ SES_STATUS_COMM_PORT_FAIL_BYTE = 0,
+ SES_STATUS_COMM_PORT_FAIL_MASK = 0x40,
+ SES_STATUS_COMM_PORT_FAIL_SHIFT = 6,
+
+ SES_STATUS_COMM_PORT_DISABLED_BYTE = 2,
+ SES_STATUS_COMM_PORT_DISABLED_MASK = 0x01,
+ SES_STATUS_COMM_PORT_DISABLED_SHIFT = 0
+};
+
+#define GEN_SES_STATUS_COMM_PORT_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_comm_port, SES_STATUS_COMM_PORT, LCASE, UCASE)
+GEN_SES_STATUS_COMM_PORT_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_COMM_PORT_ACCESSORS(fail, FAIL)
+GEN_SES_STATUS_COMM_PORT_ACCESSORS(disabled, DISABLED)
+#undef GEN_SES_STATUS_COMM_PORT_ACCESSORS
+
+/*---------------------- Voltage Sensor Status Element -----------------------*/
+struct ses_status_voltage_sensor {
+ struct ses_status_common common;
+ uint8_t bytes[1];
+ uint8_t voltage[2];
+};
+
+enum ses_status_voltage_sensor_field_data {
+ SES_STATUS_VOLTAGE_SENSOR_IDENT_BYTE = 0,
+ SES_STATUS_VOLTAGE_SENSOR_IDENT_MASK = 0x80,
+ SES_STATUS_VOLTAGE_SENSOR_IDENT_SHIFT = 7,
+
+ SES_STATUS_VOLTAGE_SENSOR_FAIL_BYTE = 0,
+ SES_STATUS_VOLTAGE_SENSOR_FAIL_MASK = 0x40,
+ SES_STATUS_VOLTAGE_SENSOR_FAIL_SHIFT = 6,
+
+ SES_STATUS_VOLTAGE_SENSOR_WARN_OVER_BYTE = 0,
+ SES_STATUS_VOLTAGE_SENSOR_WARN_OVER_MASK = 0x08,
+ SES_STATUS_VOLTAGE_SENSOR_WARN_OVER_SHIFT = 3,
+
+ SES_STATUS_VOLTAGE_SENSOR_WARN_UNDER_BYTE = 0,
+ SES_STATUS_VOLTAGE_SENSOR_WARN_UNDER_MASK = 0x04,
+ SES_STATUS_VOLTAGE_SENSOR_WARN_UNDER_SHIFT = 2,
+
+ SES_STATUS_VOLTAGE_SENSOR_CRIT_OVER_BYTE = 0,
+ SES_STATUS_VOLTAGE_SENSOR_CRIT_OVER_MASK = 0x02,
+ SES_STATUS_VOLTAGE_SENSOR_CRIT_OVER_SHIFT = 1,
+
+ SES_STATUS_VOLTAGE_SENSOR_CRIT_UNDER_BYTE = 0,
+ SES_STATUS_VOLTAGE_SENSOR_CRIT_UNDER_MASK = 0x01,
+ SES_STATUS_VOLTAGE_SENSOR_CRIT_UNDER_SHIFT = 0
+};
+
+#define GEN_SES_STATUS_VOLTAGE_SENSOR_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_voltage_sensor, SES_STATUS_VOLTAGE_SENSOR, \
+ LCASE, UCASE)
+GEN_SES_STATUS_VOLTAGE_SENSOR_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_VOLTAGE_SENSOR_ACCESSORS(fail, FAIL)
+GEN_SES_STATUS_VOLTAGE_SENSOR_ACCESSORS(warn_over, WARN_OVER)
+GEN_SES_STATUS_VOLTAGE_SENSOR_ACCESSORS(warn_under, WARN_UNDER)
+GEN_SES_STATUS_VOLTAGE_SENSOR_ACCESSORS(crit_over, CRIT_OVER)
+GEN_SES_STATUS_VOLTAGE_SENSOR_ACCESSORS(crit_under, CRIT_UNDER)
+#undef GEN_SES_STATUS_VOLTAGE_SENSOR_ACCESSORS
+
+/*---------------------- Current Sensor Status Element -----------------------*/
+struct ses_status_current_sensor {
+ struct ses_status_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_status_current_sensor_field_data {
+ SES_STATUS_CURRENT_SENSOR_IDENT_BYTE = 0,
+ SES_STATUS_CURRENT_SENSOR_IDENT_MASK = 0x80,
+ SES_STATUS_CURRENT_SENSOR_IDENT_SHIFT = 7,
+
+ SES_STATUS_CURRENT_SENSOR_FAIL_BYTE = 0,
+ SES_STATUS_CURRENT_SENSOR_FAIL_MASK = 0x40,
+ SES_STATUS_CURRENT_SENSOR_FAIL_SHIFT = 6,
+
+ SES_STATUS_CURRENT_SENSOR_WARN_OVER_BYTE = 0,
+ SES_STATUS_CURRENT_SENSOR_WARN_OVER_MASK = 0x08,
+ SES_STATUS_CURRENT_SENSOR_WARN_OVER_SHIFT = 3,
+
+ SES_STATUS_CURRENT_SENSOR_CRIT_OVER_BYTE = 0,
+ SES_STATUS_CURRENT_SENSOR_CRIT_OVER_MASK = 0x02,
+ SES_STATUS_CURRENT_SENSOR_CRIT_OVER_SHIFT = 1
+};
+
+#define GEN_SES_STATUS_CURRENT_SENSOR_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_current_sensor, SES_STATUS_CURRENT_SENSOR, \
+ LCASE, UCASE)
+GEN_SES_STATUS_CURRENT_SENSOR_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_CURRENT_SENSOR_ACCESSORS(fail, FAIL)
+GEN_SES_STATUS_CURRENT_SENSOR_ACCESSORS(warn_over, WARN_OVER)
+GEN_SES_STATUS_CURRENT_SENSOR_ACCESSORS(crit_over, CRIT_OVER)
+#undef GEN_SES_STATUS_CURRENT_SENSOR_ACCESSORS
+
+/*--------------------- SCSI Target Port Status Element ----------------------*/
+struct ses_status_target_port {
+ struct ses_status_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_status_scsi_target_port_field_data {
+ SES_STATUS_TARGET_PORT_IDENT_BYTE = 0,
+ SES_STATUS_TARGET_PORT_IDENT_MASK = 0x80,
+ SES_STATUS_TARGET_PORT_IDENT_SHIFT = 7,
+
+ SES_STATUS_TARGET_PORT_FAIL_BYTE = 0,
+ SES_STATUS_TARGET_PORT_FAIL_MASK = 0x40,
+ SES_STATUS_TARGET_PORT_FAIL_SHIFT = 6,
+
+ SES_STATUS_TARGET_PORT_REPORT_BYTE = 1,
+ SES_STATUS_TARGET_PORT_REPORT_MASK = 0x01,
+ SES_STATUS_TARGET_PORT_REPORT_SHIFT = 0,
+
+ SES_STATUS_TARGET_PORT_ENABLED_BYTE = 2,
+ SES_STATUS_TARGET_PORT_ENABLED_MASK = 0x01,
+ SES_STATUS_TARGET_PORT_ENABLED_SHIFT = 0
+};
+
+#define GEN_SES_STATUS_TARGET_PORT_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_target_port, SES_STATUS_TARGET_PORT, LCASE, UCASE)
+GEN_SES_STATUS_TARGET_PORT_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_TARGET_PORT_ACCESSORS(fail, FAIL)
+GEN_SES_STATUS_TARGET_PORT_ACCESSORS(report, REPORT)
+GEN_SES_STATUS_TARGET_PORT_ACCESSORS(enabled, ENABLED)
+#undef GEN_SES_STATUS_TARGET_PORT_ACCESSORS
+
+/*-------------------- SCSI Initiator Port Status Element --------------------*/
+struct ses_status_initiator_port {
+ struct ses_status_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_status_scsi_initiator_port_field_data {
+ SES_STATUS_INITIATOR_PORT_IDENT_BYTE = 0,
+ SES_STATUS_INITIATOR_PORT_IDENT_MASK = 0x80,
+ SES_STATUS_INITIATOR_PORT_IDENT_SHIFT = 7,
+
+ SES_STATUS_INITIATOR_PORT_FAIL_BYTE = 0,
+ SES_STATUS_INITIATOR_PORT_FAIL_MASK = 0x40,
+ SES_STATUS_INITIATOR_PORT_FAIL_SHIFT = 6,
+
+ SES_STATUS_INITIATOR_PORT_REPORT_BYTE = 1,
+ SES_STATUS_INITIATOR_PORT_REPORT_MASK = 0x01,
+ SES_STATUS_INITIATOR_PORT_REPORT_SHIFT = 0,
+
+ SES_STATUS_INITIATOR_PORT_ENABLED_BYTE = 2,
+ SES_STATUS_INITIATOR_PORT_ENABLED_MASK = 0x01,
+ SES_STATUS_INITIATOR_PORT_ENABLED_SHIFT = 0
+};
+
+#define GEN_SES_STATUS_INITIATOR_PORT_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_initiator_port, SES_STATUS_INITIATOR_PORT, \
+ LCASE, UCASE)
+GEN_SES_STATUS_INITIATOR_PORT_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_INITIATOR_PORT_ACCESSORS(fail, FAIL)
+GEN_SES_STATUS_INITIATOR_PORT_ACCESSORS(report, REPORT)
+GEN_SES_STATUS_INITIATOR_PORT_ACCESSORS(enabled, ENABLED)
+#undef GEN_SES_STATUS_INITIATOR_PORT_ACCESSORS
+
+/*-------------------- Simple Subenclosure Status Element --------------------*/
+struct ses_status_simple_subses {
+ struct ses_status_common common;
+ uint8_t bytes[2];
+ uint8_t short_enclosure_status;
+};
+
+enum ses_status_simple_subses_field_data {
+ SES_STATUS_SIMPlE_SUBSES_IDENT_BYTE = 0,
+ SES_STATUS_SIMPlE_SUBSES_IDENT_MASK = 0x80,
+ SES_STATUS_SIMPlE_SUBSES_IDENT_SHIFT = 7,
+
+ SES_STATUS_SIMPlE_SUBSES_FAIL_BYTE = 0,
+ SES_STATUS_SIMPlE_SUBSES_FAIL_MASK = 0x40,
+ SES_STATUS_SIMPlE_SUBSES_FAIL_SHIFT = 6
+};
+
+#define GEN_SES_STATUS_SIMPlE_SUBSES_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_simple_subses, SES_STATUS_SIMPlE_SUBSES, \
+ LCASE, UCASE)
+GEN_SES_STATUS_SIMPlE_SUBSES_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_SIMPlE_SUBSES_ACCESSORS(fail, FAIL)
+#undef GEN_SES_STATUS_SIMPlE_SUBSES_ACCESSORS
+
+/*----------------------- SAS Expander Status Element ------------------------*/
+struct ses_status_sas_expander {
+ struct ses_status_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_status_sas_expander_field_data {
+ SES_STATUS_SAS_EXPANDER_IDENT_BYTE = 0,
+ SES_STATUS_SAS_EXPANDER_IDENT_MASK = 0x80,
+ SES_STATUS_SAS_EXPANDER_IDENT_SHIFT = 7,
+
+ SES_STATUS_SAS_EXPANDER_FAIL_BYTE = 0,
+ SES_STATUS_SAS_EXPANDER_FAIL_MASK = 0x40,
+ SES_STATUS_SAS_EXPANDER_FAIL_SHIFT = 6
+};
+
+#define GEN_SES_STATUS_SAS_EXPANDER_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_sas_expander, SES_STATUS_SAS_EXPANDER, LCASE, UCASE)
+GEN_SES_STATUS_SAS_EXPANDER_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_SAS_EXPANDER_ACCESSORS(fail, FAIL)
+#undef GEN_SES_STATUS_SAS_EXPANDER_ACCESSORS
+
+/*----------------------- SAS Connector Status Element -----------------------*/
+struct ses_status_sas_connector {
+ struct ses_status_common common;
+ uint8_t bytes[3];
+};
+
+enum ses_status_sas_connector_field_data {
+ SES_STATUS_SAS_CONNECTOR_IDENT_BYTE = 0,
+ SES_STATUS_SAS_CONNECTOR_IDENT_MASK = 0x80,
+ SES_STATUS_SAS_CONNECTOR_IDENT_SHIFT = 7,
+
+ SES_STATUS_SAS_CONNECTOR_TYPE_BYTE = 0,
+ SES_STATUS_SAS_CONNECTOR_TYPE_MASK = 0x7F,
+ SES_STATUS_SAS_CONNECTOR_TYPE_SHIFT = 0,
+
+ SES_STATUS_SAS_CONNECTOR_PHYS_LINK_BYTE = 1,
+ SES_STATUS_SAS_CONNECTOR_PHYS_LINK_MASK = 0xFF,
+ SES_STATUS_SAS_CONNECTOR_PHYS_LINK_SHIFT = 0,
+ SES_STATUS_SAS_CONNECTOR_PHYS_LINK_ALL = 0xFF,
+
+ SES_STATUS_SAS_CONNECTOR_FAIL_BYTE = 2,
+ SES_STATUS_SAS_CONNECTOR_FAIL_MASK = 0x40,
+ SES_STATUS_SAS_CONNECTOR_FAIL_SHIFT = 6,
+};
+
+#define GEN_SES_STATUS_SAS_CONNECTOR_ACCESSORS(LCASE, UCASE) \
+ GEN_GETTER(ses_status_sas_connector, SES_STATUS_SAS_CONNECTOR, \
+ LCASE, UCASE)
+GEN_SES_STATUS_SAS_CONNECTOR_ACCESSORS(ident, IDENT)
+GEN_SES_STATUS_SAS_CONNECTOR_ACCESSORS(type, TYPE)
+GEN_SES_STATUS_SAS_CONNECTOR_ACCESSORS(phys_link, PHYS_LINK)
+GEN_SES_STATUS_SAS_CONNECTOR_ACCESSORS(fail, FAIL)
+#undef GEN_SES_STATUS_SAS_CONNECTOR_ACCESSORS
+
+/*------------------------- Universal Status Element -------------------------*/
+union ses_status_element {
+ struct ses_status_common common;
+ struct ses_status_dev_slot dev_slot;
+ struct ses_status_array_dev_slot array_dev_slot;
+ struct ses_status_power_supply power_supply;
+ struct ses_status_cooling cooling;
+ struct ses_status_temp_sensor temp_sensor;
+ struct ses_status_door_lock door_lock;
+ struct ses_status_audible_alarm audible_alarm;
+ struct ses_status_ecc_electronics ecc_electronics;
+ struct ses_status_scc_electronics scc_electronics;
+ struct ses_status_nv_cache nv_cache;
+ struct ses_status_invalid_op_reason invalid_op_reason;
+ struct ses_status_ups ups;
+ struct ses_status_display display;
+ struct ses_status_key_pad_entry key_pad_entry;
+ struct ses_status_scsi_port_or_xcvr scsi_port_or_xcvr;
+ struct ses_status_language language;
+ struct ses_status_comm_port comm_port;
+ struct ses_status_voltage_sensor voltage_sensor;
+ struct ses_status_current_sensor current_sensor;
+ struct ses_status_target_port target_port;
+ struct ses_status_initiator_port initiator_port;
+ struct ses_status_simple_subses simple_subses;
+ struct ses_status_sas_expander sas_expander;
+ struct ses_status_sas_connector sas_connector;
+ uint8_t bytes[4];
+};
+
+/*===================== SCSI SES Status Diagnostic Page =====================*/
+struct ses_status_page {
+ struct ses_page_hdr hdr;
+ union ses_status_element elements[];
+};
+
+enum ses_status_page_field_data {
+ SES_STATUS_PAGE_INVOP_MASK = 0x10,
+ SES_STATUS_PAGE_INVOP_SHIFT = 4,
+
+ SES_STATUS_PAGE_INFO_MASK = 0x08,
+ SES_STATUS_PAGE_INFO_SHIFT = 3,
+
+ SES_STATUS_PAGE_NON_CRIT_MASK = 0x04,
+ SES_STATUS_PAGE_NON_CRIT_SHIFT = 2,
+
+ SES_STATUS_PAGE_CRIT_MASK = 0x02,
+ SES_STATUS_PAGE_CRIT_SHIFT = 1,
+
+ SES_STATUS_PAGE_UNRECOV_MASK = 0x01,
+ SES_STATUS_PAGE_UNRECOV_SHIFT = 0,
+
+ SES_STATUS_PAGE_CHANGED_MASK = SES_STATUS_PAGE_INVOP_MASK
+ | SES_STATUS_PAGE_INFO_MASK
+ | SES_STATUS_PAGE_NON_CRIT_MASK
+ | SES_STATUS_PAGE_CRIT_MASK
+ | SES_STATUS_PAGE_UNRECOV_MASK,
+ SES_STATUS_PAGE_CHANGED_SHIFT = 0,
+};
+
+#define GEN_SES_STATUS_PAGE_ACCESSORS(LCASE, UCASE) \
+ GEN_HDR_ACCESSORS(ses_status_page, SES_STATUS_PAGE, LCASE, UCASE)
+
+GEN_SES_STATUS_PAGE_ACCESSORS(invop, INVOP)
+GEN_SES_STATUS_PAGE_ACCESSORS(info, INFO)
+GEN_SES_STATUS_PAGE_ACCESSORS(non_crit, NON_CRIT)
+GEN_SES_STATUS_PAGE_ACCESSORS(crit, CRIT)
+GEN_SES_STATUS_PAGE_ACCESSORS(unrecov, UNRECOV)
+GEN_SES_STATUS_PAGE_ACCESSORS(changed, CHANGED)
+#undef GEN_SES_STATUS_PAGE_ACCESSORS
+
+/*================ SCSI SES Element Descriptor Diagnostic Page ===============*/
+struct ses_elem_descr {
+ uint8_t reserved[2];
+ uint8_t length[2];
+ char description[];
+};
+
+struct ses_elem_descr_page {
+ struct ses_page_hdr hdr;
+ struct ses_elem_descr descrs[];
+};
+
+/*============ SCSI SES Additional Element Status Diagnostic Page ============*/
+struct ses_addl_elem_status_page {
+ struct ses_page_hdr hdr;
+};
+
+/*====================== Legacy (Deprecated) Structures ======================*/
+struct ses_control_page_hdr {
+ uint8_t page_code;
+ uint8_t control_flags;
+ uint8_t length[2];
+ uint8_t gen_code[4];
+/* Followed by variable length array of descriptors. */
+};
+
+struct ses_status_page_hdr {
+ uint8_t page_code;
+ uint8_t status_flags;
+ uint8_t length[2];
+ uint8_t gen_code[4];
+/* Followed by variable length array of descriptors. */
+};
+
+/* ses_page_hdr.reserved values */
/*
- * Platform Independent Definitions for SES devices.
+ * Enclosure Status Diagnostic Page:
+ * uint8_t reserved : 3,
+ * invop : 1,
+ * info : 1,
+ * noncritical : 1,
+ * critical : 1,
+ * unrecov : 1;
*/
-/*
- * SCSI Based Environmental Services Application Defines
- *
- * Based almost entirely on SCSI-3 SES Revision 8A specification,
- * but slightly abstracted as the underlying device may in fact
- * be a SAF-TE or vendor unique device.
- */
-/*
- * SES Driver Operations:
- * (The defines themselves are platform and access method specific)
- *
- * SESIOC_GETNOBJ
- * SESIOC_GETOBJMAP
- * SESIOC_GETENCSTAT
- * SESIOC_SETENCSTAT
- * SESIOC_GETOBJSTAT
- * SESIOC_SETOBJSTAT
- * SESIOC_INIT
- *
- *
- * An application finds out how many objects an SES instance
- * is managing by performing a SESIOC_GETNOBJ operation. It then
- * performs a SESIOC_GETOBJMAP to get the map that contains the
- * object identifiers for all objects (see ses_object below).
- * This information is static.
- *
- * The application may perform SESIOC_GETOBJSTAT operations to retrieve
- * status on an object (see the ses_objstat structure below), SESIOC_SETOBJSTAT
- * operations to set status for an object.
- *
- * Similarly overall enclosure status me be fetched or set via
- * SESIOC_GETENCSTAT or SESIOC_SETENCSTAT operations (see ses_encstat below).
- *
- * Readers should note that there is nothing that requires either a set
- * or a clear operation to actually latch and do anything in the target.
- *
- * A SESIOC_INIT operation causes the enclosure to be initialized.
- */
+#define SES_ENCSTAT_UNRECOV 0x01
+#define SES_ENCSTAT_CRITICAL 0x02
+#define SES_ENCSTAT_NONCRITICAL 0x04
+#define SES_ENCSTAT_INFO 0x08
+#define SES_ENCSTAT_INVOP 0x10
+/* Status mask: All of the above OR'd together */
+#define SES_STATUS_MASK 0x1f
+#define SES_SET_STATUS_MASK 0xf
+/* Element Descriptor Diagnostic Page: unused */
+/* Additional Element Status Diagnostic Page: unused */
-typedef struct {
- unsigned int obj_id; /* Object Identifier */
- unsigned char subencid; /* SubEnclosure ID */
- unsigned char object_type; /* Object Type */
-} ses_object;
-/* Object Types */
-#define SESTYP_UNSPECIFIED 0x00
-#define SESTYP_DEVICE 0x01
-#define SESTYP_POWER 0x02
-#define SESTYP_FAN 0x03
-#define SESTYP_THERM 0x04
-#define SESTYP_DOORLOCK 0x05
-#define SESTYP_ALARM 0x06
-#define SESTYP_ESCC 0x07 /* Enclosure SCC */
-#define SESTYP_SCC 0x08 /* SCC */
-#define SESTYP_NVRAM 0x09
-#define SESTYP_UPS 0x0b
-#define SESTYP_DISPLAY 0x0c
-#define SESTYP_KEYPAD 0x0d
-#define SESTYP_ENCLOSURE 0x0e
-#define SESTYP_SCSIXVR 0x0f
-#define SESTYP_LANGUAGE 0x10
-#define SESTYP_COMPORT 0x11
-#define SESTYP_VOM 0x12
-#define SESTYP_AMMETER 0x13
-#define SESTYP_SCSI_TGT 0x14
-#define SESTYP_SCSI_INI 0x15
-#define SESTYP_SUBENC 0x16
-#define SESTYP_ARRAY 0x17
-#define SESTYP_SASEXPANDER 0x18
-#define SESTYP_SASCONNECTOR 0x19
-
-/*
- * Overall Enclosure Status
- */
-typedef unsigned char ses_encstat;
-#define SES_ENCSTAT_UNRECOV 0x1
-#define SES_ENCSTAT_CRITICAL 0x2
-#define SES_ENCSTAT_NONCRITICAL 0x4
-#define SES_ENCSTAT_INFO 0x8
-
-/*
- * Object Status
- */
-typedef struct {
- unsigned int obj_id;
- unsigned char cstat[4];
-} ses_objstat;
/* Summary SES Status Defines, Common Status Codes */
#define SES_OBJSTAT_UNSUPPORTED 0
@@ -140,6 +2164,7 @@
#define SES_OBJSTAT_NOTINSTALLED 5
#define SES_OBJSTAT_UNKNOWN 6
#define SES_OBJSTAT_NOTAVAIL 7
+#define SES_OBJSTAT_NOACCESS 8
/*
* For control pages, cstat[0] is the same for the
@@ -181,3 +2206,236 @@
unsigned int obj_id;
char obj_text[1];
} ses_hlptxt;
+
+/*============================================================================*/
+struct ses_elm_desc_hdr {
+ uint8_t reserved[2];
+ uint8_t length[2];
+};
+
+/*
+ * SES v2 r20 6.1.13 - Element Additional Status diagnostic page
+ * Tables 26-28 (general), 29-32 (FC), 33-41 (SAS)
+ *
+ * Protocol identifier uses definitions in scsi_all.h;
+ * SPSP_PROTO_FC, SPSP_PROTO_SAS are the only ones used here.
+ */
+
+struct ses_elm_fc_eip_hdr {
+ uint8_t num_phys;
+ uint8_t reserved[2];
+ uint8_t dev_slot_num;
+ uint8_t node_name[8];
+};
+
+struct ses_elm_fc_noneip_hdr {
+ uint8_t num_phys;
+ uint8_t reserved;
+ uint8_t node_name[8];
+};
+
+struct ses_elm_fc_base_hdr {
+ uint8_t num_phys;
+};
+
+union ses_elm_fc_hdr {
+ struct ses_elm_fc_base_hdr base_hdr;
+ struct ses_elm_fc_eip_hdr eip_hdr;
+ struct ses_elm_fc_noneip_hdr noneip_hdr;
+};
+
+struct ses_elm_fc_port {
+ uint8_t port_loop_position;
+ uint8_t bypass_reason;
+#define SES_FC_PORT_BYPASS_UNBYPASSED 0x00
+
+#define SES_FC_PORT_BYPASS_LINKFAIL_RATE_TOO_HIGH 0x10
+#define SES_FC_PORT_BYPASS_SYNC_LOSS_RATE_TOO_HIGH 0x11
+#define SES_FC_PORT_BYPASS_SIGNAL_LOSS_RATE_TOO_HIGH 0x12
+#define SES_FC_PORT_BYPASS_SEQPROTO_ERR_RATE_TOO_HIGH 0x13
+#define SES_FC_PORT_BYPASS_INVAL_XMIT_RATE_TOO_HIGH 0x14
+#define SES_FC_PORT_BYPASS_CRC_ERR_RATE_TOO_HIGH 0x15
+
+#define SES_FC_PORT_BYPASS_ERR_RATE_RESERVED_BEGIN 0x16
+#define SES_FC_PORT_BYPASS_ERR_RATE_RESERVED_END 0x1F
+
+#define SES_FC_PORT_BYPASS_LINKFAIL_COUNT_TOO_HIGH 0x20
+#define SES_FC_PORT_BYPASS_SYNC_LOSS_COUNT_TOO_HIGH 0x21
+#define SES_FC_PORT_BYPASS_SIGNAL_LOSS_COUNT_TOO_HIGH 0x22
+#define SES_FC_PORT_BYPASS_SEQPROTO_ERR_COUNT_TOO_HIGH 0x23
+#define SES_FC_PORT_BYPASS_INVAL_XMIT_COUNT_TOO_HIGH 0x24
+#define SES_FC_PORT_BYPASS_CRC_ERR_COUNT_TOO_HIGH 0x25
+
+#define SES_FC_PORT_BYPASS_ERR_COUNT_RESERVED_BEGIN 0x26
+#define SES_FC_PORT_BYPASS_ERR_COUNT_RESERVED_END 0x2F
+
+#define SES_FC_PORT_BYPASS_RESERVED_BEGIN 0x30
+#define SES_FC_PORT_BYPASS_RESERVED_END 0xBF
+
+#define SES_FC_PORT_BYPASS_VENDOR_SPECIFIC_BEGIN 0xC0
+#define SES_FC_PORT_BYPASS_VENDOR_SPECIFIC_END 0xFF
+ uint8_t port_req_hard_addr;
+ uint8_t n_port_id[3];
+ uint8_t n_port_name[8];
+};
+
+struct ses_elm_sas_device_phy {
+ uint8_t byte0;
+ /*
+ * uint8_t reserved0 : 1,
+ * uint8_t device_type : 3,
+ * uint8_t reserved1 : 4;
+ */
+
+ uint8_t reserved0;
+
+ /* Bit positions for initiator and target port protocols */
+#define SES_SASOBJ_DEV_PHY_SMP 0x2
+#define SES_SASOBJ_DEV_PHY_STP 0x4
+#define SES_SASOBJ_DEV_PHY_SSP 0x8
+ /* Select all of the above protocols */
+#define SES_SASOBJ_DEV_PHY_PROTOMASK 0xe
+ uint8_t initiator_ports;
+ /*
+ * uint8_t reserved0 : 4,
+ * uint8_t ssp : 1,
+ * uint8_t stp : 1,
+ * uint8_t smp : 1,
+ * uint8_t reserved1 : 3;
+ */
+ uint8_t target_ports;
+ /*
+ * uint8_t sata_port_selector : 1,
+ * uint8_t reserved : 3,
+ * uint8_t ssp : 1,
+ * uint8_t stp : 1,
+ * uint8_t smp : 1,
+ * uint8_t sata_device : 1;
+ */
+ uint8_t parent_addr[8]; /* SAS address of parent */
+ uint8_t phy_addr[8]; /* SAS address of this phy */
+ uint8_t phy_id;
+ uint8_t reserved1[7];
+};
+#ifdef _KERNEL
+int ses_elm_sas_dev_phy_sata_dev(struct ses_elm_sas_device_phy *);
+int ses_elm_sas_dev_phy_sata_port(struct ses_elm_sas_device_phy *);
+int ses_elm_sas_dev_phy_dev_type(struct ses_elm_sas_device_phy *);
+#endif /* _KERNEL */
+
+struct ses_elm_sas_expander_phy {
+ uint8_t connector_index;
+ uint8_t other_index;
+};
+
+struct ses_elm_sas_port_phy {
+ uint8_t phy_id;
+ uint8_t reserved;
+ uint8_t connector_index;
+ uint8_t other_index;
+ uint8_t phy_addr[8];
+};
+
+struct ses_elm_sas_type0_base_hdr {
+ uint8_t num_phys;
+ uint8_t byte1;
+ /*
+ * uint8_t descriptor_type : 2,
+ * uint8_t reserved : 5,
+ * uint8_t not_all_phys : 1;
+ */
+#define SES_SASOBJ_TYPE0_NOT_ALL_PHYS(obj) \
+ ((obj)->byte1 & 0x1)
+};
+
+struct ses_elm_sas_type0_eip_hdr {
+ struct ses_elm_sas_type0_base_hdr base;
+ uint8_t reserved;
+ uint8_t dev_slot_num;
+};
+
+struct ses_elm_sas_type1_expander_hdr {
+ uint8_t num_phys;
+ uint8_t byte1;
+ /*
+ * uint8_t descriptor_type : 2,
+ * uint8_t reserved : 6;
+ */
+ uint8_t reserved[2];
+ uint8_t sas_addr[8];
+};
+
+struct ses_elm_sas_type1_nonexpander_hdr {
+ uint8_t num_phys;
+ uint8_t byte1;
+ /*
+ * uint8_t descriptor_type : 2,
+ * uint8_t reserved : 6;
+ */
+ uint8_t reserved[2];
+};
+
+/* NB: This is only usable for as long as the headers happen to match */
+struct ses_elm_sas_base_hdr {
+ uint8_t num_phys;
+ uint8_t byte1;
+ /*
+ * uint8_t descriptor_type : 2,
+ * uint8_t descr_specific : 6;
+ */
+#define SES_SASOBJ_TYPE_SLOT 0
+#define SES_SASOBJ_TYPE_OTHER 1
+};
+
+union ses_elm_sas_hdr {
+ struct ses_elm_sas_base_hdr base_hdr;
+ struct ses_elm_sas_type0_base_hdr type0_noneip;
+ struct ses_elm_sas_type0_eip_hdr type0_eip;
+ struct ses_elm_sas_type1_expander_hdr type1_exp;
+ struct ses_elm_sas_type1_nonexpander_hdr type1_nonexp;
+};
+int ses_elm_sas_type0_not_all_phys(union ses_elm_sas_hdr *);
+int ses_elm_sas_descr_type(union ses_elm_sas_hdr *);
+
+struct ses_elm_addlstatus_base_hdr {
+ uint8_t byte0;
+ /*
+ * uint8_t invalid : 1,
+ * uint8_t reserved : 2,
+ * uint8_t eip : 1,
+ * uint8_t proto_id : 4;
+ */
+ uint8_t length;
+};
+int ses_elm_addlstatus_proto(struct ses_elm_addlstatus_base_hdr *);
+int ses_elm_addlstatus_eip(struct ses_elm_addlstatus_base_hdr *);
+int ses_elm_addlstatus_invalid(struct ses_elm_addlstatus_base_hdr *);
+
+struct ses_elm_addlstatus_eip_hdr {
+ struct ses_elm_addlstatus_base_hdr base;
+ uint8_t reserved;
+ uint8_t element_index;
+ /* NB: This define (currently) applies to all eip=1 headers */
+#define SES_EIP_HDR_EXTRA_LEN 2
+};
+
+union ses_elm_addlstatus_descr_hdr {
+ struct ses_elm_addlstatus_base_hdr base;
+ struct ses_elm_addlstatus_eip_hdr eip;
+};
+
+union ses_elm_addlstatus_proto_hdr {
+ union ses_elm_fc_hdr fc;
+ union ses_elm_sas_hdr sas;
+};
+
+/*============================= Namespace Cleanup ============================*/
+#undef GEN_HDR_ACCESSORS
+#undef GEN_ACCESSORS
+#undef GEN_HDR_SETTER
+#undef GEN_HDR_GETTER
+#undef GEN_SETTER
+#undef GEN_GETTER
+#undef MK_ENUM
+
+#endif /* _SCSI_SES_H_ */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_sg.c
--- a/head/sys/cam/scsi/scsi_sg.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/scsi/scsi_sg.c Wed Jul 25 16:45:04 2012 +0300
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_sg.c 230000 2012-01-12 00:41:48Z ken $");
+__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_sg.c 236138 2012-05-27 06:11:09Z ken $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -61,9 +61,8 @@
#include <compat/linux/linux_ioctl.h>
typedef enum {
- SG_FLAG_OPEN = 0x01,
- SG_FLAG_LOCKED = 0x02,
- SG_FLAG_INVALID = 0x04
+ SG_FLAG_LOCKED = 0x01,
+ SG_FLAG_INVALID = 0x02
} sg_flags;
typedef enum {
@@ -141,7 +140,7 @@
static struct cdevsw sg_cdevsw = {
.d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
+ .d_flags = D_NEEDGIANT | D_TRACKCLOSE,
.d_open = sgopen,
.d_close = sgclose,
.d_ioctl = sgioctl,
@@ -415,19 +414,12 @@
softc = (struct sg_softc *)periph->softc;
if (softc->flags & SG_FLAG_INVALID) {
+ cam_periph_release_locked(periph);
cam_periph_unlock(periph);
- cam_periph_release(periph);
return (ENXIO);
}
- if ((softc->flags & SG_FLAG_OPEN) == 0) {
- softc->flags |= SG_FLAG_OPEN;
- cam_periph_unlock(periph);
- } else {
- /* Device closes aren't symmetrical, fix up the refcount. */
- cam_periph_unlock(periph);
- cam_periph_release(periph);
- }
+ cam_periph_unlock(periph);
return (error);
}
@@ -436,18 +428,11 @@
sgclose(struct cdev *dev, int flag, int fmt, struct thread *td)
{
struct cam_periph *periph;
- struct sg_softc *softc;
periph = (struct cam_periph *)dev->si_drv1;
if (periph == NULL)
return (ENXIO);
- cam_periph_lock(periph);
-
- softc = (struct sg_softc *)periph->softc;
- softc->flags &= ~SG_FLAG_OPEN;
-
- cam_periph_unlock(periph);
cam_periph_release(periph);
return (0);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_target.c
--- a/head/sys/cam/scsi/scsi_target.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/scsi/scsi_target.c Wed Jul 25 16:45:04 2012 +0300
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_target.c 228481 2011-12-13 21:26:33Z ed $");
+__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_target.c 236712 2012-06-07 10:05:51Z mav $");
#include <sys/param.h>
@@ -266,7 +266,6 @@
break;
case TARGIOCDEBUG:
{
-#ifdef CAMDEBUG
struct ccb_debug cdbg;
/* If no periph available, disallow debugging changes */
@@ -287,9 +286,6 @@
xpt_action((union ccb *)&cdbg);
cam_periph_unlock(softc->periph);
status = cdbg.ccb_h.status & CAM_STATUS_MASK;
-#else
- status = CAM_FUNC_NOTAVAIL;
-#endif
break;
}
default:
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cam/scsi/scsi_xpt.c
--- a/head/sys/cam/scsi/scsi_xpt.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cam/scsi/scsi_xpt.c Wed Jul 25 16:45:04 2012 +0300
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_xpt.c 231745 2012-02-15 07:30:23Z gibbs $");
+__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_xpt.c 236814 2012-06-09 13:07:44Z mav $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -141,6 +141,7 @@
PROBE_INQUIRY_BASIC_DV1,
PROBE_INQUIRY_BASIC_DV2,
PROBE_DV_EXIT,
+ PROBE_DONE,
PROBE_INVALID
} probe_action;
@@ -157,6 +158,7 @@
"PROBE_INQUIRY_BASIC_DV1",
"PROBE_INQUIRY_BASIC_DV2",
"PROBE_DV_EXIT",
+ "PROBE_DONE",
"PROBE_INVALID"
};
@@ -164,7 +166,7 @@
do { \
char **text; \
text = probe_action_text; \
- CAM_DEBUG((softc)->periph->path, CAM_DEBUG_INFO, \
+ CAM_DEBUG((softc)->periph->path, CAM_DEBUG_PROBE, \
("Probe %s to %s\n", text[(softc)->action], \
text[(newaction)])); \
(softc)->action = (newaction); \
@@ -535,6 +537,10 @@
CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0
},
{
+ { T_DIRECT, SIP_MEDIA_REMOVABLE, "Garmin", "*", "*" },
+ CAM_QUIRK_NORPTLUNS, /*mintags*/2, /*maxtags*/255
+ },
+ {
/* Default tagged queuing parameters for all devices */
{
T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
@@ -638,7 +644,7 @@
if (status != CAM_REQ_CMP) {
return (status);
}
-
+ CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe started\n"));
/*
* Ensure we've waited at least a bus settle
@@ -741,7 +747,7 @@
case PROBE_DV_EXIT:
{
scsi_test_unit_ready(csio,
- /*retries*/10,
+ /*retries*/4,
probedone,
MSG_SIMPLE_Q_TAG,
SSD_FULL_SIZE,
@@ -977,11 +983,8 @@
probedone(periph, start_ccb);
return;
}
- case PROBE_INVALID:
- CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO,
- ("probestart: invalid action state\n"));
default:
- break;
+ panic("probestart: invalid action state 0x%x\n", softc->action);
}
xpt_action(start_ccb);
}
@@ -1061,7 +1064,7 @@
}
if (device->flags & CAM_DEV_DV_HIT_BOTTOM) {
- CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
+ CAM_DEBUG(periph->path, CAM_DEBUG_PROBE,
("hit async: giving up on DV\n"));
return (0);
}
@@ -1081,7 +1084,7 @@
if (spi->sync_period >= 0xf) {
spi->sync_period = 0;
spi->sync_offset = 0;
- CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
+ CAM_DEBUG(periph->path, CAM_DEBUG_PROBE,
("setting to async for DV\n"));
/*
* Once we hit async, we don't want to try
@@ -1089,7 +1092,7 @@
*/
device->flags |= CAM_DEV_DV_HIT_BOTTOM;
} else if (bootverbose) {
- CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
+ CAM_DEBUG(periph->path, CAM_DEBUG_PROBE,
("DV: period 0x%x\n", spi->sync_period));
printf("setting period to 0x%x\n", spi->sync_period);
}
@@ -1099,7 +1102,7 @@
if ((cts.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
break;
}
- CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
+ CAM_DEBUG(periph->path, CAM_DEBUG_PROBE,
("DV: failed to set period 0x%x\n", spi->sync_period));
if (spi->sync_period == 0) {
return (0);
@@ -1246,6 +1249,7 @@
if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
/* Send the async notification. */
xpt_async(AC_LOST_DEVICE, path, NULL);
+ PROBE_SET_ACTION(softc, PROBE_INVALID);
xpt_release_ccb(done_ccb);
break;
@@ -1279,8 +1283,9 @@
/*
* Reallocate and retry to cover all luns
*/
- CAM_DEBUG_PATH_PRINT(CAM_DEBUG_PROBE, path,
- ("reallocating REPORT_LUNS for %u luns\n", nlun));
+ CAM_DEBUG(path, CAM_DEBUG_PROBE,
+ ("Probe: reallocating REPORT_LUNS for %u luns\n",
+ nlun));
free(lp, M_CAMXPT);
path->target->rpl_size = (nlun << 3) + 8;
xpt_release_ccb(done_ccb);
@@ -1303,8 +1308,8 @@
lun_id_t lun;
int idx;
- CAM_DEBUG_PATH_PRINT(CAM_DEBUG_PROBE, path,
- ("%u luns reported\n", nlun));
+ CAM_DEBUG(path, CAM_DEBUG_PROBE,
+ ("Probe: %u lun(s) reported\n", nlun));
CAM_GET_SIMPLE_LUN(lp, 0, lun);
/*
@@ -1326,8 +1331,8 @@
lp->luns[idx].lundata, 8);
memcpy(lp->luns[idx].lundata,
tlun, 8);
- CAM_DEBUG_PATH_PRINT(CAM_DEBUG_PROBE,
- path, ("lun 0 in position %u\n", idx));
+ CAM_DEBUG(path, CAM_DEBUG_PROBE,
+ ("lun 0 in position %u\n", idx));
} else {
/*
* There is no lun 0 in our list. Destroy
@@ -1591,14 +1596,11 @@
break;
}
case PROBE_TUR_FOR_NEGOTIATION:
+ case PROBE_DV_EXIT:
if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
- DELAY(500000);
- if (cam_periph_error(done_ccb, 0, SF_RETRY_UA,
- NULL) == ERESTART)
- return;
+ cam_periph_error(done_ccb, 0,
+ SF_NO_PRINT | SF_NO_RECOVERY | SF_NO_RETRY, NULL);
}
- /* FALLTHROUGH */
- case PROBE_DV_EXIT:
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
/* Don't wedge the queue */
xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
@@ -1612,7 +1614,7 @@
&& done_ccb->ccb_h.target_lun == 0
&& (path->device->inq_data.flags & SID_Sync) != 0
&& (path->device->flags & CAM_DEV_IN_DV) == 0) {
- CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
+ CAM_DEBUG(periph->path, CAM_DEBUG_PROBE,
("Begin Domain Validation\n"));
path->device->flags |= CAM_DEV_IN_DV;
xpt_release_ccb(done_ccb);
@@ -1621,7 +1623,7 @@
return;
}
if (softc->action == PROBE_DV_EXIT) {
- CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
+ CAM_DEBUG(periph->path, CAM_DEBUG_PROBE,
("Leave Domain Validation\n"));
}
if (path->device->flags & CAM_DEV_UNCONFIGURED) {
@@ -1637,6 +1639,7 @@
xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
done_ccb);
}
+ PROBE_SET_ACTION(softc, PROBE_DONE);
xpt_release_ccb(done_ccb);
break;
case PROBE_INQUIRY_BASIC_DV1:
@@ -1645,6 +1648,10 @@
struct scsi_inquiry_data *nbuf;
struct ccb_scsiio *csio;
+ if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
+ cam_periph_error(done_ccb, 0,
+ SF_NO_PRINT | SF_NO_RECOVERY | SF_NO_RETRY, NULL);
+ }
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
/* Don't wedge the queue */
xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
@@ -1676,7 +1683,7 @@
return;
}
if (softc->action == PROBE_INQUIRY_BASIC_DV2) {
- CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
+ CAM_DEBUG(periph->path, CAM_DEBUG_PROBE,
("Leave Domain Validation Successfully\n"));
}
if (path->device->flags & CAM_DEV_UNCONFIGURED) {
@@ -1692,23 +1699,22 @@
xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
done_ccb);
}
+ PROBE_SET_ACTION(softc, PROBE_DONE);
xpt_release_ccb(done_ccb);
break;
}
- case PROBE_INVALID:
- CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_INFO,
- ("probedone: invalid action state\n"));
default:
- break;
+ panic("probedone: invalid action state 0x%x\n", softc->action);
}
done_ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
TAILQ_REMOVE(&softc->request_ccbs, &done_ccb->ccb_h, periph_links.tqe);
done_ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(done_ccb);
if (TAILQ_FIRST(&softc->request_ccbs) == NULL) {
+ CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe completed\n"));
+ cam_periph_invalidate(periph);
cam_release_devq(periph->path,
RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_XPT + 1, FALSE);
- cam_periph_invalidate(periph);
cam_periph_release_locked(periph);
} else {
probeschedule(periph);
@@ -1918,7 +1924,7 @@
xpt_done(request_ccb);
return;
}
- CAM_DEBUG_PATH_PRINT(CAM_DEBUG_PROBE, request_ccb->ccb_h.path,
+ CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE,
("SCAN start for %p\n", scan_info));
scan_info->request_ccb = request_ccb;
scan_info->cpi = &work_ccb->cpi;
@@ -2031,8 +2037,8 @@
CAM_GET_SIMPLE_LUN(target->luns,
scan_info->lunindex[target_id], lun_id);
next_target = 0;
- CAM_DEBUG_PATH_PRINT(CAM_DEBUG_PROBE,
- request_ccb->ccb_h.path,
+ CAM_DEBUG(request_ccb->ccb_h.path,
+ CAM_DEBUG_PROBE,
("next lun to try at index %u is %u\n",
scan_info->lunindex[target_id], lun_id));
scan_info->lunindex[target_id]++;
@@ -2139,8 +2145,8 @@
xpt_free_ccb(request_ccb);
xpt_free_ccb((union ccb *)scan_info->cpi);
request_ccb = scan_info->request_ccb;
- CAM_DEBUG_PATH_PRINT(CAM_DEBUG_PROBE,
- request_ccb->ccb_h.path,
+ CAM_DEBUG(request_ccb->ccb_h.path,
+ CAM_DEBUG_TRACE,
("SCAN done for %p\n", scan_info));
free(scan_info, M_CAMXPT);
request_ccb->ccb_h.status = CAM_REQ_CMP;
@@ -2274,11 +2280,16 @@
}
if ((old_periph = cam_periph_find(path, "probe")) != NULL) {
- probe_softc *softc;
+ if ((old_periph->flags & CAM_PERIPH_INVALID) == 0) {
+ probe_softc *softc;
- softc = (probe_softc *)old_periph->softc;
- TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h,
- periph_links.tqe);
+ softc = (probe_softc *)old_periph->softc;
+ TAILQ_INSERT_TAIL(&softc->request_ccbs,
+ &request_ccb->ccb_h, periph_links.tqe);
+ } else {
+ request_ccb->ccb_h.status = CAM_REQ_CMP_ERR;
+ xpt_done(request_ccb);
+ }
} else {
status = cam_periph_alloc(proberegister, NULL, probecleanup,
probestart, "probe",
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/boot/zfs/zfsimpl.h
--- a/head/sys/cddl/boot/zfs/zfsimpl.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/boot/zfs/zfsimpl.h Wed Jul 25 16:45:04 2012 +0300
@@ -53,6 +53,8 @@
* Use is subject to license terms.
*/
+#define MAXNAMELEN 256
+
/* CRC64 table */
#define ZFS_CRC64_POLY 0xC96C5795D7870F42ULL /* ECMA-182, reflected form */
@@ -508,6 +510,7 @@
#define SPA_VERSION_26 26ULL
#define SPA_VERSION_27 27ULL
#define SPA_VERSION_28 28ULL
+#define SPA_VERSION_5000 5000ULL
/*
* When bumping up SPA_VERSION, make sure GRUB ZFS understands the on-disk
@@ -515,8 +518,8 @@
* and do the appropriate changes. Also bump the version number in
* usr/src/grub/capability.
*/
-#define SPA_VERSION SPA_VERSION_28
-#define SPA_VERSION_STRING "28"
+#define SPA_VERSION SPA_VERSION_5000
+#define SPA_VERSION_STRING "5000"
/*
* Symbolic names for the changes that caused a SPA_VERSION switch.
@@ -567,6 +570,12 @@
#define SPA_VERSION_DEADLISTS SPA_VERSION_26
#define SPA_VERSION_FAST_SNAP SPA_VERSION_27
#define SPA_VERSION_MULTI_REPLACE SPA_VERSION_28
+#define SPA_VERSION_BEFORE_FEATURES SPA_VERSION_28
+#define SPA_VERSION_FEATURES SPA_VERSION_5000
+
+#define SPA_VERSION_IS_SUPPORTED(v) \
+ (((v) >= SPA_VERSION_INITIAL && (v) <= SPA_VERSION_BEFORE_FEATURES) || \
+ ((v) >= SPA_VERSION_FEATURES && (v) <= SPA_VERSION))
/*
* The following are configuration names used in the nvlist describing a pool's
@@ -602,6 +611,7 @@
#define ZPOOL_CONFIG_HOSTNAME "hostname"
#define ZPOOL_CONFIG_IS_LOG "is_log"
#define ZPOOL_CONFIG_TIMESTAMP "timestamp" /* not stored on disk */
+#define ZPOOL_CONFIG_FEATURES_FOR_READ "features_for_read"
/*
* The persistent vdev state is stored as separate values rather than a single
@@ -1327,5 +1337,5 @@
struct uberblock spa_uberblock; /* best uberblock so far */
vdev_list_t spa_vdevs; /* list of all toplevel vdevs */
objset_phys_t spa_mos; /* MOS for this pool */
- objset_phys_t spa_root_objset; /* current mounted ZPL objset */
+ int spa_inited; /* initialized */
} spa_t;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/common/nvpair/fnvpair.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/cddl/contrib/opensolaris/common/nvpair/fnvpair.c Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,498 @@
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#include <sys/nvpair.h>
+#ifndef _KERNEL
+#include <sys/zfs_context.h>
+#else
+#include <sys/debug.h>
+#include <sys/kmem.h>
+#endif
+
+/*
+ * "Force" nvlist wrapper.
+ *
+ * These functions wrap the nvlist_* functions with assertions that assume
+ * the operation is successful. This allows the caller's code to be much
+ * more readable, especially for the fnvlist_lookup_* and fnvpair_value_*
+ * functions, which can return the requested value (rather than filling in
+ * a pointer).
+ *
+ * These functions use NV_UNIQUE_NAME, encoding NV_ENCODE_NATIVE, and allocate
+ * with KM_SLEEP.
+ *
+ * More wrappers should be added as needed -- for example
+ * nvlist_lookup_*_array and nvpair_value_*_array.
+ */
+
+nvlist_t *
+fnvlist_alloc(void)
+{
+ nvlist_t *nvl;
+ VERIFY3U(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP), ==, 0);
+ return (nvl);
+}
+
+void
+fnvlist_free(nvlist_t *nvl)
+{
+ nvlist_free(nvl);
+}
+
+size_t
+fnvlist_size(nvlist_t *nvl)
+{
+ size_t size;
+ VERIFY3U(nvlist_size(nvl, &size, NV_ENCODE_NATIVE), ==, 0);
+ return (size);
+}
+
+/*
+ * Returns allocated buffer of size *sizep. Caller must free the buffer with
+ * fnvlist_pack_free().
+ */
+char *
+fnvlist_pack(nvlist_t *nvl, size_t *sizep)
+{
+ char *packed = 0;
+ VERIFY3U(nvlist_pack(nvl, &packed, sizep, NV_ENCODE_NATIVE,
+ KM_SLEEP), ==, 0);
+ return (packed);
+}
+
+/*ARGSUSED*/
+void
+fnvlist_pack_free(char *pack, size_t size)
+{
+#ifdef _KERNEL
+ kmem_free(pack, size);
+#else
+ free(pack);
+#endif
+}
+
+nvlist_t *
+fnvlist_unpack(char *buf, size_t buflen)
+{
+ nvlist_t *rv;
+ VERIFY3U(nvlist_unpack(buf, buflen, &rv, KM_SLEEP), ==, 0);
+ return (rv);
+}
+
+nvlist_t *
+fnvlist_dup(nvlist_t *nvl)
+{
+ nvlist_t *rv;
+ VERIFY3U(nvlist_dup(nvl, &rv, KM_SLEEP), ==, 0);
+ return (rv);
+}
+
+void
+fnvlist_merge(nvlist_t *dst, nvlist_t *src)
+{
+ VERIFY3U(nvlist_merge(dst, src, KM_SLEEP), ==, 0);
+}
+
+void
+fnvlist_add_boolean(nvlist_t *nvl, const char *name)
+{
+ VERIFY3U(nvlist_add_boolean(nvl, name), ==, 0);
+}
+
+void
+fnvlist_add_boolean_value(nvlist_t *nvl, const char *name, boolean_t val)
+{
+ VERIFY3U(nvlist_add_boolean_value(nvl, name, val), ==, 0);
+}
+
+void
+fnvlist_add_byte(nvlist_t *nvl, const char *name, uchar_t val)
+{
+ VERIFY3U(nvlist_add_byte(nvl, name, val), ==, 0);
+}
+
+void
+fnvlist_add_int8(nvlist_t *nvl, const char *name, int8_t val)
+{
+ VERIFY3U(nvlist_add_int8(nvl, name, val), ==, 0);
+}
+
+void
+fnvlist_add_uint8(nvlist_t *nvl, const char *name, uint8_t val)
+{
+ VERIFY3U(nvlist_add_uint8(nvl, name, val), ==, 0);
+}
+
+void
+fnvlist_add_int16(nvlist_t *nvl, const char *name, int16_t val)
+{
+ VERIFY3U(nvlist_add_int16(nvl, name, val), ==, 0);
+}
+
+void
+fnvlist_add_uint16(nvlist_t *nvl, const char *name, uint16_t val)
+{
+ VERIFY3U(nvlist_add_uint16(nvl, name, val), ==, 0);
+}
+
+void
+fnvlist_add_int32(nvlist_t *nvl, const char *name, int32_t val)
+{
+ VERIFY3U(nvlist_add_int32(nvl, name, val), ==, 0);
+}
+
+void
+fnvlist_add_uint32(nvlist_t *nvl, const char *name, uint32_t val)
+{
+ VERIFY3U(nvlist_add_uint32(nvl, name, val), ==, 0);
+}
+
+void
+fnvlist_add_int64(nvlist_t *nvl, const char *name, int64_t val)
+{
+ VERIFY3U(nvlist_add_int64(nvl, name, val), ==, 0);
+}
+
+void
+fnvlist_add_uint64(nvlist_t *nvl, const char *name, uint64_t val)
+{
+ VERIFY3U(nvlist_add_uint64(nvl, name, val), ==, 0);
+}
+
+void
+fnvlist_add_string(nvlist_t *nvl, const char *name, const char *val)
+{
+ VERIFY3U(nvlist_add_string(nvl, name, val), ==, 0);
+}
+
+void
+fnvlist_add_nvlist(nvlist_t *nvl, const char *name, nvlist_t *val)
+{
+ VERIFY3U(nvlist_add_nvlist(nvl, name, val), ==, 0);
+}
+
+void
+fnvlist_add_nvpair(nvlist_t *nvl, nvpair_t *pair)
+{
+ VERIFY3U(nvlist_add_nvpair(nvl, pair), ==, 0);
+}
+
+void
+fnvlist_add_boolean_array(nvlist_t *nvl, const char *name,
+ boolean_t *val, uint_t n)
+{
+ VERIFY3U(nvlist_add_boolean_array(nvl, name, val, n), ==, 0);
+}
+
+void
+fnvlist_add_byte_array(nvlist_t *nvl, const char *name, uchar_t *val, uint_t n)
+{
+ VERIFY3U(nvlist_add_byte_array(nvl, name, val, n), ==, 0);
+}
+
+void
+fnvlist_add_int8_array(nvlist_t *nvl, const char *name, int8_t *val, uint_t n)
+{
+ VERIFY3U(nvlist_add_int8_array(nvl, name, val, n), ==, 0);
+}
+
+void
+fnvlist_add_uint8_array(nvlist_t *nvl, const char *name, uint8_t *val, uint_t n)
+{
+ VERIFY3U(nvlist_add_uint8_array(nvl, name, val, n), ==, 0);
+}
+
+void
+fnvlist_add_int16_array(nvlist_t *nvl, const char *name, int16_t *val, uint_t n)
+{
+ VERIFY3U(nvlist_add_int16_array(nvl, name, val, n), ==, 0);
+}
+
+void
+fnvlist_add_uint16_array(nvlist_t *nvl, const char *name,
+ uint16_t *val, uint_t n)
+{
+ VERIFY3U(nvlist_add_uint16_array(nvl, name, val, n), ==, 0);
+}
+
+void
+fnvlist_add_int32_array(nvlist_t *nvl, const char *name, int32_t *val, uint_t n)
+{
+ VERIFY3U(nvlist_add_int32_array(nvl, name, val, n), ==, 0);
+}
+
+void
+fnvlist_add_uint32_array(nvlist_t *nvl, const char *name,
+ uint32_t *val, uint_t n)
+{
+ VERIFY3U(nvlist_add_uint32_array(nvl, name, val, n), ==, 0);
+}
+
+void
+fnvlist_add_int64_array(nvlist_t *nvl, const char *name, int64_t *val, uint_t n)
+{
+ VERIFY3U(nvlist_add_int64_array(nvl, name, val, n), ==, 0);
+}
+
+void
+fnvlist_add_uint64_array(nvlist_t *nvl, const char *name,
+ uint64_t *val, uint_t n)
+{
+ VERIFY3U(nvlist_add_uint64_array(nvl, name, val, n), ==, 0);
+}
+
+void
+fnvlist_add_string_array(nvlist_t *nvl, const char *name,
+ char * const *val, uint_t n)
+{
+ VERIFY3U(nvlist_add_string_array(nvl, name, val, n), ==, 0);
+}
+
+void
+fnvlist_add_nvlist_array(nvlist_t *nvl, const char *name,
+ nvlist_t **val, uint_t n)
+{
+ VERIFY3U(nvlist_add_nvlist_array(nvl, name, val, n), ==, 0);
+}
+
+void
+fnvlist_remove(nvlist_t *nvl, const char *name)
+{
+ VERIFY3U(nvlist_remove_all(nvl, name), ==, 0);
+}
+
+void
+fnvlist_remove_nvpair(nvlist_t *nvl, nvpair_t *pair)
+{
+ VERIFY3U(nvlist_remove_nvpair(nvl, pair), ==, 0);
+}
+
+nvpair_t *
+fnvlist_lookup_nvpair(nvlist_t *nvl, const char *name)
+{
+ nvpair_t *rv;
+ VERIFY3U(nvlist_lookup_nvpair(nvl, name, &rv), ==, 0);
+ return (rv);
+}
+
+/* returns B_TRUE if the entry exists */
+boolean_t
+fnvlist_lookup_boolean(nvlist_t *nvl, const char *name)
+{
+ return (nvlist_lookup_boolean(nvl, name) == 0);
+}
+
+boolean_t
+fnvlist_lookup_boolean_value(nvlist_t *nvl, const char *name)
+{
+ boolean_t rv;
+ VERIFY3U(nvlist_lookup_boolean_value(nvl, name, &rv), ==, 0);
+ return (rv);
+}
+
+uchar_t
+fnvlist_lookup_byte(nvlist_t *nvl, const char *name)
+{
+ uchar_t rv;
+ VERIFY3U(nvlist_lookup_byte(nvl, name, &rv), ==, 0);
+ return (rv);
+}
+
+int8_t
+fnvlist_lookup_int8(nvlist_t *nvl, const char *name)
+{
+ int8_t rv;
+ VERIFY3U(nvlist_lookup_int8(nvl, name, &rv), ==, 0);
+ return (rv);
+}
+
+int16_t
+fnvlist_lookup_int16(nvlist_t *nvl, const char *name)
+{
+ int16_t rv;
+ VERIFY3U(nvlist_lookup_int16(nvl, name, &rv), ==, 0);
+ return (rv);
+}
+
+int32_t
+fnvlist_lookup_int32(nvlist_t *nvl, const char *name)
+{
+ int32_t rv;
+ VERIFY3U(nvlist_lookup_int32(nvl, name, &rv), ==, 0);
+ return (rv);
+}
+
+int64_t
+fnvlist_lookup_int64(nvlist_t *nvl, const char *name)
+{
+ int64_t rv;
+ VERIFY3U(nvlist_lookup_int64(nvl, name, &rv), ==, 0);
+ return (rv);
+}
+
+uint8_t
+fnvlist_lookup_uint8_t(nvlist_t *nvl, const char *name)
+{
+ uint8_t rv;
+ VERIFY3U(nvlist_lookup_uint8(nvl, name, &rv), ==, 0);
+ return (rv);
+}
+
+uint16_t
+fnvlist_lookup_uint16(nvlist_t *nvl, const char *name)
+{
+ uint16_t rv;
+ VERIFY3U(nvlist_lookup_uint16(nvl, name, &rv), ==, 0);
+ return (rv);
+}
+
+uint32_t
+fnvlist_lookup_uint32(nvlist_t *nvl, const char *name)
+{
+ uint32_t rv;
+ VERIFY3U(nvlist_lookup_uint32(nvl, name, &rv), ==, 0);
+ return (rv);
+}
+
+uint64_t
+fnvlist_lookup_uint64(nvlist_t *nvl, const char *name)
+{
+ uint64_t rv;
+ VERIFY3U(nvlist_lookup_uint64(nvl, name, &rv), ==, 0);
+ return (rv);
+}
+
+char *
+fnvlist_lookup_string(nvlist_t *nvl, const char *name)
+{
+ char *rv;
+ VERIFY3U(nvlist_lookup_string(nvl, name, &rv), ==, 0);
+ return (rv);
+}
+
+nvlist_t *
+fnvlist_lookup_nvlist(nvlist_t *nvl, const char *name)
+{
+ nvlist_t *rv;
+ VERIFY3U(nvlist_lookup_nvlist(nvl, name, &rv), ==, 0);
+ return (rv);
+}
+
+boolean_t
+fnvpair_value_boolean_value(nvpair_t *nvp)
+{
+ boolean_t rv;
+ VERIFY3U(nvpair_value_boolean_value(nvp, &rv), ==, 0);
+ return (rv);
+}
+
+uchar_t
+fnvpair_value_byte(nvpair_t *nvp)
+{
+ uchar_t rv;
+ VERIFY3U(nvpair_value_byte(nvp, &rv), ==, 0);
+ return (rv);
+}
+
+int8_t
+fnvpair_value_int8(nvpair_t *nvp)
+{
+ int8_t rv;
+ VERIFY3U(nvpair_value_int8(nvp, &rv), ==, 0);
+ return (rv);
+}
+
+int16_t
+fnvpair_value_int16(nvpair_t *nvp)
+{
+ int16_t rv;
+ VERIFY3U(nvpair_value_int16(nvp, &rv), ==, 0);
+ return (rv);
+}
+
+int32_t
+fnvpair_value_int32(nvpair_t *nvp)
+{
+ int32_t rv;
+ VERIFY3U(nvpair_value_int32(nvp, &rv), ==, 0);
+ return (rv);
+}
+
+int64_t
+fnvpair_value_int64(nvpair_t *nvp)
+{
+ int64_t rv;
+ VERIFY3U(nvpair_value_int64(nvp, &rv), ==, 0);
+ return (rv);
+}
+
+uint8_t
+fnvpair_value_uint8_t(nvpair_t *nvp)
+{
+ uint8_t rv;
+ VERIFY3U(nvpair_value_uint8(nvp, &rv), ==, 0);
+ return (rv);
+}
+
+uint16_t
+fnvpair_value_uint16(nvpair_t *nvp)
+{
+ uint16_t rv;
+ VERIFY3U(nvpair_value_uint16(nvp, &rv), ==, 0);
+ return (rv);
+}
+
+uint32_t
+fnvpair_value_uint32(nvpair_t *nvp)
+{
+ uint32_t rv;
+ VERIFY3U(nvpair_value_uint32(nvp, &rv), ==, 0);
+ return (rv);
+}
+
+uint64_t
+fnvpair_value_uint64(nvpair_t *nvp)
+{
+ uint64_t rv;
+ VERIFY3U(nvpair_value_uint64(nvp, &rv), ==, 0);
+ return (rv);
+}
+
+char *
+fnvpair_value_string(nvpair_t *nvp)
+{
+ char *rv;
+ VERIFY3U(nvpair_value_string(nvp, &rv), ==, 0);
+ return (rv);
+}
+
+nvlist_t *
+fnvpair_value_nvlist(nvpair_t *nvp)
+{
+ nvlist_t *rv;
+ VERIFY3U(nvpair_value_nvlist(nvp, &rv), ==, 0);
+ return (rv);
+}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,155 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#ifdef _KERNEL
+#include <sys/systm.h>
+#else
+#include <errno.h>
+#include <string.h>
+#endif
+#include <sys/debug.h>
+#include <sys/fs/zfs.h>
+#include <sys/types.h>
+#include "zfeature_common.h"
+
+/*
+ * Set to disable all feature checks while opening pools, allowing pools with
+ * unsupported features to be opened. Set for testing only.
+ */
+boolean_t zfeature_checks_disable = B_FALSE;
+
+zfeature_info_t spa_feature_table[SPA_FEATURES];
+
+/*
+ * Valid characters for feature guids. This list is mainly for aesthetic
+ * purposes and could be expanded in the future. There are different allowed
+ * characters in the guids reverse dns portion (before the colon) and its
+ * short name (after the colon).
+ */
+static int
+valid_char(char c, boolean_t after_colon)
+{
+ return ((c >= 'a' && c <= 'z') ||
+ (c >= '0' && c <= '9') ||
+ c == (after_colon ? '_' : '.'));
+}
+
+/*
+ * Every feature guid must contain exactly one colon which separates a reverse
+ * dns organization name from the feature's "short" name (e.g.
+ * "com.company:feature_name").
+ */
+boolean_t
+zfeature_is_valid_guid(const char *name)
+{
+ int i;
+ boolean_t has_colon = B_FALSE;
+
+ i = 0;
+ while (name[i] != '\0') {
+ char c = name[i++];
+ if (c == ':') {
+ if (has_colon)
+ return (B_FALSE);
+ has_colon = B_TRUE;
+ continue;
+ }
+ if (!valid_char(c, has_colon))
+ return (B_FALSE);
+ }
+
+ return (has_colon);
+}
+
+boolean_t
+zfeature_is_supported(const char *guid)
+{
+ if (zfeature_checks_disable)
+ return (B_TRUE);
+
+ return (0 == zfeature_lookup_guid(guid, NULL));
+}
+
+int
+zfeature_lookup_guid(const char *guid, zfeature_info_t **res)
+{
+ for (int i = 0; i < SPA_FEATURES; i++) {
+ zfeature_info_t *feature = &spa_feature_table[i];
+ if (strcmp(guid, feature->fi_guid) == 0) {
+ if (res != NULL)
+ *res = feature;
+ return (0);
+ }
+ }
+
+ return (ENOENT);
+}
+
+int
+zfeature_lookup_name(const char *name, zfeature_info_t **res)
+{
+ for (int i = 0; i < SPA_FEATURES; i++) {
+ zfeature_info_t *feature = &spa_feature_table[i];
+ if (strcmp(name, feature->fi_uname) == 0) {
+ if (res != NULL)
+ *res = feature;
+ return (0);
+ }
+ }
+
+ return (ENOENT);
+}
+
+static void
+zfeature_register(int fid, const char *guid, const char *name, const char *desc,
+ boolean_t readonly, boolean_t mos, zfeature_info_t **deps)
+{
+ zfeature_info_t *feature = &spa_feature_table[fid];
+ static zfeature_info_t *nodeps[] = { NULL };
+
+ ASSERT(name != NULL);
+ ASSERT(desc != NULL);
+ ASSERT(!readonly || !mos);
+ ASSERT3U(fid, <, SPA_FEATURES);
+ ASSERT(zfeature_is_valid_guid(guid));
+
+ if (deps == NULL)
+ deps = nodeps;
+
+ feature->fi_guid = guid;
+ feature->fi_uname = name;
+ feature->fi_desc = desc;
+ feature->fi_can_readonly = readonly;
+ feature->fi_mos = mos;
+ feature->fi_depends = deps;
+}
+
+void
+zpool_feature_init(void)
+{
+ zfeature_register(SPA_FEATURE_ASYNC_DESTROY,
+ "com.delphix:async_destroy", "async_destroy",
+ "Destroy filesystems asynchronously.", B_TRUE, B_FALSE, NULL);
+}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#ifndef _ZFEATURE_COMMON_H
+#define _ZFEATURE_COMMON_H
+
+#include <sys/fs/zfs.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct zfeature_info;
+
+typedef struct zfeature_info {
+ const char *fi_uname; /* User-facing feature name */
+ const char *fi_guid; /* On-disk feature identifier */
+ const char *fi_desc; /* Feature description */
+ boolean_t fi_can_readonly; /* Can open pool readonly w/o support? */
+ boolean_t fi_mos; /* Is the feature necessary to read the MOS? */
+ struct zfeature_info **fi_depends; /* array; null terminated */
+} zfeature_info_t;
+
+typedef int (zfeature_func_t)(zfeature_info_t *fi, void *arg);
+
+#define ZFS_FEATURE_DEBUG
+
+static enum spa_feature {
+ SPA_FEATURE_ASYNC_DESTROY,
+ SPA_FEATURES
+} spa_feature_t;
+
+extern zfeature_info_t spa_feature_table[SPA_FEATURES];
+
+extern boolean_t zfeature_is_valid_guid(const char *);
+
+extern boolean_t zfeature_is_supported(const char *);
+extern int zfeature_lookup_guid(const char *, zfeature_info_t **res);
+extern int zfeature_lookup_name(const char *, zfeature_info_t **res);
+
+extern void zpool_feature_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ZFEATURE_COMMON_H */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c
--- a/head/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c Wed Jul 25 16:45:04 2012 +0300
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/zio.h>
@@ -79,8 +79,12 @@
ZFS_TYPE_POOL, "<size>", "SIZE");
zprop_register_number(ZPOOL_PROP_FREE, "free", 0, PROP_READONLY,
ZFS_TYPE_POOL, "<size>", "FREE");
+ zprop_register_number(ZPOOL_PROP_FREEING, "freeing", 0, PROP_READONLY,
+ ZFS_TYPE_POOL, "<size>", "FREEING");
zprop_register_number(ZPOOL_PROP_ALLOCATED, "allocated", 0,
PROP_READONLY, ZFS_TYPE_POOL, "<size>", "ALLOC");
+ zprop_register_number(ZPOOL_PROP_EXPANDSZ, "expandsize", 0,
+ PROP_READONLY, ZFS_TYPE_POOL, "<size>", "EXPANDSZ");
zprop_register_number(ZPOOL_PROP_CAPACITY, "capacity", 0, PROP_READONLY,
ZFS_TYPE_POOL, "<size>", "CAP");
zprop_register_number(ZPOOL_PROP_GUID, "guid", 0, PROP_READONLY,
@@ -164,6 +168,26 @@
return (zpool_prop_table[prop].pd_numdefault);
}
+/*
+ * Returns true if this is a valid feature@ property.
+ */
+boolean_t
+zpool_prop_feature(const char *name)
+{
+ static const char *prefix = "feature@";
+ return (strncmp(name, prefix, strlen(prefix)) == 0);
+}
+
+/*
+ * Returns true if this is a valid unsupported@ property.
+ */
+boolean_t
+zpool_prop_unsupported(const char *name)
+{
+ static const char *prefix = "unsupported@";
+ return (strncmp(name, prefix, strlen(prefix)) == 0);
+}
+
int
zpool_prop_string_to_index(zpool_prop_t prop, const char *string,
uint64_t *index)
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/Makefile.files
--- a/head/sys/cddl/contrib/opensolaris/uts/common/Makefile.files Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/Makefile.files Wed Jul 25 16:45:04 2012 +0300
@@ -21,6 +21,7 @@
#
# Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012 by Delphix. All rights reserved.
#
#
# This Makefile defines all file modules for the directory uts/common
@@ -31,6 +32,7 @@
arc.o \
bplist.o \
bpobj.o \
+ bptree.o \
dbuf.o \
ddt.o \
ddt_zap.o \
@@ -52,6 +54,7 @@
dsl_deleg.o \
dsl_prop.o \
dsl_scan.o \
+ zfeature.o \
gzip.o \
lzjb.o \
metaslab.o \
@@ -94,11 +97,12 @@
zrlock.o
ZFS_SHARED_OBJS += \
+ zfeature_common.o \
+ zfs_comutil.o \
+ zfs_deleg.o \
+ zfs_fletcher.o \
zfs_namecheck.o \
- zfs_deleg.o \
zfs_prop.o \
- zfs_comutil.o \
- zfs_fletcher.o \
zpool_prop.o \
zprop_common.o
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c Wed Jul 25 16:45:04 2012 +0300
@@ -18,7 +18,7 @@
*
* CDDL HEADER END
*
- * $FreeBSD: head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c 233408 2012-03-24 04:52:18Z gonzo $
+ * $FreeBSD: head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c 237817 2012-06-29 18:49:14Z pfg $
*/
/*
@@ -157,7 +157,7 @@
size_t dtrace_global_maxsize = (16 * 1024);
size_t dtrace_actions_max = (16 * 1024);
size_t dtrace_retain_max = 1024;
-dtrace_optval_t dtrace_helper_actions_max = 32;
+dtrace_optval_t dtrace_helper_actions_max = 128;
dtrace_optval_t dtrace_helper_providers_max = 32;
dtrace_optval_t dtrace_dstate_defsize = (1 * 1024 * 1024);
size_t dtrace_strsize_default = 256;
@@ -1913,6 +1913,75 @@
lquanta[levels + 1] += incr;
}
+static int
+dtrace_aggregate_llquantize_bucket(uint16_t factor, uint16_t low,
+ uint16_t high, uint16_t nsteps, int64_t value)
+{
+ int64_t this = 1, last, next;
+ int base = 1, order;
+
+ ASSERT(factor <= nsteps);
+ ASSERT(nsteps % factor == 0);
+
+ for (order = 0; order < low; order++)
+ this *= factor;
+
+ /*
+ * If our value is less than our factor taken to the power of the
+ * low order of magnitude, it goes into the zeroth bucket.
+ */
+ if (value < (last = this))
+ return (0);
+
+ for (this *= factor; order <= high; order++) {
+ int nbuckets = this > nsteps ? nsteps : this;
+
+ if ((next = this * factor) < this) {
+ /*
+ * We should not generally get log/linear quantizations
+ * with a high magnitude that allows 64-bits to
+ * overflow, but we nonetheless protect against this
+ * by explicitly checking for overflow, and clamping
+ * our value accordingly.
+ */
+ value = this - 1;
+ }
+
+ if (value < this) {
+ /*
+ * If our value lies within this order of magnitude,
+ * determine its position by taking the offset within
+ * the order of magnitude, dividing by the bucket
+ * width, and adding to our (accumulated) base.
+ */
+ return (base + (value - last) / (this / nbuckets));
+ }
+
+ base += nbuckets - (nbuckets / factor);
+ last = this;
+ this = next;
+ }
+
+ /*
+ * Our value is greater than or equal to our factor taken to the
+ * power of one plus the high magnitude -- return the top bucket.
+ */
+ return (base);
+}
+
+static void
+dtrace_aggregate_llquantize(uint64_t *llquanta, uint64_t nval, uint64_t incr)
+{
+ uint64_t arg = *llquanta++;
+ uint16_t factor = DTRACE_LLQUANTIZE_FACTOR(arg);
+ uint16_t low = DTRACE_LLQUANTIZE_LOW(arg);
+ uint16_t high = DTRACE_LLQUANTIZE_HIGH(arg);
+ uint16_t nsteps = DTRACE_LLQUANTIZE_NSTEP(arg);
+
+ llquanta[dtrace_aggregate_llquantize_bucket(factor,
+ low, high, nsteps, nval)] += incr;
+}
+
/*ARGSUSED*/
static void
dtrace_aggregate_avg(uint64_t *data, uint64_t nval, uint64_t arg)
@@ -3143,6 +3212,11 @@
return (curthread->td_errno);
#endif
}
+#if !defined(sun)
+ case DIF_VAR_CPU: {
+ return curcpu;
+ }
+#endif
default:
DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
return (0);
@@ -9848,6 +9922,35 @@
break;
}
+ case DTRACEAGG_LLQUANTIZE: {
+ uint16_t factor = DTRACE_LLQUANTIZE_FACTOR(desc->dtad_arg);
+ uint16_t low = DTRACE_LLQUANTIZE_LOW(desc->dtad_arg);
+ uint16_t high = DTRACE_LLQUANTIZE_HIGH(desc->dtad_arg);
+ uint16_t nsteps = DTRACE_LLQUANTIZE_NSTEP(desc->dtad_arg);
+ int64_t v;
+
+ agg->dtag_initial = desc->dtad_arg;
+ agg->dtag_aggregate = dtrace_aggregate_llquantize;
+
+ if (factor < 2 || low >= high || nsteps < factor)
+ goto err;
+
+ /*
+ * Now check that the number of steps evenly divides a power
+ * of the factor. (This assures both integer bucket size and
+ * linearity within each magnitude.)
+ */
+ for (v = factor; v < nsteps; v *= factor)
+ continue;
+
+ if ((v % nsteps) || (nsteps % factor))
+ goto err;
+
+ size = (dtrace_aggregate_llquantize_bucket(factor,
+ low, high, nsteps, INT64_MAX) + 2) * sizeof (uint64_t);
+ break;
+ }
+
case DTRACEAGG_AVG:
agg->dtag_aggregate = dtrace_aggregate_avg;
size = sizeof (uint64_t) * 2;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Wed Jul 25 16:45:04 2012 +0300
@@ -2794,9 +2794,11 @@
callback_list = hdr->b_acb;
ASSERT(callback_list != NULL);
if (BP_SHOULD_BYTESWAP(zio->io_bp) && zio->io_error == 0) {
+ dmu_object_byteswap_t bswap =
+ DMU_OT_BYTESWAP(BP_GET_TYPE(zio->io_bp));
arc_byteswap_func_t *func = BP_GET_LEVEL(zio->io_bp) > 0 ?
byteswap_uint64_array :
- dmu_ot[BP_GET_TYPE(zio->io_bp)].ot_byteswap;
+ dmu_ot_byteswap[bswap].ob_func;
func(buf->b_data, hdr->b_size);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,224 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#include <sys/arc.h>
+#include <sys/bptree.h>
+#include <sys/dmu.h>
+#include <sys/dmu_objset.h>
+#include <sys/dmu_tx.h>
+#include <sys/dmu_traverse.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_pool.h>
+#include <sys/dnode.h>
+#include <sys/refcount.h>
+#include <sys/spa.h>
+
+/*
+ * A bptree is a queue of root block pointers from destroyed datasets. When a
+ * dataset is destroyed its root block pointer is put on the end of the pool's
+ * bptree queue so the dataset's blocks can be freed asynchronously by
+ * dsl_scan_sync. This allows the delete operation to finish without traversing
+ * all the dataset's blocks.
+ *
+ * Note that while bt_begin and bt_end are only ever incremented in this code
+ * they are effectively reset to 0 every time the entire bptree is freed because
+ * the bptree's object is destroyed and re-created.
+ */
+
+struct bptree_args {
+ bptree_phys_t *ba_phys; /* data in bonus buffer, dirtied if freeing */
+ boolean_t ba_free; /* true if freeing during traversal */
+
+ bptree_itor_t *ba_func; /* function to call for each blockpointer */
+ void *ba_arg; /* caller supplied argument to ba_func */
+ dmu_tx_t *ba_tx; /* caller supplied tx, NULL if not freeing */
+} bptree_args_t;
+
+uint64_t
+bptree_alloc(objset_t *os, dmu_tx_t *tx)
+{
+ uint64_t obj;
+ dmu_buf_t *db;
+ bptree_phys_t *bt;
+
+ obj = dmu_object_alloc(os, DMU_OTN_UINT64_METADATA,
+ SPA_MAXBLOCKSIZE, DMU_OTN_UINT64_METADATA,
+ sizeof (bptree_phys_t), tx);
+
+ /*
+ * Bonus buffer contents are already initialized to 0, but for
+ * readability we make it explicit.
+ */
+ VERIFY3U(0, ==, dmu_bonus_hold(os, obj, FTAG, &db));
+ dmu_buf_will_dirty(db, tx);
+ bt = db->db_data;
+ bt->bt_begin = 0;
+ bt->bt_end = 0;
+ bt->bt_bytes = 0;
+ bt->bt_comp = 0;
+ bt->bt_uncomp = 0;
+ dmu_buf_rele(db, FTAG);
+
+ return (obj);
+}
+
+int
+bptree_free(objset_t *os, uint64_t obj, dmu_tx_t *tx)
+{
+ dmu_buf_t *db;
+ bptree_phys_t *bt;
+
+ VERIFY3U(0, ==, dmu_bonus_hold(os, obj, FTAG, &db));
+ bt = db->db_data;
+ ASSERT3U(bt->bt_begin, ==, bt->bt_end);
+ ASSERT3U(bt->bt_bytes, ==, 0);
+ ASSERT3U(bt->bt_comp, ==, 0);
+ ASSERT3U(bt->bt_uncomp, ==, 0);
+ dmu_buf_rele(db, FTAG);
+
+ return (dmu_object_free(os, obj, tx));
+}
+
+void
+bptree_add(objset_t *os, uint64_t obj, blkptr_t *bp, uint64_t birth_txg,
+ uint64_t bytes, uint64_t comp, uint64_t uncomp, dmu_tx_t *tx)
+{
+ dmu_buf_t *db;
+ bptree_phys_t *bt;
+ bptree_entry_phys_t bte;
+
+ /*
+ * bptree objects are in the pool mos, therefore they can only be
+ * modified in syncing context. Furthermore, this is only modified
+ * by the sync thread, so no locking is necessary.
+ */
+ ASSERT(dmu_tx_is_syncing(tx));
+
+ VERIFY3U(0, ==, dmu_bonus_hold(os, obj, FTAG, &db));
+ bt = db->db_data;
+
+ bte.be_birth_txg = birth_txg;
+ bte.be_bp = *bp;
+ bzero(&bte.be_zb, sizeof (bte.be_zb));
+ dmu_write(os, obj, bt->bt_end * sizeof (bte), sizeof (bte), &bte, tx);
+
+ dmu_buf_will_dirty(db, tx);
+ bt->bt_end++;
+ bt->bt_bytes += bytes;
+ bt->bt_comp += comp;
+ bt->bt_uncomp += uncomp;
+ dmu_buf_rele(db, FTAG);
+}
+
+/* ARGSUSED */
+static int
+bptree_visit_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, arc_buf_t *pbuf,
+ const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg)
+{
+ int err;
+ struct bptree_args *ba = arg;
+
+ if (bp == NULL)
+ return (0);
+
+ err = ba->ba_func(ba->ba_arg, bp, ba->ba_tx);
+ if (err == 0 && ba->ba_free) {
+ ba->ba_phys->bt_bytes -= bp_get_dsize_sync(spa, bp);
+ ba->ba_phys->bt_comp -= BP_GET_PSIZE(bp);
+ ba->ba_phys->bt_uncomp -= BP_GET_UCSIZE(bp);
+ }
+ return (err);
+}
+
+int
+bptree_iterate(objset_t *os, uint64_t obj, boolean_t free, bptree_itor_t func,
+ void *arg, dmu_tx_t *tx)
+{
+ int err;
+ uint64_t i;
+ dmu_buf_t *db;
+ struct bptree_args ba;
+
+ ASSERT(!free || dmu_tx_is_syncing(tx));
+
+ err = dmu_bonus_hold(os, obj, FTAG, &db);
+ if (err != 0)
+ return (err);
+
+ if (free)
+ dmu_buf_will_dirty(db, tx);
+
+ ba.ba_phys = db->db_data;
+ ba.ba_free = free;
+ ba.ba_func = func;
+ ba.ba_arg = arg;
+ ba.ba_tx = tx;
+
+ err = 0;
+ for (i = ba.ba_phys->bt_begin; i < ba.ba_phys->bt_end; i++) {
+ bptree_entry_phys_t bte;
+
+ ASSERT(!free || i == ba.ba_phys->bt_begin);
+
+ err = dmu_read(os, obj, i * sizeof (bte), sizeof (bte),
+ &bte, DMU_READ_NO_PREFETCH);
+ if (err != 0)
+ break;
+
+ err = traverse_dataset_destroyed(os->os_spa, &bte.be_bp,
+ bte.be_birth_txg, &bte.be_zb, TRAVERSE_POST,
+ bptree_visit_cb, &ba);
+ if (free) {
+ ASSERT(err == 0 || err == ERESTART);
+ if (err != 0) {
+ /* save bookmark for future resume */
+ ASSERT3U(bte.be_zb.zb_objset, ==,
+ ZB_DESTROYED_OBJSET);
+ ASSERT3U(bte.be_zb.zb_level, ==, 0);
+ dmu_write(os, obj, i * sizeof (bte),
+ sizeof (bte), &bte, tx);
+ break;
+ } else {
+ ba.ba_phys->bt_begin++;
+ (void) dmu_free_range(os, obj,
+ i * sizeof (bte), sizeof (bte), tx);
+ }
+ }
+ }
+
+ ASSERT(!free || err != 0 || ba.ba_phys->bt_begin == ba.ba_phys->bt_end);
+
+ /* if all blocks are free there should be no used space */
+ if (ba.ba_phys->bt_begin == ba.ba_phys->bt_end) {
+ ASSERT3U(ba.ba_phys->bt_bytes, ==, 0);
+ ASSERT3U(ba.ba_phys->bt_comp, ==, 0);
+ ASSERT3U(ba.ba_phys->bt_uncomp, ==, 0);
+ }
+
+ dmu_buf_rele(db, FTAG);
+
+ return (err);
+}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c Wed Jul 25 16:45:04 2012 +0300
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@@ -227,7 +228,7 @@
boolean_t is_metadata;
DB_DNODE_ENTER(db);
- is_metadata = dmu_ot[DB_DNODE(db)->dn_type].ot_metadata;
+ is_metadata = DMU_OT_IS_METADATA(DB_DNODE(db)->dn_type);
DB_DNODE_EXIT(db);
return (is_metadata);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c Wed Jul 25 16:45:04 2012 +0300
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@@ -1067,11 +1068,9 @@
ASSERT(spa->spa_uberblock.ub_version >= SPA_VERSION_DEDUP);
if (spa->spa_ddt_stat_object == 0) {
- spa->spa_ddt_stat_object = zap_create(ddt->ddt_os,
- DMU_OT_DDT_STATS, DMU_OT_NONE, 0, tx);
- VERIFY(zap_add(ddt->ddt_os, DMU_POOL_DIRECTORY_OBJECT,
- DMU_POOL_DDT_STATS, sizeof (uint64_t), 1,
- &spa->spa_ddt_stat_object, tx) == 0);
+ spa->spa_ddt_stat_object = zap_create_link(ddt->ddt_os,
+ DMU_OT_DDT_STATS, DMU_POOL_DIRECTORY_OBJECT,
+ DMU_POOL_DDT_STATS, tx);
}
while ((dde = avl_destroy_nodes(&ddt->ddt_tree, &cookie)) != NULL) {
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c Wed Jul 25 16:45:04 2012 +0300
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/dmu.h>
@@ -45,60 +46,73 @@
#endif
const dmu_object_type_info_t dmu_ot[DMU_OT_NUMTYPES] = {
- { byteswap_uint8_array, TRUE, "unallocated" },
- { zap_byteswap, TRUE, "object directory" },
- { byteswap_uint64_array, TRUE, "object array" },
- { byteswap_uint8_array, TRUE, "packed nvlist" },
- { byteswap_uint64_array, TRUE, "packed nvlist size" },
- { byteswap_uint64_array, TRUE, "bpobj" },
- { byteswap_uint64_array, TRUE, "bpobj header" },
- { byteswap_uint64_array, TRUE, "SPA space map header" },
- { byteswap_uint64_array, TRUE, "SPA space map" },
- { byteswap_uint64_array, TRUE, "ZIL intent log" },
- { dnode_buf_byteswap, TRUE, "DMU dnode" },
- { dmu_objset_byteswap, TRUE, "DMU objset" },
- { byteswap_uint64_array, TRUE, "DSL directory" },
- { zap_byteswap, TRUE, "DSL directory child map"},
- { zap_byteswap, TRUE, "DSL dataset snap map" },
- { zap_byteswap, TRUE, "DSL props" },
- { byteswap_uint64_array, TRUE, "DSL dataset" },
- { zfs_znode_byteswap, TRUE, "ZFS znode" },
- { zfs_oldacl_byteswap, TRUE, "ZFS V0 ACL" },
- { byteswap_uint8_array, FALSE, "ZFS plain file" },
- { zap_byteswap, TRUE, "ZFS directory" },
- { zap_byteswap, TRUE, "ZFS master node" },
- { zap_byteswap, TRUE, "ZFS delete queue" },
- { byteswap_uint8_array, FALSE, "zvol object" },
- { zap_byteswap, TRUE, "zvol prop" },
- { byteswap_uint8_array, FALSE, "other uint8[]" },
- { byteswap_uint64_array, FALSE, "other uint64[]" },
- { zap_byteswap, TRUE, "other ZAP" },
- { zap_byteswap, TRUE, "persistent error log" },
- { byteswap_uint8_array, TRUE, "SPA history" },
- { byteswap_uint64_array, TRUE, "SPA history offsets" },
- { zap_byteswap, TRUE, "Pool properties" },
- { zap_byteswap, TRUE, "DSL permissions" },
- { zfs_acl_byteswap, TRUE, "ZFS ACL" },
- { byteswap_uint8_array, TRUE, "ZFS SYSACL" },
- { byteswap_uint8_array, TRUE, "FUID table" },
- { byteswap_uint64_array, TRUE, "FUID table size" },
- { zap_byteswap, TRUE, "DSL dataset next clones"},
- { zap_byteswap, TRUE, "scan work queue" },
- { zap_byteswap, TRUE, "ZFS user/group used" },
- { zap_byteswap, TRUE, "ZFS user/group quota" },
- { zap_byteswap, TRUE, "snapshot refcount tags"},
- { zap_byteswap, TRUE, "DDT ZAP algorithm" },
- { zap_byteswap, TRUE, "DDT statistics" },
- { byteswap_uint8_array, TRUE, "System attributes" },
- { zap_byteswap, TRUE, "SA master node" },
- { zap_byteswap, TRUE, "SA attr registration" },
- { zap_byteswap, TRUE, "SA attr layouts" },
- { zap_byteswap, TRUE, "scan translations" },
- { byteswap_uint8_array, FALSE, "deduplicated block" },
- { zap_byteswap, TRUE, "DSL deadlist map" },
- { byteswap_uint64_array, TRUE, "DSL deadlist map hdr" },
- { zap_byteswap, TRUE, "DSL dir clones" },
- { byteswap_uint64_array, TRUE, "bpobj subobj" },
+ { DMU_BSWAP_UINT8, TRUE, "unallocated" },
+ { DMU_BSWAP_ZAP, TRUE, "object directory" },
+ { DMU_BSWAP_UINT64, TRUE, "object array" },
+ { DMU_BSWAP_UINT8, TRUE, "packed nvlist" },
+ { DMU_BSWAP_UINT64, TRUE, "packed nvlist size" },
+ { DMU_BSWAP_UINT64, TRUE, "bpobj" },
+ { DMU_BSWAP_UINT64, TRUE, "bpobj header" },
+ { DMU_BSWAP_UINT64, TRUE, "SPA space map header" },
+ { DMU_BSWAP_UINT64, TRUE, "SPA space map" },
+ { DMU_BSWAP_UINT64, TRUE, "ZIL intent log" },
+ { DMU_BSWAP_DNODE, TRUE, "DMU dnode" },
+ { DMU_BSWAP_OBJSET, TRUE, "DMU objset" },
+ { DMU_BSWAP_UINT64, TRUE, "DSL directory" },
+ { DMU_BSWAP_ZAP, TRUE, "DSL directory child map"},
+ { DMU_BSWAP_ZAP, TRUE, "DSL dataset snap map" },
+ { DMU_BSWAP_ZAP, TRUE, "DSL props" },
+ { DMU_BSWAP_UINT64, TRUE, "DSL dataset" },
+ { DMU_BSWAP_ZNODE, TRUE, "ZFS znode" },
+ { DMU_BSWAP_OLDACL, TRUE, "ZFS V0 ACL" },
+ { DMU_BSWAP_UINT8, FALSE, "ZFS plain file" },
+ { DMU_BSWAP_ZAP, TRUE, "ZFS directory" },
+ { DMU_BSWAP_ZAP, TRUE, "ZFS master node" },
+ { DMU_BSWAP_ZAP, TRUE, "ZFS delete queue" },
+ { DMU_BSWAP_UINT8, FALSE, "zvol object" },
+ { DMU_BSWAP_ZAP, TRUE, "zvol prop" },
+ { DMU_BSWAP_UINT8, FALSE, "other uint8[]" },
+ { DMU_BSWAP_UINT64, FALSE, "other uint64[]" },
+ { DMU_BSWAP_ZAP, TRUE, "other ZAP" },
+ { DMU_BSWAP_ZAP, TRUE, "persistent error log" },
+ { DMU_BSWAP_UINT8, TRUE, "SPA history" },
+ { DMU_BSWAP_UINT64, TRUE, "SPA history offsets" },
+ { DMU_BSWAP_ZAP, TRUE, "Pool properties" },
+ { DMU_BSWAP_ZAP, TRUE, "DSL permissions" },
+ { DMU_BSWAP_ACL, TRUE, "ZFS ACL" },
+ { DMU_BSWAP_UINT8, TRUE, "ZFS SYSACL" },
+ { DMU_BSWAP_UINT8, TRUE, "FUID table" },
+ { DMU_BSWAP_UINT64, TRUE, "FUID table size" },
+ { DMU_BSWAP_ZAP, TRUE, "DSL dataset next clones"},
+ { DMU_BSWAP_ZAP, TRUE, "scan work queue" },
+ { DMU_BSWAP_ZAP, TRUE, "ZFS user/group used" },
+ { DMU_BSWAP_ZAP, TRUE, "ZFS user/group quota" },
+ { DMU_BSWAP_ZAP, TRUE, "snapshot refcount tags"},
+ { DMU_BSWAP_ZAP, TRUE, "DDT ZAP algorithm" },
+ { DMU_BSWAP_ZAP, TRUE, "DDT statistics" },
+ { DMU_BSWAP_UINT8, TRUE, "System attributes" },
+ { DMU_BSWAP_ZAP, TRUE, "SA master node" },
+ { DMU_BSWAP_ZAP, TRUE, "SA attr registration" },
+ { DMU_BSWAP_ZAP, TRUE, "SA attr layouts" },
+ { DMU_BSWAP_ZAP, TRUE, "scan translations" },
+ { DMU_BSWAP_UINT8, FALSE, "deduplicated block" },
+ { DMU_BSWAP_ZAP, TRUE, "DSL deadlist map" },
+ { DMU_BSWAP_UINT64, TRUE, "DSL deadlist map hdr" },
+ { DMU_BSWAP_ZAP, TRUE, "DSL dir clones" },
+ { DMU_BSWAP_UINT64, TRUE, "bpobj subobj" }
+};
+
+const dmu_object_byteswap_info_t dmu_ot_byteswap[DMU_BSWAP_NUMFUNCS] = {
+ { byteswap_uint8_array, "uint8" },
+ { byteswap_uint16_array, "uint16" },
+ { byteswap_uint32_array, "uint32" },
+ { byteswap_uint64_array, "uint64" },
+ { zap_byteswap, "zap" },
+ { dnode_buf_byteswap, "dnode" },
+ { dmu_objset_byteswap, "objset" },
+ { zfs_znode_byteswap, "znode" },
+ { zfs_oldacl_byteswap, "oldacl" },
+ { zfs_acl_byteswap, "acl" }
};
int
@@ -175,7 +189,7 @@
DB_DNODE_ENTER(db);
dn = DB_DNODE(db);
- if (type > DMU_OT_NUMTYPES) {
+ if (!DMU_OT_IS_VALID(type)) {
error = EINVAL;
} else if (dn->dn_bonus != db) {
error = EINVAL;
@@ -1513,7 +1527,7 @@
dmu_write_policy(objset_t *os, dnode_t *dn, int level, int wp, zio_prop_t *zp)
{
dmu_object_type_t type = dn ? dn->dn_type : DMU_OT_OBJSET;
- boolean_t ismd = (level > 0 || dmu_ot[type].ot_metadata ||
+ boolean_t ismd = (level > 0 || DMU_OT_IS_METADATA(type) ||
(wp & WP_SPILL));
enum zio_checksum checksum = os->os_checksum;
enum zio_compress compress = os->os_compress;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c Wed Jul 25 16:45:04 2012 +0300
@@ -20,11 +20,10 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
- */
-/*
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2012, Martin Matuska <mm at FreeBSD.org>. All rights reserved.
*/
#include <sys/dmu.h>
@@ -54,38 +53,15 @@
static char *dmu_recv_tag = "dmu_recv_tag";
-/*
- * The list of data whose inclusion in a send stream can be pending from
- * one call to backup_cb to another. Multiple calls to dump_free() and
- * dump_freeobjects() can be aggregated into a single DRR_FREE or
- * DRR_FREEOBJECTS replay record.
- */
-typedef enum {
- PENDING_NONE,
- PENDING_FREE,
- PENDING_FREEOBJECTS
-} pendop_t;
-
-struct backuparg {
- dmu_replay_record_t *drr;
- kthread_t *td;
- struct file *fp;
- offset_t *off;
- objset_t *os;
- zio_cksum_t zc;
- uint64_t toguid;
- int err;
- pendop_t pending_op;
-};
-
static int
-dump_bytes(struct backuparg *ba, void *buf, int len)
+dump_bytes(dmu_sendarg_t *dsp, void *buf, int len)
{
+ dsl_dataset_t *ds = dsp->dsa_os->os_dsl_dataset;
struct uio auio;
struct iovec aiov;
ASSERT3U(len % 8, ==, 0);
- fletcher_4_incremental_native(buf, len, &ba->zc);
+ fletcher_4_incremental_native(buf, len, &dsp->dsa_zc);
aiov.iov_base = buf;
aiov.iov_len = len;
auio.uio_iov = &aiov;
@@ -94,24 +70,31 @@
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_rw = UIO_WRITE;
auio.uio_offset = (off_t)-1;
- auio.uio_td = ba->td;
+ auio.uio_td = dsp->dsa_td;
#ifdef _KERNEL
- if (ba->fp->f_type == DTYPE_VNODE)
+ if (dsp->dsa_fp->f_type == DTYPE_VNODE)
bwillwrite();
- ba->err = fo_write(ba->fp, &auio, ba->td->td_ucred, 0, ba->td);
+ dsp->dsa_err = fo_write(dsp->dsa_fp, &auio, dsp->dsa_td->td_ucred, 0,
+ dsp->dsa_td);
#else
fprintf(stderr, "%s: returning EOPNOTSUPP\n", __func__);
- ba->err = EOPNOTSUPP;
+ dsp->dsa_err = EOPNOTSUPP;
#endif
- *ba->off += len;
- return (ba->err);
+ mutex_enter(&ds->ds_sendstream_lock);
+ *dsp->dsa_off += len;
+ mutex_exit(&ds->ds_sendstream_lock);
+
+ return (dsp->dsa_err);
}
static int
-dump_free(struct backuparg *ba, uint64_t object, uint64_t offset,
+dump_free(dmu_sendarg_t *dsp, uint64_t object, uint64_t offset,
uint64_t length)
{
- struct drr_free *drrf = &(ba->drr->drr_u.drr_free);
+ struct drr_free *drrf = &(dsp->dsa_drr->drr_u.drr_free);
+
+ if (length != -1ULL && offset + length < offset)
+ length = -1ULL;
/*
* If there is a pending op, but it's not PENDING_FREE, push it out,
@@ -120,13 +103,15 @@
* other DRR_FREE records. DRR_FREEOBJECTS records can only be
* aggregated with other DRR_FREEOBJECTS records.
*/
- if (ba->pending_op != PENDING_NONE && ba->pending_op != PENDING_FREE) {
- if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)) != 0)
+ if (dsp->dsa_pending_op != PENDING_NONE &&
+ dsp->dsa_pending_op != PENDING_FREE) {
+ if (dump_bytes(dsp, dsp->dsa_drr,
+ sizeof (dmu_replay_record_t)) != 0)
return (EINTR);
- ba->pending_op = PENDING_NONE;
+ dsp->dsa_pending_op = PENDING_NONE;
}
- if (ba->pending_op == PENDING_FREE) {
+ if (dsp->dsa_pending_op == PENDING_FREE) {
/*
* There should never be a PENDING_FREE if length is -1
* (because dump_dnode is the only place where this
@@ -144,34 +129,35 @@
return (0);
} else {
/* not a continuation. Push out pending record */
- if (dump_bytes(ba, ba->drr,
+ if (dump_bytes(dsp, dsp->dsa_drr,
sizeof (dmu_replay_record_t)) != 0)
return (EINTR);
- ba->pending_op = PENDING_NONE;
+ dsp->dsa_pending_op = PENDING_NONE;
}
}
/* create a FREE record and make it pending */
- bzero(ba->drr, sizeof (dmu_replay_record_t));
- ba->drr->drr_type = DRR_FREE;
+ bzero(dsp->dsa_drr, sizeof (dmu_replay_record_t));
+ dsp->dsa_drr->drr_type = DRR_FREE;
drrf->drr_object = object;
drrf->drr_offset = offset;
drrf->drr_length = length;
- drrf->drr_toguid = ba->toguid;
+ drrf->drr_toguid = dsp->dsa_toguid;
if (length == -1ULL) {
- if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)) != 0)
+ if (dump_bytes(dsp, dsp->dsa_drr,
+ sizeof (dmu_replay_record_t)) != 0)
return (EINTR);
} else {
- ba->pending_op = PENDING_FREE;
+ dsp->dsa_pending_op = PENDING_FREE;
}
return (0);
}
static int
-dump_data(struct backuparg *ba, dmu_object_type_t type,
+dump_data(dmu_sendarg_t *dsp, dmu_object_type_t type,
uint64_t object, uint64_t offset, int blksz, const blkptr_t *bp, void *data)
{
- struct drr_write *drrw = &(ba->drr->drr_u.drr_write);
+ struct drr_write *drrw = &(dsp->dsa_drr->drr_u.drr_write);
/*
@@ -180,19 +166,20 @@
* the stream, since aggregation can't be done across operations
* of different types.
*/
- if (ba->pending_op != PENDING_NONE) {
- if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)) != 0)
+ if (dsp->dsa_pending_op != PENDING_NONE) {
+ if (dump_bytes(dsp, dsp->dsa_drr,
+ sizeof (dmu_replay_record_t)) != 0)
return (EINTR);
- ba->pending_op = PENDING_NONE;
+ dsp->dsa_pending_op = PENDING_NONE;
}
/* write a DATA record */
- bzero(ba->drr, sizeof (dmu_replay_record_t));
- ba->drr->drr_type = DRR_WRITE;
+ bzero(dsp->dsa_drr, sizeof (dmu_replay_record_t));
+ dsp->dsa_drr->drr_type = DRR_WRITE;
drrw->drr_object = object;
drrw->drr_type = type;
drrw->drr_offset = offset;
drrw->drr_length = blksz;
- drrw->drr_toguid = ba->toguid;
+ drrw->drr_toguid = dsp->dsa_toguid;
drrw->drr_checksumtype = BP_GET_CHECKSUM(bp);
if (zio_checksum_table[drrw->drr_checksumtype].ci_dedup)
drrw->drr_checksumflags |= DRR_CHECKSUM_DEDUP;
@@ -201,42 +188,43 @@
DDK_SET_COMPRESS(&drrw->drr_key, BP_GET_COMPRESS(bp));
drrw->drr_key.ddk_cksum = bp->blk_cksum;
- if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)) != 0)
+ if (dump_bytes(dsp, dsp->dsa_drr, sizeof (dmu_replay_record_t)) != 0)
return (EINTR);
- if (dump_bytes(ba, data, blksz) != 0)
+ if (dump_bytes(dsp, data, blksz) != 0)
return (EINTR);
return (0);
}
static int
-dump_spill(struct backuparg *ba, uint64_t object, int blksz, void *data)
+dump_spill(dmu_sendarg_t *dsp, uint64_t object, int blksz, void *data)
{
- struct drr_spill *drrs = &(ba->drr->drr_u.drr_spill);
+ struct drr_spill *drrs = &(dsp->dsa_drr->drr_u.drr_spill);
- if (ba->pending_op != PENDING_NONE) {
- if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)) != 0)
+ if (dsp->dsa_pending_op != PENDING_NONE) {
+ if (dump_bytes(dsp, dsp->dsa_drr,
+ sizeof (dmu_replay_record_t)) != 0)
return (EINTR);
- ba->pending_op = PENDING_NONE;
+ dsp->dsa_pending_op = PENDING_NONE;
}
/* write a SPILL record */
- bzero(ba->drr, sizeof (dmu_replay_record_t));
- ba->drr->drr_type = DRR_SPILL;
+ bzero(dsp->dsa_drr, sizeof (dmu_replay_record_t));
+ dsp->dsa_drr->drr_type = DRR_SPILL;
drrs->drr_object = object;
drrs->drr_length = blksz;
- drrs->drr_toguid = ba->toguid;
+ drrs->drr_toguid = dsp->dsa_toguid;
- if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)))
+ if (dump_bytes(dsp, dsp->dsa_drr, sizeof (dmu_replay_record_t)))
return (EINTR);
- if (dump_bytes(ba, data, blksz))
+ if (dump_bytes(dsp, data, blksz))
return (EINTR);
return (0);
}
static int
-dump_freeobjects(struct backuparg *ba, uint64_t firstobj, uint64_t numobjs)
+dump_freeobjects(dmu_sendarg_t *dsp, uint64_t firstobj, uint64_t numobjs)
{
- struct drr_freeobjects *drrfo = &(ba->drr->drr_u.drr_freeobjects);
+ struct drr_freeobjects *drrfo = &(dsp->dsa_drr->drr_u.drr_freeobjects);
/*
* If there is a pending op, but it's not PENDING_FREEOBJECTS,
@@ -245,13 +233,14 @@
* aggregated with other DRR_FREE records. DRR_FREEOBJECTS records
* can only be aggregated with other DRR_FREEOBJECTS records.
*/
- if (ba->pending_op != PENDING_NONE &&
- ba->pending_op != PENDING_FREEOBJECTS) {
- if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)) != 0)
+ if (dsp->dsa_pending_op != PENDING_NONE &&
+ dsp->dsa_pending_op != PENDING_FREEOBJECTS) {
+ if (dump_bytes(dsp, dsp->dsa_drr,
+ sizeof (dmu_replay_record_t)) != 0)
return (EINTR);
- ba->pending_op = PENDING_NONE;
+ dsp->dsa_pending_op = PENDING_NONE;
}
- if (ba->pending_op == PENDING_FREEOBJECTS) {
+ if (dsp->dsa_pending_op == PENDING_FREEOBJECTS) {
/*
* See whether this free object array can be aggregated
* with pending one
@@ -261,42 +250,43 @@
return (0);
} else {
/* can't be aggregated. Push out pending record */
- if (dump_bytes(ba, ba->drr,
+ if (dump_bytes(dsp, dsp->dsa_drr,
sizeof (dmu_replay_record_t)) != 0)
return (EINTR);
- ba->pending_op = PENDING_NONE;
+ dsp->dsa_pending_op = PENDING_NONE;
}
}
/* write a FREEOBJECTS record */
- bzero(ba->drr, sizeof (dmu_replay_record_t));
- ba->drr->drr_type = DRR_FREEOBJECTS;
+ bzero(dsp->dsa_drr, sizeof (dmu_replay_record_t));
+ dsp->dsa_drr->drr_type = DRR_FREEOBJECTS;
drrfo->drr_firstobj = firstobj;
drrfo->drr_numobjs = numobjs;
- drrfo->drr_toguid = ba->toguid;
+ drrfo->drr_toguid = dsp->dsa_toguid;
- ba->pending_op = PENDING_FREEOBJECTS;
+ dsp->dsa_pending_op = PENDING_FREEOBJECTS;
return (0);
}
static int
-dump_dnode(struct backuparg *ba, uint64_t object, dnode_phys_t *dnp)
+dump_dnode(dmu_sendarg_t *dsp, uint64_t object, dnode_phys_t *dnp)
{
- struct drr_object *drro = &(ba->drr->drr_u.drr_object);
+ struct drr_object *drro = &(dsp->dsa_drr->drr_u.drr_object);
if (dnp == NULL || dnp->dn_type == DMU_OT_NONE)
- return (dump_freeobjects(ba, object, 1));
+ return (dump_freeobjects(dsp, object, 1));
- if (ba->pending_op != PENDING_NONE) {
- if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)) != 0)
+ if (dsp->dsa_pending_op != PENDING_NONE) {
+ if (dump_bytes(dsp, dsp->dsa_drr,
+ sizeof (dmu_replay_record_t)) != 0)
return (EINTR);
- ba->pending_op = PENDING_NONE;
+ dsp->dsa_pending_op = PENDING_NONE;
}
/* write an OBJECT record */
- bzero(ba->drr, sizeof (dmu_replay_record_t));
- ba->drr->drr_type = DRR_OBJECT;
+ bzero(dsp->dsa_drr, sizeof (dmu_replay_record_t));
+ dsp->dsa_drr->drr_type = DRR_OBJECT;
drro->drr_object = object;
drro->drr_type = dnp->dn_type;
drro->drr_bonustype = dnp->dn_bonustype;
@@ -304,19 +294,19 @@
drro->drr_bonuslen = dnp->dn_bonuslen;
drro->drr_checksumtype = dnp->dn_checksum;
drro->drr_compress = dnp->dn_compress;
- drro->drr_toguid = ba->toguid;
+ drro->drr_toguid = dsp->dsa_toguid;
- if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)) != 0)
+ if (dump_bytes(dsp, dsp->dsa_drr, sizeof (dmu_replay_record_t)) != 0)
return (EINTR);
- if (dump_bytes(ba, DN_BONUS(dnp), P2ROUNDUP(dnp->dn_bonuslen, 8)) != 0)
+ if (dump_bytes(dsp, DN_BONUS(dnp), P2ROUNDUP(dnp->dn_bonuslen, 8)) != 0)
return (EINTR);
/* free anything past the end of the file */
- if (dump_free(ba, object, (dnp->dn_maxblkid + 1) *
+ if (dump_free(dsp, object, (dnp->dn_maxblkid + 1) *
(dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT), -1ULL))
return (EINTR);
- if (ba->err)
+ if (dsp->dsa_err)
return (EINTR);
return (0);
}
@@ -330,7 +320,7 @@
backup_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, arc_buf_t *pbuf,
const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg)
{
- struct backuparg *ba = arg;
+ dmu_sendarg_t *dsp = arg;
dmu_object_type_t type = bp ? BP_GET_TYPE(bp) : DMU_OT_NONE;
int err = 0;
@@ -343,10 +333,10 @@
} else if (bp == NULL && zb->zb_object == DMU_META_DNODE_OBJECT) {
uint64_t span = BP_SPAN(dnp, zb->zb_level);
uint64_t dnobj = (zb->zb_blkid * span) >> DNODE_SHIFT;
- err = dump_freeobjects(ba, dnobj, span >> DNODE_SHIFT);
+ err = dump_freeobjects(dsp, dnobj, span >> DNODE_SHIFT);
} else if (bp == NULL) {
uint64_t span = BP_SPAN(dnp, zb->zb_level);
- err = dump_free(ba, zb->zb_object, zb->zb_blkid * span, span);
+ err = dump_free(dsp, zb->zb_object, zb->zb_blkid * span, span);
} else if (zb->zb_level > 0 || type == DMU_OT_OBJSET) {
return (0);
} else if (type == DMU_OT_DNODE) {
@@ -365,7 +355,7 @@
for (i = 0; i < blksz >> DNODE_SHIFT; i++) {
uint64_t dnobj = (zb->zb_blkid <<
(DNODE_BLOCK_SHIFT - DNODE_SHIFT)) + i;
- err = dump_dnode(ba, dnobj, blk+i);
+ err = dump_dnode(dsp, dnobj, blk+i);
if (err)
break;
}
@@ -380,7 +370,7 @@
ZIO_FLAG_CANFAIL, &aflags, zb) != 0)
return (EIO);
- err = dump_spill(ba, zb->zb_object, blksz, abuf->b_data);
+ err = dump_spill(dsp, zb->zb_object, blksz, abuf->b_data);
(void) arc_buf_remove_ref(abuf, &abuf);
} else { /* it's a level-0 block of a regular object */
uint32_t aflags = ARC_WAIT;
@@ -404,7 +394,7 @@
}
}
- err = dump_data(ba, type, zb->zb_object, zb->zb_blkid * blksz,
+ err = dump_data(dsp, type, zb->zb_object, zb->zb_blkid * blksz,
blksz, bp, abuf->b_data);
(void) arc_buf_remove_ref(abuf, &abuf);
}
@@ -414,13 +404,13 @@
}
int
-dmu_sendbackup(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
- struct file *fp, offset_t *off)
+dmu_send(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
+ int outfd, struct file *fp, offset_t *off)
{
dsl_dataset_t *ds = tosnap->os_dsl_dataset;
dsl_dataset_t *fromds = fromsnap ? fromsnap->os_dsl_dataset : NULL;
dmu_replay_record_t *drr;
- struct backuparg ba;
+ dmu_sendarg_t *dsp;
int err;
uint64_t fromtxg = 0;
@@ -461,8 +451,10 @@
#ifdef _KERNEL
if (dmu_objset_type(tosnap) == DMU_OST_ZFS) {
uint64_t version;
- if (zfs_get_zplprop(tosnap, ZFS_PROP_VERSION, &version) != 0)
+ if (zfs_get_zplprop(tosnap, ZFS_PROP_VERSION, &version) != 0) {
+ kmem_free(drr, sizeof (dmu_replay_record_t));
return (EINVAL);
+ }
if (version == ZPL_VERSION_SA) {
DMU_SET_FEATUREFLAGS(
drr->drr_u.drr_begin.drr_versioninfo,
@@ -489,47 +481,60 @@
if (fromorigin)
dsl_dataset_rele(fromds, FTAG);
- ba.drr = drr;
- ba.td = curthread;
- ba.fp = fp;
- ba.os = tosnap;
- ba.off = off;
- ba.toguid = ds->ds_phys->ds_guid;
- ZIO_SET_CHECKSUM(&ba.zc, 0, 0, 0, 0);
- ba.pending_op = PENDING_NONE;
+ dsp = kmem_zalloc(sizeof (dmu_sendarg_t), KM_SLEEP);
- if (dump_bytes(&ba, drr, sizeof (dmu_replay_record_t)) != 0) {
- kmem_free(drr, sizeof (dmu_replay_record_t));
- return (ba.err);
+ dsp->dsa_drr = drr;
+ dsp->dsa_outfd = outfd;
+ dsp->dsa_proc = curproc;
+ dsp->dsa_td = curthread;
+ dsp->dsa_fp = fp;
+ dsp->dsa_os = tosnap;
+ dsp->dsa_off = off;
+ dsp->dsa_toguid = ds->ds_phys->ds_guid;
+ ZIO_SET_CHECKSUM(&dsp->dsa_zc, 0, 0, 0, 0);
+ dsp->dsa_pending_op = PENDING_NONE;
+
+ mutex_enter(&ds->ds_sendstream_lock);
+ list_insert_head(&ds->ds_sendstreams, dsp);
+ mutex_exit(&ds->ds_sendstream_lock);
+
+ if (dump_bytes(dsp, drr, sizeof (dmu_replay_record_t)) != 0) {
+ err = dsp->dsa_err;
+ goto out;
}
err = traverse_dataset(ds, fromtxg, TRAVERSE_PRE | TRAVERSE_PREFETCH,
- backup_cb, &ba);
+ backup_cb, dsp);
- if (ba.pending_op != PENDING_NONE)
- if (dump_bytes(&ba, drr, sizeof (dmu_replay_record_t)) != 0)
+ if (dsp->dsa_pending_op != PENDING_NONE)
+ if (dump_bytes(dsp, drr, sizeof (dmu_replay_record_t)) != 0)
err = EINTR;
if (err) {
- if (err == EINTR && ba.err)
- err = ba.err;
- kmem_free(drr, sizeof (dmu_replay_record_t));
- return (err);
+ if (err == EINTR && dsp->dsa_err)
+ err = dsp->dsa_err;
+ goto out;
}
bzero(drr, sizeof (dmu_replay_record_t));
drr->drr_type = DRR_END;
- drr->drr_u.drr_end.drr_checksum = ba.zc;
- drr->drr_u.drr_end.drr_toguid = ba.toguid;
+ drr->drr_u.drr_end.drr_checksum = dsp->dsa_zc;
+ drr->drr_u.drr_end.drr_toguid = dsp->dsa_toguid;
- if (dump_bytes(&ba, drr, sizeof (dmu_replay_record_t)) != 0) {
- kmem_free(drr, sizeof (dmu_replay_record_t));
- return (ba.err);
+ if (dump_bytes(dsp, drr, sizeof (dmu_replay_record_t)) != 0) {
+ err = dsp->dsa_err;
+ goto out;
}
+out:
+ mutex_enter(&ds->ds_sendstream_lock);
+ list_remove(&ds->ds_sendstreams, dsp);
+ mutex_exit(&ds->ds_sendstream_lock);
+
kmem_free(drr, sizeof (dmu_replay_record_t));
+ kmem_free(dsp, sizeof (dmu_sendarg_t));
- return (0);
+ return (err);
}
int
@@ -1112,8 +1117,8 @@
void *data = NULL;
if (drro->drr_type == DMU_OT_NONE ||
- drro->drr_type >= DMU_OT_NUMTYPES ||
- drro->drr_bonustype >= DMU_OT_NUMTYPES ||
+ !DMU_OT_IS_VALID(drro->drr_type) ||
+ !DMU_OT_IS_VALID(drro->drr_bonustype) ||
drro->drr_checksumtype >= ZIO_CHECKSUM_FUNCTIONS ||
drro->drr_compress >= ZIO_COMPRESS_FUNCTIONS ||
P2PHASE(drro->drr_blksz, SPA_MINBLOCKSIZE) ||
@@ -1178,7 +1183,9 @@
ASSERT3U(db->db_size, >=, drro->drr_bonuslen);
bcopy(data, db->db_data, drro->drr_bonuslen);
if (ra->byteswap) {
- dmu_ot[drro->drr_bonustype].ot_byteswap(db->db_data,
+ dmu_object_byteswap_t byteswap =
+ DMU_OT_BYTESWAP(drro->drr_bonustype);
+ dmu_ot_byteswap[byteswap].ob_func(db->db_data,
drro->drr_bonuslen);
}
dmu_buf_rele(db, FTAG);
@@ -1221,7 +1228,7 @@
int err;
if (drrw->drr_offset + drrw->drr_length < drrw->drr_offset ||
- drrw->drr_type >= DMU_OT_NUMTYPES)
+ !DMU_OT_IS_VALID(drrw->drr_type))
return (EINVAL);
data = restore_read(ra, drrw->drr_length);
@@ -1240,8 +1247,11 @@
dmu_tx_abort(tx);
return (err);
}
- if (ra->byteswap)
- dmu_ot[drrw->drr_type].ot_byteswap(data, drrw->drr_length);
+ if (ra->byteswap) {
+ dmu_object_byteswap_t byteswap =
+ DMU_OT_BYTESWAP(drrw->drr_type);
+ dmu_ot_byteswap[byteswap].ob_func(data, drrw->drr_length);
+ }
dmu_write(os, drrw->drr_object,
drrw->drr_offset, drrw->drr_length, data, tx);
dmu_tx_commit(tx);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c Wed Jul 25 16:45:04 2012 +0300
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@@ -53,6 +54,7 @@
uint64_t td_objset;
blkptr_t *td_rootbp;
uint64_t td_min_txg;
+ zbookmark_t *td_resume;
int td_flags;
prefetch_data_t *td_pfd;
blkptr_cb_t *td_func;
@@ -128,6 +130,54 @@
zil_free(zilog);
}
+typedef enum resume_skip {
+ RESUME_SKIP_ALL,
+ RESUME_SKIP_NONE,
+ RESUME_SKIP_CHILDREN
+} resume_skip_t;
+
+/*
+ * Returns RESUME_SKIP_ALL if td indicates that we are resuming a traversal and
+ * the block indicated by zb does not need to be visited at all. Returns
+ * RESUME_SKIP_CHILDREN if we are resuming a post traversal and we reach the
+ * resume point. This indicates that this block should be visited but not its
+ * children (since they must have been visited in a previous traversal).
+ * Otherwise returns RESUME_SKIP_NONE.
+ */
+static resume_skip_t
+resume_skip_check(traverse_data_t *td, const dnode_phys_t *dnp,
+ const zbookmark_t *zb)
+{
+ if (td->td_resume != NULL && !ZB_IS_ZERO(td->td_resume)) {
+ /*
+ * If we already visited this bp & everything below,
+ * don't bother doing it again.
+ */
+ if (zbookmark_is_before(dnp, zb, td->td_resume))
+ return (RESUME_SKIP_ALL);
+
+ /*
+ * If we found the block we're trying to resume from, zero
+ * the bookmark out to indicate that we have resumed.
+ */
+ ASSERT3U(zb->zb_object, <=, td->td_resume->zb_object);
+ if (bcmp(zb, td->td_resume, sizeof (*zb)) == 0) {
+ bzero(td->td_resume, sizeof (*zb));
+ if (td->td_flags & TRAVERSE_POST)
+ return (RESUME_SKIP_CHILDREN);
+ }
+ }
+ return (RESUME_SKIP_NONE);
+}
+
+static void
+traverse_pause(traverse_data_t *td, const zbookmark_t *zb)
+{
+ ASSERT(td->td_resume != NULL);
+ ASSERT3U(zb->zb_level, ==, 0);
+ bcopy(zb, td->td_resume, sizeof (*td->td_resume));
+}
+
static int
traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp,
arc_buf_t *pbuf, blkptr_t *bp, const zbookmark_t *zb)
@@ -137,8 +187,20 @@
arc_buf_t *buf = NULL;
prefetch_data_t *pd = td->td_pfd;
boolean_t hard = td->td_flags & TRAVERSE_HARD;
+ boolean_t pause = B_FALSE;
- if (bp->blk_birth == 0) {
+ switch (resume_skip_check(td, dnp, zb)) {
+ case RESUME_SKIP_ALL:
+ return (0);
+ case RESUME_SKIP_CHILDREN:
+ goto post;
+ case RESUME_SKIP_NONE:
+ break;
+ default:
+ ASSERT(0);
+ }
+
+ if (BP_IS_HOLE(bp)) {
err = td->td_func(td->td_spa, NULL, NULL, pbuf, zb, dnp,
td->td_arg);
return (err);
@@ -164,8 +226,10 @@
td->td_arg);
if (err == TRAVERSE_VISIT_NO_CHILDREN)
return (0);
- if (err)
- return (err);
+ if (err == ERESTART)
+ pause = B_TRUE; /* handle pausing at a common point */
+ if (err != 0)
+ goto post;
}
if (BP_GET_LEVEL(bp) > 0) {
@@ -253,9 +317,18 @@
if (buf)
(void) arc_buf_remove_ref(buf, &buf);
+post:
if (err == 0 && lasterr == 0 && (td->td_flags & TRAVERSE_POST)) {
err = td->td_func(td->td_spa, NULL, bp, pbuf, zb, dnp,
td->td_arg);
+ if (err == ERESTART)
+ pause = B_TRUE;
+ }
+
+ if (pause && td->td_resume != NULL) {
+ ASSERT3U(err, ==, ERESTART);
+ ASSERT(!hard);
+ traverse_pause(td, zb);
}
return (err != 0 ? err : lasterr);
@@ -353,18 +426,23 @@
* in syncing context).
*/
static int
-traverse_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *rootbp,
- uint64_t txg_start, int flags, blkptr_cb_t func, void *arg)
+traverse_impl(spa_t *spa, dsl_dataset_t *ds, uint64_t objset, blkptr_t *rootbp,
+ uint64_t txg_start, zbookmark_t *resume, int flags,
+ blkptr_cb_t func, void *arg)
{
traverse_data_t td;
prefetch_data_t pd = { 0 };
zbookmark_t czb;
int err;
+ ASSERT(ds == NULL || objset == ds->ds_object);
+ ASSERT(!(flags & TRAVERSE_PRE) || !(flags & TRAVERSE_POST));
+
td.td_spa = spa;
- td.td_objset = ds ? ds->ds_object : 0;
+ td.td_objset = objset;
td.td_rootbp = rootbp;
td.td_min_txg = txg_start;
+ td.td_resume = resume;
td.td_func = func;
td.td_arg = arg;
td.td_pfd = &pd;
@@ -416,8 +494,17 @@
traverse_dataset(dsl_dataset_t *ds, uint64_t txg_start, int flags,
blkptr_cb_t func, void *arg)
{
- return (traverse_impl(ds->ds_dir->dd_pool->dp_spa, ds,
- &ds->ds_phys->ds_bp, txg_start, flags, func, arg));
+ return (traverse_impl(ds->ds_dir->dd_pool->dp_spa, ds, ds->ds_object,
+ &ds->ds_phys->ds_bp, txg_start, NULL, flags, func, arg));
+}
+
+int
+traverse_dataset_destroyed(spa_t *spa, blkptr_t *blkptr,
+ uint64_t txg_start, zbookmark_t *resume, int flags,
+ blkptr_cb_t func, void *arg)
+{
+ return (traverse_impl(spa, NULL, ZB_DESTROYED_OBJSET,
+ blkptr, txg_start, resume, flags, func, arg));
}
/*
@@ -434,8 +521,8 @@
boolean_t hard = (flags & TRAVERSE_HARD);
/* visit the MOS */
- err = traverse_impl(spa, NULL, spa_get_rootblkptr(spa),
- txg_start, flags, func, arg);
+ err = traverse_impl(spa, NULL, 0, spa_get_rootblkptr(spa),
+ txg_start, NULL, flags, func, arg);
if (err)
return (err);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c Wed Jul 25 16:45:04 2012 +0300
@@ -20,9 +20,8 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- */
-/*
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/dmu.h>
@@ -676,7 +675,7 @@
return;
}
- ASSERT3P(dmu_ot[dn->dn_type].ot_byteswap, ==, zap_byteswap);
+ ASSERT3P(DMU_OT_BYTESWAP(dn->dn_type), ==, DMU_BSWAP_ZAP);
if (dn->dn_maxblkid == 0 && !add) {
blkptr_t *bp;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c Wed Jul 25 16:45:04 2012 +0300
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@@ -196,7 +197,7 @@
ASSERT(dn->dn_objset);
ASSERT(dn->dn_handle->dnh_dnode == dn);
- ASSERT(dn->dn_phys->dn_type < DMU_OT_NUMTYPES);
+ ASSERT(DMU_OT_IS_VALID(dn->dn_phys->dn_type));
if (!(zfs_flags & ZFS_DEBUG_DNODE_VERIFY))
return;
@@ -215,7 +216,7 @@
ASSERT3U(1<<dn->dn_datablkshift, ==, dn->dn_datablksz);
}
ASSERT3U(dn->dn_nlevels, <=, 30);
- ASSERT3U(dn->dn_type, <=, DMU_OT_NUMTYPES);
+ ASSERT(DMU_OT_IS_VALID(dn->dn_type));
ASSERT3U(dn->dn_nblkptr, >=, 1);
ASSERT3U(dn->dn_nblkptr, <=, DN_MAX_NBLKPTR);
ASSERT3U(dn->dn_bonuslen, <=, DN_MAX_BONUSLEN);
@@ -281,8 +282,10 @@
*/
int off = (dnp->dn_nblkptr-1) * sizeof (blkptr_t);
size_t len = DN_MAX_BONUSLEN - off;
- ASSERT3U(dnp->dn_bonustype, <, DMU_OT_NUMTYPES);
- dmu_ot[dnp->dn_bonustype].ot_byteswap(dnp->dn_bonus + off, len);
+ ASSERT(DMU_OT_IS_VALID(dnp->dn_bonustype));
+ dmu_object_byteswap_t byteswap =
+ DMU_OT_BYTESWAP(dnp->dn_bonustype);
+ dmu_ot_byteswap[byteswap].ob_func(dnp->dn_bonus + off, len);
}
/* Swap SPILL block if we have one */
@@ -410,7 +413,7 @@
dmu_zfetch_init(&dn->dn_zfetch, dn);
- ASSERT(dn->dn_phys->dn_type < DMU_OT_NUMTYPES);
+ ASSERT(DMU_OT_IS_VALID(dn->dn_phys->dn_type));
mutex_enter(&os->os_lock);
list_insert_head(&os->os_dnodes, dn);
@@ -499,11 +502,11 @@
ASSERT(bcmp(dn->dn_phys, &dnode_phys_zero, sizeof (dnode_phys_t)) == 0);
ASSERT(dn->dn_phys->dn_type == DMU_OT_NONE);
ASSERT(ot != DMU_OT_NONE);
- ASSERT3U(ot, <, DMU_OT_NUMTYPES);
+ ASSERT(DMU_OT_IS_VALID(ot));
ASSERT((bonustype == DMU_OT_NONE && bonuslen == 0) ||
(bonustype == DMU_OT_SA && bonuslen == 0) ||
(bonustype != DMU_OT_NONE && bonuslen != 0));
- ASSERT3U(bonustype, <, DMU_OT_NUMTYPES);
+ ASSERT(DMU_OT_IS_VALID(bonustype));
ASSERT3U(bonuslen, <=, DN_MAX_BONUSLEN);
ASSERT(dn->dn_type == DMU_OT_NONE);
ASSERT3U(dn->dn_maxblkid, ==, 0);
@@ -571,7 +574,7 @@
ASSERT((bonustype == DMU_OT_NONE && bonuslen == 0) ||
(bonustype != DMU_OT_NONE && bonuslen != 0) ||
(bonustype == DMU_OT_SA && bonuslen == 0));
- ASSERT3U(bonustype, <, DMU_OT_NUMTYPES);
+ ASSERT(DMU_OT_IS_VALID(bonustype));
ASSERT3U(bonuslen, <=, DN_MAX_BONUSLEN);
/* clean up any unreferenced dbufs */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c Wed Jul 25 16:45:04 2012 +0300
@@ -18,8 +18,10 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@@ -597,7 +599,7 @@
}
if (dn->dn_next_bonustype[txgoff]) {
- ASSERT(dn->dn_next_bonustype[txgoff] < DMU_OT_NUMTYPES);
+ ASSERT(DMU_OT_IS_VALID(dn->dn_next_bonustype[txgoff]));
dnp->dn_bonustype = dn->dn_next_bonustype[txgoff];
dn->dn_next_bonustype[txgoff] = 0;
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c Wed Jul 25 16:45:04 2012 +0300
@@ -20,7 +20,8 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel at dawidek.net>.
* All rights reserved.
* Portions Copyright (c) 2011 Martin Matuska <mm at FreeBSD.org>
@@ -32,10 +33,12 @@
#include <sys/dsl_prop.h>
#include <sys/dsl_synctask.h>
#include <sys/dmu_traverse.h>
+#include <sys/dmu_impl.h>
#include <sys/dmu_tx.h>
#include <sys/arc.h>
#include <sys/zio.h>
#include <sys/zap.h>
+#include <sys/zfeature.h>
#include <sys/unique.h>
#include <sys/zfs_context.h>
#include <sys/zfs_ioctl.h>
@@ -101,7 +104,7 @@
if (BP_IS_HOLE(bp))
return;
ASSERT(BP_GET_TYPE(bp) != DMU_OT_NONE);
- ASSERT3U(BP_GET_TYPE(bp), <, DMU_OT_NUMTYPES);
+ ASSERT(DMU_OT_IS_VALID(BP_GET_TYPE(bp)));
if (ds == NULL) {
/*
* Account for the meta-objset space in its placeholder
@@ -118,7 +121,7 @@
mutex_enter(&ds->ds_dir->dd_lock);
mutex_enter(&ds->ds_lock);
delta = parent_delta(ds, used);
- ds->ds_phys->ds_used_bytes += used;
+ ds->ds_phys->ds_referenced_bytes += used;
ds->ds_phys->ds_compressed_bytes += compressed;
ds->ds_phys->ds_uncompressed_bytes += uncompressed;
ds->ds_phys->ds_unique_bytes += used;
@@ -212,8 +215,8 @@
}
}
mutex_enter(&ds->ds_lock);
- ASSERT3U(ds->ds_phys->ds_used_bytes, >=, used);
- ds->ds_phys->ds_used_bytes -= used;
+ ASSERT3U(ds->ds_phys->ds_referenced_bytes, >=, used);
+ ds->ds_phys->ds_referenced_bytes -= used;
ASSERT3U(ds->ds_phys->ds_compressed_bytes, >=, compressed);
ds->ds_phys->ds_compressed_bytes -= compressed;
ASSERT3U(ds->ds_phys->ds_uncompressed_bytes, >=, uncompressed);
@@ -401,6 +404,8 @@
mutex_init(&ds->ds_lock, NULL, MUTEX_DEFAULT, NULL);
mutex_init(&ds->ds_recvlock, NULL, MUTEX_DEFAULT, NULL);
mutex_init(&ds->ds_opening_lock, NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&ds->ds_sendstream_lock, NULL, MUTEX_DEFAULT, NULL);
+
rw_init(&ds->ds_rwlock, 0, 0, 0);
cv_init(&ds->ds_exclusive_cv, NULL, CV_DEFAULT, NULL);
@@ -408,6 +413,9 @@
dsl_deadlist_open(&ds->ds_deadlist,
mos, ds->ds_phys->ds_deadlist_obj);
+ list_create(&ds->ds_sendstreams, sizeof (dmu_sendarg_t),
+ offsetof(dmu_sendarg_t, dsa_link));
+
if (err == 0) {
err = dsl_dir_open_obj(dp,
ds->ds_phys->ds_dir_obj, NULL, ds, &ds->ds_dir);
@@ -802,8 +810,10 @@
dsphys->ds_dir_obj = dd->dd_object;
dsphys->ds_flags = flags;
dsphys->ds_fsid_guid = unique_create();
- (void) random_get_pseudo_bytes((void*)&dsphys->ds_guid,
- sizeof (dsphys->ds_guid));
+ do {
+ (void) random_get_pseudo_bytes((void*)&dsphys->ds_guid,
+ sizeof (dsphys->ds_guid));
+ } while (dsphys->ds_guid == 0);
dsphys->ds_snapnames_zapobj =
zap_create_norm(mos, U8_TEXTPREP_TOUPPER, DMU_OT_DSL_DS_SNAP_MAP,
DMU_OT_NONE, 0, tx);
@@ -818,8 +828,8 @@
dsphys->ds_prev_snap_obj = origin->ds_object;
dsphys->ds_prev_snap_txg =
origin->ds_phys->ds_creation_txg;
- dsphys->ds_used_bytes =
- origin->ds_phys->ds_used_bytes;
+ dsphys->ds_referenced_bytes =
+ origin->ds_phys->ds_referenced_bytes;
dsphys->ds_compressed_bytes =
origin->ds_phys->ds_compressed_bytes;
dsphys->ds_uncompressed_bytes =
@@ -972,7 +982,6 @@
for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
pair = nvlist_next_nvpair(snaps, pair)) {
dsl_dataset_t *ds;
- int err;
err = dsl_dataset_own(nvpair_name(pair), B_TRUE, dstg, &ds);
if (err == 0) {
@@ -1121,19 +1130,23 @@
goto out;
/*
- * remove the objects in open context, so that we won't
- * have too much to do in syncing context.
+ * If async destruction is not enabled try to remove all objects
+ * while in the open context so that there is less work to do in
+ * the syncing context.
*/
- for (obj = 0; err == 0; err = dmu_object_next(os, &obj, FALSE,
- ds->ds_phys->ds_prev_snap_txg)) {
- /*
- * Ignore errors, if there is not enough disk space
- * we will deal with it in dsl_dataset_destroy_sync().
- */
- (void) dmu_free_object(os, obj);
+ if (!spa_feature_is_enabled(dsl_dataset_get_spa(ds),
+ &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
+ for (obj = 0; err == 0; err = dmu_object_next(os, &obj, FALSE,
+ ds->ds_phys->ds_prev_snap_txg)) {
+ /*
+ * Ignore errors, if there is not enough disk space
+ * we will deal with it in dsl_dataset_destroy_sync().
+ */
+ (void) dmu_free_object(os, obj);
+ }
+ if (err != ESRCH)
+ goto out;
}
- if (err != ESRCH)
- goto out;
/*
* Only the ZIL knows how to free log blocks.
@@ -1279,7 +1292,7 @@
ASSERT(!dsl_dataset_is_snapshot(ds));
if (ds->ds_phys->ds_prev_snap_obj != 0)
- mrs_used = ds->ds_prev->ds_phys->ds_used_bytes;
+ mrs_used = ds->ds_prev->ds_phys->ds_referenced_bytes;
else
mrs_used = 0;
@@ -1287,7 +1300,7 @@
ASSERT3U(dlused, <=, mrs_used);
ds->ds_phys->ds_unique_bytes =
- ds->ds_phys->ds_used_bytes - (mrs_used - dlused);
+ ds->ds_phys->ds_referenced_bytes - (mrs_used - dlused);
if (spa_version(ds->ds_dir->dd_pool->dp_spa) >=
SPA_VERSION_UNIQUE_ACCURATE)
@@ -1646,6 +1659,30 @@
ds_next->ds_phys->ds_deadlist_obj);
}
+static int
+old_synchronous_dataset_destroy(dsl_dataset_t *ds, dmu_tx_t *tx)
+{
+ int err;
+ struct killarg ka;
+
+ /*
+ * Free everything that we point to (that's born after
+ * the previous snapshot, if we are a clone)
+ *
+ * NB: this should be very quick, because we already
+ * freed all the objects in open context.
+ */
+ ka.ds = ds;
+ ka.tx = tx;
+ err = traverse_dataset(ds,
+ ds->ds_phys->ds_prev_snap_txg, TRAVERSE_POST,
+ kill_blkptr, &ka);
+ ASSERT3U(err, ==, 0);
+ ASSERT(!DS_UNIQUE_IS_ACCURATE(ds) || ds->ds_phys->ds_unique_bytes == 0);
+
+ return (err);
+}
+
void
dsl_dataset_destroy_sync(void *arg1, void *tag, dmu_tx_t *tx)
{
@@ -1792,7 +1829,6 @@
tx);
dsl_dir_diduse_space(tx->tx_pool->dp_free_dir,
DD_USED_HEAD, used, comp, uncomp, tx);
- dsl_dir_dirty(tx->tx_pool->dp_free_dir, tx);
/* Merge our deadlist into next's and free it. */
dsl_deadlist_merge(&ds_next->ds_deadlist,
@@ -1868,32 +1904,54 @@
}
dsl_dataset_rele(ds_next, FTAG);
} else {
+ zfeature_info_t *async_destroy =
+ &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY];
+
/*
* There's no next snapshot, so this is a head dataset.
* Destroy the deadlist. Unless it's a clone, the
* deadlist should be empty. (If it's a clone, it's
* safe to ignore the deadlist contents.)
*/
- struct killarg ka;
-
dsl_deadlist_close(&ds->ds_deadlist);
dsl_deadlist_free(mos, ds->ds_phys->ds_deadlist_obj, tx);
ds->ds_phys->ds_deadlist_obj = 0;
- /*
- * Free everything that we point to (that's born after
- * the previous snapshot, if we are a clone)
- *
- * NB: this should be very quick, because we already
- * freed all the objects in open context.
- */
- ka.ds = ds;
- ka.tx = tx;
- err = traverse_dataset(ds, ds->ds_phys->ds_prev_snap_txg,
- TRAVERSE_POST, kill_blkptr, &ka);
- ASSERT3U(err, ==, 0);
- ASSERT(!DS_UNIQUE_IS_ACCURATE(ds) ||
- ds->ds_phys->ds_unique_bytes == 0);
+ if (!spa_feature_is_enabled(dp->dp_spa, async_destroy)) {
+ err = old_synchronous_dataset_destroy(ds, tx);
+ } else {
+ /*
+ * Move the bptree into the pool's list of trees to
+ * clean up and update space accounting information.
+ */
+ uint64_t used, comp, uncomp;
+
+ ASSERT(err == 0 || err == EBUSY);
+ if (!spa_feature_is_active(dp->dp_spa, async_destroy)) {
+ spa_feature_incr(dp->dp_spa, async_destroy, tx);
+ dp->dp_bptree_obj = bptree_alloc(
+ dp->dp_meta_objset, tx);
+ VERIFY(zap_add(dp->dp_meta_objset,
+ DMU_POOL_DIRECTORY_OBJECT,
+ DMU_POOL_BPTREE_OBJ, sizeof (uint64_t), 1,
+ &dp->dp_bptree_obj, tx) == 0);
+ }
+
+ used = ds->ds_dir->dd_phys->dd_used_bytes;
+ comp = ds->ds_dir->dd_phys->dd_compressed_bytes;
+ uncomp = ds->ds_dir->dd_phys->dd_uncompressed_bytes;
+
+ ASSERT(!DS_UNIQUE_IS_ACCURATE(ds) ||
+ ds->ds_phys->ds_unique_bytes == used);
+
+ bptree_add(dp->dp_meta_objset, dp->dp_bptree_obj,
+ &ds->ds_phys->ds_bp, ds->ds_phys->ds_prev_snap_txg,
+ used, comp, uncomp, tx);
+ dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD,
+ -used, -comp, -uncomp, tx);
+ dsl_dir_diduse_space(dp->dp_free_dir, DD_USED_HEAD,
+ used, comp, uncomp, tx);
+ }
if (ds->ds_prev != NULL) {
if (spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
@@ -2075,8 +2133,10 @@
bzero(dsphys, sizeof (dsl_dataset_phys_t));
dsphys->ds_dir_obj = ds->ds_dir->dd_object;
dsphys->ds_fsid_guid = unique_create();
- (void) random_get_pseudo_bytes((void*)&dsphys->ds_guid,
- sizeof (dsphys->ds_guid));
+ do {
+ (void) random_get_pseudo_bytes((void*)&dsphys->ds_guid,
+ sizeof (dsphys->ds_guid));
+ } while (dsphys->ds_guid == 0);
dsphys->ds_prev_snap_obj = ds->ds_phys->ds_prev_snap_obj;
dsphys->ds_prev_snap_txg = ds->ds_phys->ds_prev_snap_txg;
dsphys->ds_next_snap_obj = ds->ds_object;
@@ -2084,7 +2144,7 @@
dsphys->ds_creation_time = gethrestime_sec();
dsphys->ds_creation_txg = crtxg;
dsphys->ds_deadlist_obj = ds->ds_phys->ds_deadlist_obj;
- dsphys->ds_used_bytes = ds->ds_phys->ds_used_bytes;
+ dsphys->ds_referenced_bytes = ds->ds_phys->ds_referenced_bytes;
dsphys->ds_compressed_bytes = ds->ds_phys->ds_compressed_bytes;
dsphys->ds_uncompressed_bytes = ds->ds_phys->ds_uncompressed_bytes;
dsphys->ds_flags = ds->ds_phys->ds_flags;
@@ -2208,10 +2268,22 @@
zap_cursor_advance(&zc)) {
dsl_dataset_t *clone;
char buf[ZFS_MAXNAMELEN];
+ /*
+ * Even though we hold the dp_config_rwlock, the dataset
+ * may fail to open, returning ENOENT. If there is a
+ * thread concurrently attempting to destroy this
+ * dataset, it will have the ds_rwlock held for
+ * RW_WRITER. Our call to dsl_dataset_hold_obj() ->
+ * dsl_dataset_hold_ref() will fail its
+ * rw_tryenter(&ds->ds_rwlock, RW_READER), drop the
+ * dp_config_rwlock, and wait for the destroy progress
+ * and signal ds_exclusive_cv. If the destroy was
+ * successful, we will see that
+ * DSL_DATASET_IS_DESTROYED(), and return ENOENT.
+ */
if (dsl_dataset_hold_obj(ds->ds_dir->dd_pool,
- za.za_first_integer, FTAG, &clone) != 0) {
- goto fail;
- }
+ za.za_first_integer, FTAG, &clone) != 0)
+ continue;
dsl_dir_name(clone->ds_dir, buf);
VERIFY(nvlist_add_boolean(val, buf) == 0);
dsl_dataset_rele(clone, FTAG);
@@ -2334,7 +2406,7 @@
uint64_t *refdbytesp, uint64_t *availbytesp,
uint64_t *usedobjsp, uint64_t *availobjsp)
{
- *refdbytesp = ds->ds_phys->ds_used_bytes;
+ *refdbytesp = ds->ds_phys->ds_referenced_bytes;
*availbytesp = dsl_dir_space_available(ds->ds_dir, NULL, 0, TRUE);
if (ds->ds_reserved > ds->ds_phys->ds_unique_bytes)
*availbytesp += ds->ds_reserved - ds->ds_phys->ds_unique_bytes;
@@ -2677,7 +2749,7 @@
* Note however, if we stop before we reach the ORIGIN we get:
* uN + kN + kN-1 + ... + kM - uM-1
*/
- pa->used = origin_ds->ds_phys->ds_used_bytes;
+ pa->used = origin_ds->ds_phys->ds_referenced_bytes;
pa->comp = origin_ds->ds_phys->ds_compressed_bytes;
pa->uncomp = origin_ds->ds_phys->ds_uncompressed_bytes;
for (snap = list_head(&pa->shared_snaps); snap;
@@ -2711,7 +2783,7 @@
* so we need to subtract out the clone origin's used space.
*/
if (pa->origin_origin) {
- pa->used -= pa->origin_origin->ds_phys->ds_used_bytes;
+ pa->used -= pa->origin_origin->ds_phys->ds_referenced_bytes;
pa->comp -= pa->origin_origin->ds_phys->ds_compressed_bytes;
pa->uncomp -= pa->origin_origin->ds_phys->ds_uncompressed_bytes;
}
@@ -3227,8 +3299,8 @@
dsl_deadlist_space(&csa->ohds->ds_deadlist,
&odl_used, &odl_comp, &odl_uncomp);
- dused = csa->cds->ds_phys->ds_used_bytes + cdl_used -
- (csa->ohds->ds_phys->ds_used_bytes + odl_used);
+ dused = csa->cds->ds_phys->ds_referenced_bytes + cdl_used -
+ (csa->ohds->ds_phys->ds_referenced_bytes + odl_used);
dcomp = csa->cds->ds_phys->ds_compressed_bytes + cdl_comp -
(csa->ohds->ds_phys->ds_compressed_bytes + odl_comp);
duncomp = csa->cds->ds_phys->ds_uncompressed_bytes +
@@ -3257,8 +3329,8 @@
}
/* swap ds_*_bytes */
- SWITCH64(csa->ohds->ds_phys->ds_used_bytes,
- csa->cds->ds_phys->ds_used_bytes);
+ SWITCH64(csa->ohds->ds_phys->ds_referenced_bytes,
+ csa->cds->ds_phys->ds_referenced_bytes);
SWITCH64(csa->ohds->ds_phys->ds_compressed_bytes,
csa->cds->ds_phys->ds_compressed_bytes);
SWITCH64(csa->ohds->ds_phys->ds_uncompressed_bytes,
@@ -3387,8 +3459,9 @@
* on-disk is over quota and there are no pending changes (which
* may free up space for us).
*/
- if (ds->ds_phys->ds_used_bytes + inflight >= ds->ds_quota) {
- if (inflight > 0 || ds->ds_phys->ds_used_bytes < ds->ds_quota)
+ if (ds->ds_phys->ds_referenced_bytes + inflight >= ds->ds_quota) {
+ if (inflight > 0 ||
+ ds->ds_phys->ds_referenced_bytes < ds->ds_quota)
error = ERESTART;
else
error = EDQUOT;
@@ -3415,7 +3488,7 @@
if (psa->psa_effective_value == 0)
return (0);
- if (psa->psa_effective_value < ds->ds_phys->ds_used_bytes ||
+ if (psa->psa_effective_value < ds->ds_phys->ds_referenced_bytes ||
psa->psa_effective_value < ds->ds_reserved)
return (ENOSPC);
@@ -4169,8 +4242,8 @@
dsl_pool_t *dp = new->ds_dir->dd_pool;
*usedp = 0;
- *usedp += new->ds_phys->ds_used_bytes;
- *usedp -= oldsnap->ds_phys->ds_used_bytes;
+ *usedp += new->ds_phys->ds_referenced_bytes;
+ *usedp -= oldsnap->ds_phys->ds_referenced_bytes;
*compp = 0;
*compp += new->ds_phys->ds_compressed_bytes;
@@ -4186,9 +4259,13 @@
dsl_dataset_t *snap;
uint64_t used, comp, uncomp;
- err = dsl_dataset_hold_obj(dp, snapobj, FTAG, &snap);
- if (err != 0)
- break;
+ if (snapobj == new->ds_object) {
+ snap = new;
+ } else {
+ err = dsl_dataset_hold_obj(dp, snapobj, FTAG, &snap);
+ if (err != 0)
+ break;
+ }
if (snap->ds_phys->ds_prev_snap_txg ==
oldsnap->ds_phys->ds_creation_txg) {
@@ -4217,7 +4294,8 @@
* was not a snapshot of/before new.
*/
snapobj = snap->ds_phys->ds_prev_snap_obj;
- dsl_dataset_rele(snap, FTAG);
+ if (snap != new)
+ dsl_dataset_rele(snap, FTAG);
if (snapobj == 0) {
err = EINVAL;
break;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deleg.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deleg.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deleg.c Wed Jul 25 16:45:04 2012 +0300
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
/*
@@ -171,10 +171,8 @@
VERIFY(nvpair_value_nvlist(whopair, &perms) == 0);
if (zap_lookup(mos, zapobj, whokey, 8, 1, &jumpobj) != 0) {
- jumpobj = zap_create(mos, DMU_OT_DSL_PERMS,
- DMU_OT_NONE, 0, tx);
- VERIFY(zap_update(mos, zapobj,
- whokey, 8, 1, &jumpobj, tx) == 0);
+ jumpobj = zap_create_link(mos, DMU_OT_DSL_PERMS,
+ zapobj, whokey, tx);
}
while (permpair = nvlist_next_nvpair(perms, permpair)) {
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c Wed Jul 25 16:45:04 2012 +0300
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/dsl_pool.h>
@@ -40,6 +40,8 @@
#include <sys/zfs_znode.h>
#include <sys/spa_impl.h>
#include <sys/dsl_deadlist.h>
+#include <sys/bptree.h>
+#include <sys/zfeature.h>
int zfs_no_write_throttle = 0;
int zfs_write_limit_shift = 3; /* 1/8th of physical memory */
@@ -125,20 +127,32 @@
}
int
-dsl_pool_open(spa_t *spa, uint64_t txg, dsl_pool_t **dpp)
+dsl_pool_init(spa_t *spa, uint64_t txg, dsl_pool_t **dpp)
{
int err;
dsl_pool_t *dp = dsl_pool_open_impl(spa, txg);
+
+ err = dmu_objset_open_impl(spa, NULL, &dp->dp_meta_rootbp,
+ &dp->dp_meta_objset);
+ if (err != 0)
+ dsl_pool_close(dp);
+ else
+ *dpp = dp;
+
+ return (err);
+}
+
+int
+dsl_pool_open(dsl_pool_t *dp)
+{
+ int err;
dsl_dir_t *dd;
dsl_dataset_t *ds;
uint64_t obj;
+ ASSERT(!dmu_objset_is_dirty_anywhere(dp->dp_meta_objset));
+
rw_enter(&dp->dp_config_rwlock, RW_WRITER);
- err = dmu_objset_open_impl(spa, NULL, &dp->dp_meta_rootbp,
- &dp->dp_meta_objset);
- if (err)
- goto out;
-
err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
DMU_POOL_ROOT_DATASET, sizeof (uint64_t), 1,
&dp->dp_root_dir_obj);
@@ -154,7 +168,7 @@
if (err)
goto out;
- if (spa_version(spa) >= SPA_VERSION_ORIGIN) {
+ if (spa_version(dp->dp_spa) >= SPA_VERSION_ORIGIN) {
err = dsl_pool_open_special_dir(dp, ORIGIN_DIR_NAME, &dd);
if (err)
goto out;
@@ -171,7 +185,7 @@
goto out;
}
- if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
+ if (spa_version(dp->dp_spa) >= SPA_VERSION_DEADLISTS) {
err = dsl_pool_open_special_dir(dp, FREE_DIR_NAME,
&dp->dp_free_dir);
if (err)
@@ -185,6 +199,15 @@
dp->dp_meta_objset, obj));
}
+ if (spa_feature_is_active(dp->dp_spa,
+ &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
+ err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+ DMU_POOL_BPTREE_OBJ, sizeof (uint64_t), 1,
+ &dp->dp_bptree_obj);
+ if (err != 0)
+ goto out;
+ }
+
err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
DMU_POOL_TMP_USERREFS, sizeof (uint64_t), 1,
&dp->dp_tmp_userrefs_obj);
@@ -193,15 +216,10 @@
if (err)
goto out;
- err = dsl_scan_init(dp, txg);
+ err = dsl_scan_init(dp, dp->dp_tx.tx_open_txg);
out:
rw_exit(&dp->dp_config_rwlock);
- if (err)
- dsl_pool_close(dp);
- else
- *dpp = dp;
-
return (err);
}
@@ -495,7 +513,7 @@
dsl_pool_sync_context(dsl_pool_t *dp)
{
return (curthread == dp->dp_tx.tx_sync_thread ||
- spa_get_dsl(dp->dp_spa) == NULL);
+ spa_is_initializing(dp->dp_spa));
}
uint64_t
@@ -813,11 +831,8 @@
ASSERT(dp->dp_tmp_userrefs_obj == 0);
ASSERT(dmu_tx_is_syncing(tx));
- dp->dp_tmp_userrefs_obj = zap_create(mos, DMU_OT_USERREFS,
- DMU_OT_NONE, 0, tx);
-
- VERIFY(zap_add(mos, DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_TMP_USERREFS,
- sizeof (uint64_t), 1, &dp->dp_tmp_userrefs_obj, tx) == 0);
+ dp->dp_tmp_userrefs_obj = zap_create_link(mos, DMU_OT_USERREFS,
+ DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_TMP_USERREFS, tx);
}
static int
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c Wed Jul 25 16:45:04 2012 +0300
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/dsl_scan.h>
@@ -44,6 +45,7 @@
#include <sys/ddt.h>
#include <sys/sa.h>
#include <sys/sa_impl.h>
+#include <sys/zfeature.h>
#ifdef _KERNEL
#include <sys/zfs_vfsops.h>
#endif
@@ -56,18 +58,48 @@
static dsl_syncfunc_t dsl_scan_cancel_sync;
static void dsl_scan_sync_state(dsl_scan_t *, dmu_tx_t *tx);
-int zfs_top_maxinflight = 32; /* maximum I/Os per top-level */
-int zfs_resilver_delay = 2; /* number of ticks to delay resilver */
-int zfs_scrub_delay = 4; /* number of ticks to delay scrub */
-int zfs_scan_idle = 50; /* idle window in clock ticks */
+unsigned int zfs_top_maxinflight = 32; /* maximum I/Os per top-level */
+unsigned int zfs_resilver_delay = 2; /* number of ticks to delay resilver */
+unsigned int zfs_scrub_delay = 4; /* number of ticks to delay scrub */
+unsigned int zfs_scan_idle = 50; /* idle window in clock ticks */
-int zfs_scan_min_time_ms = 1000; /* min millisecs to scrub per txg */
-int zfs_free_min_time_ms = 1000; /* min millisecs to free per txg */
-int zfs_resilver_min_time_ms = 3000; /* min millisecs to resilver per txg */
+unsigned int zfs_scan_min_time_ms = 1000; /* min millisecs to scrub per txg */
+unsigned int zfs_free_min_time_ms = 1000; /* min millisecs to free per txg */
+unsigned int zfs_resilver_min_time_ms = 3000; /* min millisecs to resilver
+ per txg */
boolean_t zfs_no_scrub_io = B_FALSE; /* set to disable scrub i/o */
boolean_t zfs_no_scrub_prefetch = B_FALSE; /* set to disable srub prefetching */
+
+SYSCTL_DECL(_vfs_zfs);
+TUNABLE_INT("vfs.zfs.top_maxinflight", &zfs_top_maxinflight);
+SYSCTL_UINT(_vfs_zfs, OID_AUTO, top_maxinflight, CTLFLAG_RW,
+ &zfs_top_maxinflight, 0, "Maximum I/Os per top-level vdev");
+TUNABLE_INT("vfs.zfs.resilver_delay", &zfs_resilver_delay);
+SYSCTL_UINT(_vfs_zfs, OID_AUTO, resilver_delay, CTLFLAG_RW,
+ &zfs_resilver_delay, 0, "Number of ticks to delay resilver");
+TUNABLE_INT("vfs.zfs.scrub_delay", &zfs_scrub_delay);
+SYSCTL_UINT(_vfs_zfs, OID_AUTO, scrub_delay, CTLFLAG_RW,
+ &zfs_scrub_delay, 0, "Number of ticks to delay scrub");
+TUNABLE_INT("vfs.zfs.scan_idle", &zfs_scan_idle);
+SYSCTL_UINT(_vfs_zfs, OID_AUTO, scan_idle, CTLFLAG_RW,
+ &zfs_scan_idle, 0, "Idle scan window in clock ticks");
+TUNABLE_INT("vfs.zfs.scan_min_time_ms", &zfs_scan_min_time_ms);
+SYSCTL_UINT(_vfs_zfs, OID_AUTO, scan_min_time_ms, CTLFLAG_RW,
+ &zfs_scan_min_time_ms, 0, "Min millisecs to scrub per txg");
+TUNABLE_INT("vfs.zfs.free_min_time_ms", &zfs_free_min_time_ms);
+SYSCTL_UINT(_vfs_zfs, OID_AUTO, free_min_time_ms, CTLFLAG_RW,
+ &zfs_free_min_time_ms, 0, "Min millisecs to free per txg");
+TUNABLE_INT("vfs.zfs.resilver_min_time_ms", &zfs_resilver_min_time_ms);
+SYSCTL_UINT(_vfs_zfs, OID_AUTO, resilver_min_time_ms, CTLFLAG_RW,
+ &zfs_resilver_min_time_ms, 0, "Min millisecs to resilver per txg");
+TUNABLE_INT("vfs.zfs.no_scrub_io", &zfs_no_scrub_io);
+SYSCTL_INT(_vfs_zfs, OID_AUTO, no_scrub_io, CTLFLAG_RW,
+ &zfs_no_scrub_io, 0, "Disable scrub I/O");
+TUNABLE_INT("vfs.zfs.no_scrub_prefetch", &zfs_no_scrub_prefetch);
+SYSCTL_INT(_vfs_zfs, OID_AUTO, no_scrub_prefetch, CTLFLAG_RW,
+ &zfs_no_scrub_prefetch, 0, "Disable scrub prefetching");
+
enum ddt_class zfs_scrub_ddt_class_max = DDT_CLASS_DUPLICATE;
-int dsl_scan_delay_completion = B_FALSE; /* set to delay scan completion */
#define DSL_SCAN_IS_SCRUB_RESILVER(scn) \
((scn)->scn_phys.scn_func == POOL_SCAN_SCRUB || \
@@ -382,55 +414,6 @@
priority, zio_flags, arc_flags, zb));
}
-static boolean_t
-bookmark_is_zero(const zbookmark_t *zb)
-{
- return (zb->zb_objset == 0 && zb->zb_object == 0 &&
- zb->zb_level == 0 && zb->zb_blkid == 0);
-}
-
-/* dnp is the dnode for zb1->zb_object */
-static boolean_t
-bookmark_is_before(const dnode_phys_t *dnp, const zbookmark_t *zb1,
- const zbookmark_t *zb2)
-{
- uint64_t zb1nextL0, zb2thisobj;
-
- ASSERT(zb1->zb_objset == zb2->zb_objset);
- ASSERT(zb2->zb_level == 0);
-
- /*
- * A bookmark in the deadlist is considered to be after
- * everything else.
- */
- if (zb2->zb_object == DMU_DEADLIST_OBJECT)
- return (B_TRUE);
-
- /* The objset_phys_t isn't before anything. */
- if (dnp == NULL)
- return (B_FALSE);
-
- zb1nextL0 = (zb1->zb_blkid + 1) <<
- ((zb1->zb_level) * (dnp->dn_indblkshift - SPA_BLKPTRSHIFT));
-
- zb2thisobj = zb2->zb_object ? zb2->zb_object :
- zb2->zb_blkid << (DNODE_BLOCK_SHIFT - DNODE_SHIFT);
-
- if (zb1->zb_object == DMU_META_DNODE_OBJECT) {
- uint64_t nextobj = zb1nextL0 *
- (dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT) >> DNODE_SHIFT;
- return (nextobj <= zb2thisobj);
- }
-
- if (zb1->zb_object < zb2thisobj)
- return (B_TRUE);
- if (zb1->zb_object > zb2thisobj)
- return (B_FALSE);
- if (zb2->zb_object == DMU_META_DNODE_OBJECT)
- return (B_FALSE);
- return (zb1nextL0 <= zb2->zb_blkid);
-}
-
static uint64_t
dsl_scan_ds_maxtxg(dsl_dataset_t *ds)
{
@@ -453,7 +436,7 @@
dsl_scan_check_pause(dsl_scan_t *scn, const zbookmark_t *zb)
{
uint64_t elapsed_nanosecs;
- int mintime;
+ unsigned int mintime;
/* we never skip user/group accounting objects */
if (zb && (int64_t)zb->zb_object < 0)
@@ -462,7 +445,7 @@
if (scn->scn_pausing)
return (B_TRUE); /* we're already pausing */
- if (!bookmark_is_zero(&scn->scn_phys.scn_bookmark))
+ if (!ZB_IS_ZERO(&scn->scn_phys.scn_bookmark))
return (B_FALSE); /* we're resuming */
/* We only know how to resume from level-0 blocks. */
@@ -617,13 +600,13 @@
/*
* We never skip over user/group accounting objects (obj<0)
*/
- if (!bookmark_is_zero(&scn->scn_phys.scn_bookmark) &&
+ if (!ZB_IS_ZERO(&scn->scn_phys.scn_bookmark) &&
(int64_t)zb->zb_object >= 0) {
/*
* If we already visited this bp & everything below (in
* a prior txg sync), don't bother doing it again.
*/
- if (bookmark_is_before(dnp, zb, &scn->scn_phys.scn_bookmark))
+ if (zbookmark_is_before(dnp, zb, &scn->scn_phys.scn_bookmark))
return (B_TRUE);
/*
@@ -816,22 +799,6 @@
if (bp->blk_birth <= scn->scn_phys.scn_cur_min_txg)
return;
- if (BP_GET_TYPE(bp) != DMU_OT_USERGROUP_USED) {
- /*
- * For non-user-accounting blocks, we need to read the
- * new bp (from a deleted snapshot, found in
- * check_existing_xlation). If we used the old bp,
- * pointers inside this block from before we resumed
- * would be untranslated.
- *
- * For user-accounting blocks, we need to read the old
- * bp, because we will apply the entire space delta to
- * it (original untranslated -> translations from
- * deleted snap -> now).
- */
- bp_toread = *bp;
- }
-
if (dsl_scan_recurse(scn, ds, ostype, dnp, &bp_toread, zb, tx,
&buf) != 0)
return;
@@ -1396,19 +1363,28 @@
zap_cursor_fini(&zc);
}
-static int
-dsl_scan_free_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
+static boolean_t
+dsl_scan_free_should_pause(dsl_scan_t *scn)
{
- dsl_scan_t *scn = arg;
uint64_t elapsed_nanosecs;
elapsed_nanosecs = gethrtime() - scn->scn_sync_start_time;
-
- if (elapsed_nanosecs / NANOSEC > zfs_txg_timeout ||
+ return (elapsed_nanosecs / NANOSEC > zfs_txg_timeout ||
(elapsed_nanosecs / MICROSEC > zfs_free_min_time_ms &&
txg_sync_waiting(scn->scn_dp)) ||
- spa_shutting_down(scn->scn_dp->dp_spa))
- return (ERESTART);
+ spa_shutting_down(scn->scn_dp->dp_spa));
+}
+
+static int
+dsl_scan_free_block_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
+{
+ dsl_scan_t *scn = arg;
+
+ if (!scn->scn_is_bptree ||
+ (BP_GET_LEVEL(bp) == 0 && BP_GET_TYPE(bp) != DMU_OT_OBJSET)) {
+ if (dsl_scan_free_should_pause(scn))
+ return (ERESTART);
+ }
zio_nowait(zio_free_sync(scn->scn_zio_root, scn->scn_dp->dp_spa,
dmu_tx_get_txg(tx), bp, 0));
@@ -1433,6 +1409,10 @@
if (scn->scn_phys.scn_state == DSS_SCANNING)
return (B_TRUE);
+ if (spa_feature_is_active(spa,
+ &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
+ return (B_TRUE);
+ }
if (spa_version(scn->scn_dp->dp_spa) >= SPA_VERSION_DEADLISTS) {
(void) bpobj_space(&scn->scn_dp->dp_free_bpobj,
&used, &comp, &uncomp);
@@ -1479,14 +1459,40 @@
* traversing it.
*/
if (spa_version(dp->dp_spa) >= SPA_VERSION_DEADLISTS) {
+ scn->scn_is_bptree = B_FALSE;
scn->scn_zio_root = zio_root(dp->dp_spa, NULL,
NULL, ZIO_FLAG_MUSTSUCCEED);
err = bpobj_iterate(&dp->dp_free_bpobj,
- dsl_scan_free_cb, scn, tx);
+ dsl_scan_free_block_cb, scn, tx);
VERIFY3U(0, ==, zio_wait(scn->scn_zio_root));
+
+ if (err == 0 && spa_feature_is_active(spa,
+ &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
+ scn->scn_is_bptree = B_TRUE;
+ scn->scn_zio_root = zio_root(dp->dp_spa, NULL,
+ NULL, ZIO_FLAG_MUSTSUCCEED);
+ err = bptree_iterate(dp->dp_meta_objset,
+ dp->dp_bptree_obj, B_TRUE, dsl_scan_free_block_cb,
+ scn, tx);
+ VERIFY3U(0, ==, zio_wait(scn->scn_zio_root));
+ if (err != 0)
+ return;
+
+ /* disable async destroy feature */
+ spa_feature_decr(spa,
+ &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY], tx);
+ ASSERT(!spa_feature_is_active(spa,
+ &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY]));
+ VERIFY3U(0, ==, zap_remove(dp->dp_meta_objset,
+ DMU_POOL_DIRECTORY_OBJECT,
+ DMU_POOL_BPTREE_OBJ, tx));
+ VERIFY3U(0, ==, bptree_free(dp->dp_meta_objset,
+ dp->dp_bptree_obj, tx));
+ dp->dp_bptree_obj = 0;
+ }
if (scn->scn_visited_this_txg) {
zfs_dbgmsg("freed %llu blocks in %llums from "
- "free_bpobj txg %llu",
+ "free_bpobj/bptree txg %llu",
(longlong_t)scn->scn_visited_this_txg,
(longlong_t)
(gethrtime() - scn->scn_sync_start_time) / MICROSEC,
@@ -1601,6 +1607,8 @@
for (i = 0; i < 4; i++) {
int l = (i < 2) ? BP_GET_LEVEL(bp) : DN_MAX_LEVELS;
int t = (i & 1) ? BP_GET_TYPE(bp) : DMU_OT_TOTAL;
+ if (t & DMU_OT_NEWTYPE)
+ t = DMU_OT_OTHER;
zfs_blkstat_t *zb = &zab->zab_type[l][t];
int equal;
@@ -1661,7 +1669,7 @@
boolean_t needs_io;
int zio_flags = ZIO_FLAG_SCAN_THREAD | ZIO_FLAG_RAW | ZIO_FLAG_CANFAIL;
int zio_priority;
- int scan_delay = 0;
+ unsigned int scan_delay = 0;
if (phys_birth <= scn->scn_phys.scn_min_txg ||
phys_birth >= scn->scn_phys.scn_max_txg)
@@ -1718,7 +1726,8 @@
if (needs_io && !zfs_no_scrub_io) {
vdev_t *rvd = spa->spa_root_vdev;
- uint64_t maxinflight = rvd->vdev_children * zfs_top_maxinflight;
+ uint64_t maxinflight = rvd->vdev_children *
+ MAX(zfs_top_maxinflight, 1);
void *data = zio_data_buf_alloc(size);
mutex_enter(&spa->spa_scrub_lock);
@@ -1732,7 +1741,7 @@
* then throttle our workload to limit the impact of a scan.
*/
if (ddi_get_lbolt64() - spa->spa_last_io <= zfs_scan_idle)
- delay(scan_delay);
+ delay(MAX((int)scan_delay, 0));
zio_nowait(zio_read(NULL, spa, bp, data, size,
dsl_scan_scrub_done, NULL, zio_priority,
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c Wed Jul 25 16:45:04 2012 +0300
@@ -18,9 +18,11 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Portions Copyright 2011 iXsystems, Inc
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@@ -427,10 +429,9 @@
char attr_name[8];
if (sa->sa_layout_attr_obj == 0) {
- sa->sa_layout_attr_obj = zap_create(os,
- DMU_OT_SA_ATTR_LAYOUTS, DMU_OT_NONE, 0, tx);
- VERIFY(zap_add(os, sa->sa_master_obj, SA_LAYOUTS, 8, 1,
- &sa->sa_layout_attr_obj, tx) == 0);
+ sa->sa_layout_attr_obj = zap_create_link(os,
+ DMU_OT_SA_ATTR_LAYOUTS,
+ sa->sa_master_obj, SA_LAYOUTS, tx);
}
(void) snprintf(attr_name, sizeof (attr_name),
@@ -1552,10 +1553,9 @@
}
if (sa->sa_reg_attr_obj == 0) {
- sa->sa_reg_attr_obj = zap_create(hdl->sa_os,
- DMU_OT_SA_ATTR_REGISTRATION, DMU_OT_NONE, 0, tx);
- VERIFY(zap_add(hdl->sa_os, sa->sa_master_obj,
- SA_REGISTRY, 8, 1, &sa->sa_reg_attr_obj, tx) == 0);
+ sa->sa_reg_attr_obj = zap_create_link(hdl->sa_os,
+ DMU_OT_SA_ATTR_REGISTRATION,
+ sa->sa_master_obj, SA_REGISTRY, tx);
}
for (i = 0; i != sa->sa_num_attrs; i++) {
if (sa->sa_attr_table[i].sa_registered)
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c Wed Jul 25 16:45:04 2012 +0300
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
/*
@@ -60,6 +60,7 @@
#include <sys/spa_boot.h>
#include <sys/zfs_ioctl.h>
#include <sys/dsl_scan.h>
+#include <sys/zfeature.h>
#include <sys/zvol.h>
#ifdef _KERNEL
@@ -117,6 +118,7 @@
{ ZTI_ONE, ZTI_NULL, ZTI_ONE, ZTI_NULL },
};
+static dsl_syncfunc_t spa_sync_version;
static dsl_syncfunc_t spa_sync_props;
static boolean_t spa_has_active_shared_spare(spa_t *spa);
static int spa_load_impl(spa_t *spa, uint64_t, nvlist_t *config,
@@ -175,15 +177,18 @@
static void
spa_prop_get_config(spa_t *spa, nvlist_t **nvp)
{
+ vdev_t *rvd = spa->spa_root_vdev;
+ dsl_pool_t *pool = spa->spa_dsl_pool;
uint64_t size;
uint64_t alloc;
+ uint64_t space;
uint64_t cap, version;
zprop_source_t src = ZPROP_SRC_NONE;
spa_config_dirent_t *dp;
ASSERT(MUTEX_HELD(&spa->spa_props_lock));
- if (spa->spa_root_vdev != NULL) {
+ if (rvd != NULL) {
alloc = metaslab_class_get_alloc(spa_normal_class(spa));
size = metaslab_class_get_space(spa_normal_class(spa));
spa_prop_add_list(*nvp, ZPOOL_PROP_NAME, spa_name(spa), 0, src);
@@ -191,6 +196,15 @@
spa_prop_add_list(*nvp, ZPOOL_PROP_ALLOCATED, NULL, alloc, src);
spa_prop_add_list(*nvp, ZPOOL_PROP_FREE, NULL,
size - alloc, src);
+
+ space = 0;
+ for (int c = 0; c < rvd->vdev_children; c++) {
+ vdev_t *tvd = rvd->vdev_child[c];
+ space += tvd->vdev_max_asize - tvd->vdev_asize;
+ }
+ spa_prop_add_list(*nvp, ZPOOL_PROP_EXPANDSZ, NULL, space,
+ src);
+
spa_prop_add_list(*nvp, ZPOOL_PROP_READONLY, NULL,
(spa_mode(spa) == FREAD), src);
@@ -201,7 +215,7 @@
ddt_get_pool_dedup_ratio(spa), src);
spa_prop_add_list(*nvp, ZPOOL_PROP_HEALTH, NULL,
- spa->spa_root_vdev->vdev_state, src);
+ rvd->vdev_state, src);
version = spa_version(spa);
if (version == zpool_prop_default_numeric(ZPOOL_PROP_VERSION))
@@ -211,6 +225,22 @@
spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL, version, src);
}
+ if (pool != NULL) {
+ dsl_dir_t *freedir = pool->dp_free_dir;
+
+ /*
+ * The $FREE directory was introduced in SPA_VERSION_DEADLISTS,
+ * when opening pools before this version freedir will be NULL.
+ */
+ if (freedir != NULL) {
+ spa_prop_add_list(*nvp, ZPOOL_PROP_FREEING, NULL,
+ freedir->dd_phys->dd_used_bytes, src);
+ } else {
+ spa_prop_add_list(*nvp, ZPOOL_PROP_FREEING,
+ NULL, 0, src);
+ }
+ }
+
spa_prop_add_list(*nvp, ZPOOL_PROP_GUID, NULL, spa_guid(spa), src);
if (spa->spa_comment != NULL) {
@@ -350,25 +380,55 @@
nvpair_t *elem;
int error = 0, reset_bootfs = 0;
uint64_t objnum;
+ boolean_t has_feature = B_FALSE;
elem = NULL;
while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
- zpool_prop_t prop;
- char *propname, *strval;
uint64_t intval;
- objset_t *os;
- char *slash, *check;
-
- propname = nvpair_name(elem);
-
- if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL)
- return (EINVAL);
+ char *strval, *slash, *check, *fname;
+ const char *propname = nvpair_name(elem);
+ zpool_prop_t prop = zpool_name_to_prop(propname);
switch (prop) {
+ case ZPROP_INVAL:
+ if (!zpool_prop_feature(propname)) {
+ error = EINVAL;
+ break;
+ }
+
+ /*
+ * Sanitize the input.
+ */
+ if (nvpair_type(elem) != DATA_TYPE_UINT64) {
+ error = EINVAL;
+ break;
+ }
+
+ if (nvpair_value_uint64(elem, &intval) != 0) {
+ error = EINVAL;
+ break;
+ }
+
+ if (intval != 0) {
+ error = EINVAL;
+ break;
+ }
+
+ fname = strchr(propname, '@') + 1;
+ if (zfeature_lookup_name(fname, NULL) != 0) {
+ error = EINVAL;
+ break;
+ }
+
+ has_feature = B_TRUE;
+ break;
+
case ZPOOL_PROP_VERSION:
error = nvpair_value_uint64(elem, &intval);
if (!error &&
- (intval < spa_version(spa) || intval > SPA_VERSION))
+ (intval < spa_version(spa) ||
+ intval > SPA_VERSION_BEFORE_FEATURES ||
+ has_feature))
error = EINVAL;
break;
@@ -405,6 +465,7 @@
error = nvpair_value_string(elem, &strval);
if (!error) {
+ objset_t *os;
uint64_t compress;
if (strval == NULL || strval[0] == '\0') {
@@ -554,33 +615,58 @@
spa_prop_set(spa_t *spa, nvlist_t *nvp)
{
int error;
- nvpair_t *elem;
+ nvpair_t *elem = NULL;
boolean_t need_sync = B_FALSE;
- zpool_prop_t prop;
if ((error = spa_prop_validate(spa, nvp)) != 0)
return (error);
- elem = NULL;
while ((elem = nvlist_next_nvpair(nvp, elem)) != NULL) {
- if ((prop = zpool_name_to_prop(
- nvpair_name(elem))) == ZPROP_INVAL)
- return (EINVAL);
+ zpool_prop_t prop = zpool_name_to_prop(nvpair_name(elem));
if (prop == ZPOOL_PROP_CACHEFILE ||
prop == ZPOOL_PROP_ALTROOT ||
prop == ZPOOL_PROP_READONLY)
continue;
+ if (prop == ZPOOL_PROP_VERSION || prop == ZPROP_INVAL) {
+ uint64_t ver;
+
+ if (prop == ZPOOL_PROP_VERSION) {
+ VERIFY(nvpair_value_uint64(elem, &ver) == 0);
+ } else {
+ ASSERT(zpool_prop_feature(nvpair_name(elem)));
+ ver = SPA_VERSION_FEATURES;
+ need_sync = B_TRUE;
+ }
+
+ /* Save time if the version is already set. */
+ if (ver == spa_version(spa))
+ continue;
+
+ /*
+ * In addition to the pool directory object, we might
+ * create the pool properties object, the features for
+ * read object, the features for write object, or the
+ * feature descriptions object.
+ */
+ error = dsl_sync_task_do(spa_get_dsl(spa), NULL,
+ spa_sync_version, spa, &ver, 6);
+ if (error)
+ return (error);
+ continue;
+ }
+
need_sync = B_TRUE;
break;
}
- if (need_sync)
+ if (need_sync) {
return (dsl_sync_task_do(spa_get_dsl(spa), NULL, spa_sync_props,
- spa, nvp, 3));
- else
- return (0);
+ spa, nvp, 6));
+ }
+
+ return (0);
}
/*
@@ -1619,7 +1705,7 @@
int error = zio->io_error;
if (error) {
- if ((BP_GET_LEVEL(bp) != 0 || dmu_ot[type].ot_metadata) &&
+ if ((BP_GET_LEVEL(bp) != 0 || DMU_OT_IS_METADATA(type)) &&
type != DMU_OT_INTENT_LOG)
atomic_add_64(&sle->sle_meta_count, 1);
else
@@ -1849,6 +1935,9 @@
KM_SLEEP) == 0);
}
+ nvlist_free(spa->spa_load_info);
+ spa->spa_load_info = fnvlist_alloc();
+
gethrestime(&spa->spa_loaded_ts);
error = spa_load_impl(spa, pool_guid, config, state, type,
mosconfig, &ereport);
@@ -1881,12 +1970,14 @@
{
int error = 0;
nvlist_t *nvroot = NULL;
+ nvlist_t *label;
vdev_t *rvd;
uberblock_t *ub = &spa->spa_uberblock;
uint64_t children, config_cache_txg = spa->spa_config_txg;
int orig_mode = spa->spa_mode;
int parse;
uint64_t obj;
+ boolean_t missing_feat_write = B_FALSE;
/*
* If this is an untrusted config, access the pool in read-only mode.
@@ -1966,19 +2057,78 @@
/*
* Find the best uberblock.
*/
- vdev_uberblock_load(NULL, rvd, ub);
+ vdev_uberblock_load(rvd, ub, &label);
/*
* If we weren't able to find a single valid uberblock, return failure.
*/
- if (ub->ub_txg == 0)
+ if (ub->ub_txg == 0) {
+ nvlist_free(label);
return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, ENXIO));
+ }
/*
- * If the pool is newer than the code, we can't open it.
+ * If the pool has an unsupported version we can't open it.
*/
- if (ub->ub_version > SPA_VERSION)
+ if (!SPA_VERSION_IS_SUPPORTED(ub->ub_version)) {
+ nvlist_free(label);
return (spa_vdev_err(rvd, VDEV_AUX_VERSION_NEWER, ENOTSUP));
+ }
+
+ if (ub->ub_version >= SPA_VERSION_FEATURES) {
+ nvlist_t *features;
+
+ /*
+ * If we weren't able to find what's necessary for reading the
+ * MOS in the label, return failure.
+ */
+ if (label == NULL || nvlist_lookup_nvlist(label,
+ ZPOOL_CONFIG_FEATURES_FOR_READ, &features) != 0) {
+ nvlist_free(label);
+ return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA,
+ ENXIO));
+ }
+
+ /*
+ * Update our in-core representation with the definitive values
+ * from the label.
+ */
+ nvlist_free(spa->spa_label_features);
+ VERIFY(nvlist_dup(features, &spa->spa_label_features, 0) == 0);
+ }
+
+ nvlist_free(label);
+
+ /*
+ * Look through entries in the label nvlist's features_for_read. If
+ * there is a feature listed there which we don't understand then we
+ * cannot open a pool.
+ */
+ if (ub->ub_version >= SPA_VERSION_FEATURES) {
+ nvlist_t *unsup_feat;
+
+ VERIFY(nvlist_alloc(&unsup_feat, NV_UNIQUE_NAME, KM_SLEEP) ==
+ 0);
+
+ for (nvpair_t *nvp = nvlist_next_nvpair(spa->spa_label_features,
+ NULL); nvp != NULL;
+ nvp = nvlist_next_nvpair(spa->spa_label_features, nvp)) {
+ if (!zfeature_is_supported(nvpair_name(nvp))) {
+ VERIFY(nvlist_add_string(unsup_feat,
+ nvpair_name(nvp), "") == 0);
+ }
+ }
+
+ if (!nvlist_empty(unsup_feat)) {
+ VERIFY(nvlist_add_nvlist(spa->spa_load_info,
+ ZPOOL_CONFIG_UNSUP_FEAT, unsup_feat) == 0);
+ nvlist_free(unsup_feat);
+ return (spa_vdev_err(rvd, VDEV_AUX_UNSUP_FEAT,
+ ENOTSUP));
+ }
+
+ nvlist_free(unsup_feat);
+ }
/*
* If the vdev guid sum doesn't match the uberblock, we have an
@@ -2012,7 +2162,7 @@
spa->spa_claim_max_txg = spa->spa_first_txg;
spa->spa_prev_software_version = ub->ub_software_version;
- error = dsl_pool_open(spa, spa->spa_first_txg, &spa->spa_dsl_pool);
+ error = dsl_pool_init(spa, spa->spa_first_txg, &spa->spa_dsl_pool);
if (error)
return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
spa->spa_meta_objset = spa->spa_dsl_pool->dp_meta_objset;
@@ -2020,6 +2170,84 @@
if (spa_dir_prop(spa, DMU_POOL_CONFIG, &spa->spa_config_object) != 0)
return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+ if (spa_version(spa) >= SPA_VERSION_FEATURES) {
+ boolean_t missing_feat_read = B_FALSE;
+ nvlist_t *unsup_feat;
+
+ if (spa_dir_prop(spa, DMU_POOL_FEATURES_FOR_READ,
+ &spa->spa_feat_for_read_obj) != 0) {
+ return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+ }
+
+ if (spa_dir_prop(spa, DMU_POOL_FEATURES_FOR_WRITE,
+ &spa->spa_feat_for_write_obj) != 0) {
+ return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+ }
+
+ if (spa_dir_prop(spa, DMU_POOL_FEATURE_DESCRIPTIONS,
+ &spa->spa_feat_desc_obj) != 0) {
+ return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+ }
+
+ VERIFY(nvlist_alloc(&unsup_feat, NV_UNIQUE_NAME, KM_SLEEP) ==
+ 0);
+
+ if (!feature_is_supported(spa->spa_meta_objset,
+ spa->spa_feat_for_read_obj, spa->spa_feat_desc_obj,
+ unsup_feat))
+ missing_feat_read = B_TRUE;
+
+ if (spa_writeable(spa) || state == SPA_LOAD_TRYIMPORT) {
+ if (!feature_is_supported(spa->spa_meta_objset,
+ spa->spa_feat_for_write_obj, spa->spa_feat_desc_obj,
+ unsup_feat))
+ missing_feat_write = B_TRUE;
+ }
+
+ if (!nvlist_empty(unsup_feat)) {
+ VERIFY(nvlist_add_nvlist(spa->spa_load_info,
+ ZPOOL_CONFIG_UNSUP_FEAT, unsup_feat) == 0);
+ }
+
+ nvlist_free(unsup_feat);
+
+ if (!missing_feat_read) {
+ fnvlist_add_boolean(spa->spa_load_info,
+ ZPOOL_CONFIG_CAN_RDONLY);
+ }
+
+ /*
+ * If the state is SPA_LOAD_TRYIMPORT, our objective is
+ * twofold: to determine whether the pool is available for
+ * import in read-write mode and (if it is not) whether the
+ * pool is available for import in read-only mode. If the pool
+ * is available for import in read-write mode, it is displayed
+ * as available in userland; if it is not available for import
+ * in read-only mode, it is displayed as unavailable in
+ * userland. If the pool is available for import in read-only
+ * mode but not read-write mode, it is displayed as unavailable
+ * in userland with a special note that the pool is actually
+ * available for open in read-only mode.
+ *
+ * As a result, if the state is SPA_LOAD_TRYIMPORT and we are
+ * missing a feature for write, we must first determine whether
+ * the pool can be opened read-only before returning to
+ * userland in order to know whether to display the
+ * abovementioned note.
+ */
+ if (missing_feat_read || (missing_feat_write &&
+ spa_writeable(spa))) {
+ return (spa_vdev_err(rvd, VDEV_AUX_UNSUP_FEAT,
+ ENOTSUP));
+ }
+ }
+
+ spa->spa_is_initializing = B_TRUE;
+ error = dsl_pool_open(spa->spa_dsl_pool);
+ spa->spa_is_initializing = B_FALSE;
+ if (error != 0)
+ return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+
if (!mosconfig) {
uint64_t hostid;
nvlist_t *policy = NULL, *nvconfig;
@@ -2050,7 +2278,7 @@
cmn_err(CE_WARN, "pool '%s' could not be "
"loaded as it was last accessed by "
"another system (host: %s hostid: 0x%lx). "
- "See: http://www.sun.com/msg/ZFS-8000-EY",
+ "See: http://illumos.org/msg/ZFS-8000-EY",
spa_name(spa), hostname,
(unsigned long)hostid);
return (EBADF);
@@ -2237,7 +2465,7 @@
nvlist_free(nvconfig);
/*
- * Now that we've validate the config, check the state of the
+ * Now that we've validated the config, check the state of the
* root vdev. If it can't be opened, it indicates one or
* more toplevel vdevs are faulted.
*/
@@ -2250,6 +2478,17 @@
}
}
+ if (missing_feat_write) {
+ ASSERT(state == SPA_LOAD_TRYIMPORT);
+
+ /*
+ * At this point, we know that we can open the pool in
+ * read-only mode but not read-write mode. We now have enough
+ * information and can return to userland.
+ */
+ return (spa_vdev_err(rvd, VDEV_AUX_UNSUP_FEAT, ENOTSUP));
+ }
+
/*
* We've successfully opened the pool, verify that we're ready
* to start pushing transactions.
@@ -2359,10 +2598,18 @@
return (spa_load(spa, state, SPA_IMPORT_EXISTING, mosconfig));
}
+/*
+ * If spa_load() fails this function will try loading prior txg's. If
+ * 'state' is SPA_LOAD_RECOVER and one of these loads succeeds the pool
+ * will be rewound to that txg. If 'state' is not SPA_LOAD_RECOVER this
+ * function will not rewind the pool and will return the same error as
+ * spa_load().
+ */
static int
spa_load_best(spa_t *spa, spa_load_state_t state, int mosconfig,
uint64_t max_request, int rewind_flags)
{
+ nvlist_t *loadinfo = NULL;
nvlist_t *config = NULL;
int load_error, rewind_error;
uint64_t safe_rewind_txg;
@@ -2391,9 +2638,18 @@
return (load_error);
}
- /* Price of rolling back is discarding txgs, including log */
- if (state == SPA_LOAD_RECOVER)
+ if (state == SPA_LOAD_RECOVER) {
+ /* Price of rolling back is discarding txgs, including log */
spa_set_log_state(spa, SPA_LOG_CLEAR);
+ } else {
+ /*
+ * If we aren't rolling back save the load info from our first
+ * import attempt so that we can restore it after attempting
+ * to rewind.
+ */
+ loadinfo = spa->spa_load_info;
+ spa->spa_load_info = fnvlist_alloc();
+ }
spa->spa_load_max_txg = spa->spa_last_ubsync_txg;
safe_rewind_txg = spa->spa_last_ubsync_txg - TXG_DEFER_SIZE;
@@ -2417,7 +2673,20 @@
if (config && (rewind_error || state != SPA_LOAD_RECOVER))
spa_config_set(spa, config);
- return (state == SPA_LOAD_RECOVER ? rewind_error : load_error);
+ if (state == SPA_LOAD_RECOVER) {
+ ASSERT3P(loadinfo, ==, NULL);
+ return (rewind_error);
+ } else {
+ /* Store the rewind info as part of the initial load info */
+ fnvlist_add_nvlist(loadinfo, ZPOOL_CONFIG_REWIND_INFO,
+ spa->spa_load_info);
+
+ /* Restore the initial load info */
+ fnvlist_free(spa->spa_load_info);
+ spa->spa_load_info = loadinfo;
+
+ return (load_error);
+ }
}
/*
@@ -2696,8 +2965,50 @@
}
}
+static void
+spa_add_feature_stats(spa_t *spa, nvlist_t *config)
+{
+ nvlist_t *features;
+ zap_cursor_t zc;
+ zap_attribute_t za;
+
+ ASSERT(spa_config_held(spa, SCL_CONFIG, RW_READER));
+ VERIFY(nvlist_alloc(&features, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+
+ if (spa->spa_feat_for_read_obj != 0) {
+ for (zap_cursor_init(&zc, spa->spa_meta_objset,
+ spa->spa_feat_for_read_obj);
+ zap_cursor_retrieve(&zc, &za) == 0;
+ zap_cursor_advance(&zc)) {
+ ASSERT(za.za_integer_length == sizeof (uint64_t) &&
+ za.za_num_integers == 1);
+ VERIFY3U(0, ==, nvlist_add_uint64(features, za.za_name,
+ za.za_first_integer));
+ }
+ zap_cursor_fini(&zc);
+ }
+
+ if (spa->spa_feat_for_write_obj != 0) {
+ for (zap_cursor_init(&zc, spa->spa_meta_objset,
+ spa->spa_feat_for_write_obj);
+ zap_cursor_retrieve(&zc, &za) == 0;
+ zap_cursor_advance(&zc)) {
+ ASSERT(za.za_integer_length == sizeof (uint64_t) &&
+ za.za_num_integers == 1);
+ VERIFY3U(0, ==, nvlist_add_uint64(features, za.za_name,
+ za.za_first_integer));
+ }
+ zap_cursor_fini(&zc);
+ }
+
+ VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_FEATURE_STATS,
+ features) == 0);
+ nvlist_free(features);
+}
+
int
-spa_get_stats(const char *name, nvlist_t **config, char *altroot, size_t buflen)
+spa_get_stats(const char *name, nvlist_t **config,
+ char *altroot, size_t buflen)
{
int error;
spa_t *spa;
@@ -2732,6 +3043,7 @@
spa_add_spares(spa, *config);
spa_add_l2cache(spa, *config);
+ spa_add_feature_stats(spa, *config);
}
}
@@ -2952,6 +3264,7 @@
nvlist_t **spares, **l2cache;
uint_t nspares, nl2cache;
uint64_t version, obj;
+ boolean_t has_features;
/*
* If this pool already exists, return failure.
@@ -2977,10 +3290,18 @@
return (error);
}
- if (nvlist_lookup_uint64(props, zpool_prop_to_name(ZPOOL_PROP_VERSION),
- &version) != 0)
+ has_features = B_FALSE;
+ for (nvpair_t *elem = nvlist_next_nvpair(props, NULL);
+ elem != NULL; elem = nvlist_next_nvpair(props, elem)) {
+ if (zpool_prop_feature(nvpair_name(elem)))
+ has_features = B_TRUE;
+ }
+
+ if (has_features || nvlist_lookup_uint64(props,
+ zpool_prop_to_name(ZPOOL_PROP_VERSION), &version) != 0) {
version = SPA_VERSION;
- ASSERT(version <= SPA_VERSION);
+ }
+ ASSERT(SPA_VERSION_IS_SUPPORTED(version));
spa->spa_first_txg = txg;
spa->spa_uberblock.ub_txg = txg - 1;
@@ -3056,8 +3377,10 @@
spa->spa_l2cache.sav_sync = B_TRUE;
}
+ spa->spa_is_initializing = B_TRUE;
spa->spa_dsl_pool = dp = dsl_pool_create(spa, zplprops, txg);
spa->spa_meta_objset = dp->dp_meta_objset;
+ spa->spa_is_initializing = B_FALSE;
/*
* Create DDTs (dedup tables).
@@ -3081,6 +3404,9 @@
cmn_err(CE_PANIC, "failed to add pool config");
}
+ if (spa_version(spa) >= SPA_VERSION_FEATURES)
+ spa_feature_create_zap_objects(spa, tx);
+
if (zap_add(spa->spa_meta_objset,
DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_CREATION_VERSION,
sizeof (uint64_t), 1, &version, tx) != 0) {
@@ -3272,7 +3598,7 @@
}
#endif
if (config == NULL) {
- cmn_err(CE_NOTE, "Can not read the pool label from '%s'",
+ cmn_err(CE_NOTE, "Cannot read the pool label from '%s'",
devpath);
return (EIO);
}
@@ -3592,6 +3918,8 @@
state) == 0);
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TIMESTAMP,
spa->spa_uberblock.ub_timestamp) == 0);
+ VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_LOAD_INFO,
+ spa->spa_load_info) == 0);
/*
* If the bootfs property exists on this pool then we
@@ -5317,7 +5645,7 @@
* information. This avoids the dbuf_will_dirty() path and
* saves us a pre-read to get data we don't actually care about.
*/
- bufsize = P2ROUNDUP(nvsize, SPA_CONFIG_BLOCKSIZE);
+ bufsize = P2ROUNDUP((uint64_t)nvsize, SPA_CONFIG_BLOCKSIZE);
packed = kmem_alloc(bufsize, KM_SLEEP);
VERIFY(nvlist_pack(nv, &packed, &nvsize, NV_ENCODE_XDR,
@@ -5402,6 +5730,24 @@
spa_sync_nvlist(spa, spa->spa_config_object, config, tx);
}
+static void
+spa_sync_version(void *arg1, void *arg2, dmu_tx_t *tx)
+{
+ spa_t *spa = arg1;
+ uint64_t version = *(uint64_t *)arg2;
+
+ /*
+ * Setting the version is special cased when first creating the pool.
+ */
+ ASSERT(tx->tx_txg != TXG_INITIAL);
+
+ ASSERT(version <= SPA_VERSION);
+ ASSERT(version >= spa_version(spa));
+
+ spa->spa_uberblock.ub_version = version;
+ vdev_config_dirty(spa->spa_root_vdev);
+}
+
/*
* Set zpool properties.
*/
@@ -5411,32 +5757,38 @@
spa_t *spa = arg1;
objset_t *mos = spa->spa_meta_objset;
nvlist_t *nvp = arg2;
- nvpair_t *elem;
- uint64_t intval;
- char *strval;
- zpool_prop_t prop;
- const char *propname;
- zprop_type_t proptype;
+ nvpair_t *elem = NULL;
mutex_enter(&spa->spa_props_lock);
- elem = NULL;
while ((elem = nvlist_next_nvpair(nvp, elem))) {
+ uint64_t intval;
+ char *strval, *fname;
+ zpool_prop_t prop;
+ const char *propname;
+ zprop_type_t proptype;
+ zfeature_info_t *feature;
+
switch (prop = zpool_name_to_prop(nvpair_name(elem))) {
+ case ZPROP_INVAL:
+ /*
+ * We checked this earlier in spa_prop_validate().
+ */
+ ASSERT(zpool_prop_feature(nvpair_name(elem)));
+
+ fname = strchr(nvpair_name(elem), '@') + 1;
+ VERIFY3U(0, ==, zfeature_lookup_name(fname, &feature));
+
+ spa_feature_enable(spa, feature, tx);
+ break;
+
case ZPOOL_PROP_VERSION:
+ VERIFY(nvpair_value_uint64(elem, &intval) == 0);
/*
- * Only set version for non-zpool-creation cases
- * (set/import). spa_create() needs special care
- * for version setting.
+ * The version is synced seperatly before other
+ * properties and should be correct by now.
*/
- if (tx->tx_txg != TXG_INITIAL) {
- VERIFY(nvpair_value_uint64(elem,
- &intval) == 0);
- ASSERT(intval <= SPA_VERSION);
- ASSERT(intval >= spa_version(spa));
- spa->spa_uberblock.ub_version = intval;
- vdev_config_dirty(spa->spa_root_vdev);
- }
+ ASSERT3U(spa_version(spa), >=, intval);
break;
case ZPOOL_PROP_ALTROOT:
@@ -5473,14 +5825,10 @@
* Set pool property values in the poolprops mos object.
*/
if (spa->spa_pool_props_object == 0) {
- VERIFY((spa->spa_pool_props_object =
- zap_create(mos, DMU_OT_POOL_PROPS,
- DMU_OT_NONE, 0, tx)) > 0);
-
- VERIFY(zap_update(mos,
+ spa->spa_pool_props_object =
+ zap_create_link(mos, DMU_OT_POOL_PROPS,
DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_PROPS,
- 8, 1, &spa->spa_pool_props_object, tx)
- == 0);
+ tx);
}
/* normalize the property name */
@@ -5579,6 +5927,11 @@
/* Keeping the freedir open increases spa_minref */
spa->spa_minref += 3;
}
+
+ if (spa->spa_ubsync.ub_version < SPA_VERSION_FEATURES &&
+ spa->spa_uberblock.ub_version >= SPA_VERSION_FEATURES) {
+ spa_feature_create_zap_objects(spa, tx);
+ }
}
/*
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c Wed Jul 25 16:45:04 2012 +0300
@@ -22,7 +22,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@@ -35,6 +35,7 @@
#include <sys/zfs_ioctl.h>
#include <sys/utsname.h>
#include <sys/sunddi.h>
+#include <sys/zfeature.h>
#ifdef _KERNEL
#include <sys/kobj.h>
#include <sys/zone.h>
@@ -407,6 +408,12 @@
VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, nvroot) == 0);
nvlist_free(nvroot);
+ /*
+ * Store what's necessary for reading the MOS in the label.
+ */
+ VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_FEATURES_FOR_READ,
+ spa->spa_label_features) == 0);
+
if (getstats && spa_load_state(spa) == SPA_LOAD_NONE) {
ddt_histogram_t *ddh;
ddt_stat_t *dds;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c Wed Jul 25 16:45:04 2012 +0300
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
@@ -48,6 +48,7 @@
#include <sys/arc.h>
#include <sys/ddt.h>
#include "zfs_prop.h"
+#include "zfeature_common.h"
/*
* SPA locking
@@ -216,7 +217,7 @@
* Like spa_vdev_enter/exit, these are convenience wrappers -- the actual
* locking is, always, based on spa_namespace_lock and spa_config_lock[].
*
- * spa_rename() is also implemented within this file since is requires
+ * spa_rename() is also implemented within this file since it requires
* manipulation of the namespace.
*/
@@ -487,8 +488,22 @@
VERIFY(nvlist_alloc(&spa->spa_load_info, NV_UNIQUE_NAME,
KM_SLEEP) == 0);
- if (config != NULL)
+ if (config != NULL) {
+ nvlist_t *features;
+
+ if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_FEATURES_FOR_READ,
+ &features) == 0) {
+ VERIFY(nvlist_dup(features, &spa->spa_label_features,
+ 0) == 0);
+ }
+
VERIFY(nvlist_dup(config, &spa->spa_config, 0) == 0);
+ }
+
+ if (spa->spa_label_features == NULL) {
+ VERIFY(nvlist_alloc(&spa->spa_label_features, NV_UNIQUE_NAME,
+ KM_SLEEP) == 0);
+ }
return (spa);
}
@@ -525,6 +540,7 @@
list_destroy(&spa->spa_config_list);
+ nvlist_free(spa->spa_label_features);
nvlist_free(spa->spa_load_info);
spa_config_set(spa, NULL);
@@ -1033,6 +1049,20 @@
* ==========================================================================
*/
+void
+spa_activate_mos_feature(spa_t *spa, const char *feature)
+{
+ (void) nvlist_add_boolean(spa->spa_label_features, feature);
+ vdev_config_dirty(spa->spa_root_vdev);
+}
+
+void
+spa_deactivate_mos_feature(spa_t *spa, const char *feature)
+{
+ (void) nvlist_remove_all(spa->spa_label_features, feature);
+ vdev_config_dirty(spa->spa_root_vdev);
+}
+
/*
* Rename a spa_t.
*/
@@ -1183,12 +1213,22 @@
void
sprintf_blkptr(char *buf, const blkptr_t *bp)
{
- char *type = NULL;
+ char type[256];
char *checksum = NULL;
char *compress = NULL;
if (bp != NULL) {
- type = dmu_ot[BP_GET_TYPE(bp)].ot_name;
+ if (BP_GET_TYPE(bp) & DMU_OT_NEWTYPE) {
+ dmu_object_byteswap_t bswap =
+ DMU_OT_BYTESWAP(BP_GET_TYPE(bp));
+ (void) snprintf(type, sizeof (type), "bswap %s %s",
+ DMU_OT_IS_METADATA(BP_GET_TYPE(bp)) ?
+ "metadata" : "data",
+ dmu_ot_byteswap[bswap].ob_name);
+ } else {
+ (void) strlcpy(type, dmu_ot[BP_GET_TYPE(bp)].ot_name,
+ sizeof (type));
+ }
checksum = zio_checksum_table[BP_GET_CHECKSUM(bp)].ci_name;
compress = zio_compress_table[BP_GET_COMPRESS(bp)].ci_name;
}
@@ -1270,6 +1310,12 @@
return (spa->spa_dsl_pool);
}
+boolean_t
+spa_is_initializing(spa_t *spa)
+{
+ return (spa->spa_is_initializing);
+}
+
blkptr_t *
spa_get_rootblkptr(spa_t *spa)
{
@@ -1553,6 +1599,7 @@
vdev_cache_stat_init();
zfs_prop_init();
zpool_prop_init();
+ zpool_feature_init();
spa_config_load();
l2arc_start();
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c Wed Jul 25 16:45:04 2012 +0300
@@ -173,7 +173,6 @@
void
space_map_remove(space_map_t *sm, uint64_t start, uint64_t size)
{
- avl_index_t where;
space_seg_t ssearch, *ss, *newseg;
uint64_t end = start + size;
int left_over, right_over;
@@ -185,7 +184,7 @@
ssearch.ss_start = start;
ssearch.ss_end = end;
- ss = avl_find(&sm->sm_root, &ssearch, &where);
+ ss = avl_find(&sm->sm_root, &ssearch, NULL);
/* Make sure we completely overlap with someone */
if (ss == NULL) {
@@ -196,7 +195,7 @@
}
VERIFY3U(ss->ss_start, <=, start);
VERIFY3U(ss->ss_end, >=, end);
- VERIFY(sm->sm_space - size <= sm->sm_size);
+ VERIFY(sm->sm_space - size < sm->sm_size);
left_over = (ss->ss_start != start);
right_over = (ss->ss_end != end);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/bptree.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/bptree.h Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#ifndef _SYS_BPTREE_H
+#define _SYS_BPTREE_H
+
+#include <sys/spa.h>
+#include <sys/zio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct bptree_phys {
+ uint64_t bt_begin;
+ uint64_t bt_end;
+ uint64_t bt_bytes;
+ uint64_t bt_comp;
+ uint64_t bt_uncomp;
+} bptree_phys_t;
+
+typedef struct bptree_entry_phys {
+ blkptr_t be_bp;
+ uint64_t be_birth_txg; /* only delete blocks born after this txg */
+ zbookmark_t be_zb; /* holds traversal resume point if needed */
+} bptree_entry_phys_t;
+
+typedef int bptree_itor_t(void *arg, const blkptr_t *bp, dmu_tx_t *tx);
+
+uint64_t bptree_alloc(objset_t *os, dmu_tx_t *tx);
+int bptree_free(objset_t *os, uint64_t obj, dmu_tx_t *tx);
+
+void bptree_add(objset_t *os, uint64_t obj, blkptr_t *bp, uint64_t birth_txg,
+ uint64_t bytes, uint64_t comp, uint64_t uncomp, dmu_tx_t *tx);
+
+int bptree_iterate(objset_t *os, uint64_t obj, boolean_t free,
+ bptree_itor_t func, void *arg, dmu_tx_t *tx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_BPTREE_H */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h Wed Jul 25 16:45:04 2012 +0300
@@ -18,12 +18,12 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
- */
-/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
/* Portions Copyright 2010 Robert Milkowski */
@@ -74,6 +74,53 @@
typedef struct dmu_tx dmu_tx_t;
typedef struct dsl_dir dsl_dir_t;
+typedef enum dmu_object_byteswap {
+ DMU_BSWAP_UINT8,
+ DMU_BSWAP_UINT16,
+ DMU_BSWAP_UINT32,
+ DMU_BSWAP_UINT64,
+ DMU_BSWAP_ZAP,
+ DMU_BSWAP_DNODE,
+ DMU_BSWAP_OBJSET,
+ DMU_BSWAP_ZNODE,
+ DMU_BSWAP_OLDACL,
+ DMU_BSWAP_ACL,
+ /*
+ * Allocating a new byteswap type number makes the on-disk format
+ * incompatible with any other format that uses the same number.
+ *
+ * Data can usually be structured to work with one of the
+ * DMU_BSWAP_UINT* or DMU_BSWAP_ZAP types.
+ */
+ DMU_BSWAP_NUMFUNCS
+} dmu_object_byteswap_t;
+
+#define DMU_OT_NEWTYPE 0x80
+#define DMU_OT_METADATA 0x40
+#define DMU_OT_BYTESWAP_MASK 0x3f
+
+/*
+ * Defines a uint8_t object type. Object types specify if the data
+ * in the object is metadata (boolean) and how to byteswap the data
+ * (dmu_object_byteswap_t).
+ */
+#define DMU_OT(byteswap, metadata) \
+ (DMU_OT_NEWTYPE | \
+ ((metadata) ? DMU_OT_METADATA : 0) | \
+ ((byteswap) & DMU_OT_BYTESWAP_MASK))
+
+#define DMU_OT_IS_VALID(ot) (((ot) & DMU_OT_NEWTYPE) ? \
+ ((ot) & DMU_OT_BYTESWAP_MASK) < DMU_BSWAP_NUMFUNCS : \
+ (ot) < DMU_OT_NUMTYPES)
+
+#define DMU_OT_IS_METADATA(ot) (((ot) & DMU_OT_NEWTYPE) ? \
+ ((ot) & DMU_OT_METADATA) : \
+ dmu_ot[(ot)].ot_metadata)
+
+#define DMU_OT_BYTESWAP(ot) (((ot) & DMU_OT_NEWTYPE) ? \
+ ((ot) & DMU_OT_BYTESWAP_MASK) : \
+ dmu_ot[(ot)].ot_byteswap)
+
typedef enum dmu_object_type {
DMU_OT_NONE,
/* general: */
@@ -138,7 +185,35 @@
DMU_OT_DEADLIST_HDR, /* UINT64 */
DMU_OT_DSL_CLONES, /* ZAP */
DMU_OT_BPOBJ_SUBOBJ, /* UINT64 */
- DMU_OT_NUMTYPES
+ /*
+ * Do not allocate new object types here. Doing so makes the on-disk
+ * format incompatible with any other format that uses the same object
+ * type number.
+ *
+ * When creating an object which does not have one of the above types
+ * use the DMU_OTN_* type with the correct byteswap and metadata
+ * values.
+ *
+ * The DMU_OTN_* types do not have entries in the dmu_ot table,
+ * use the DMU_OT_IS_METDATA() and DMU_OT_BYTESWAP() macros instead
+ * of indexing into dmu_ot directly (this works for both DMU_OT_* types
+ * and DMU_OTN_* types).
+ */
+ DMU_OT_NUMTYPES,
+
+ /*
+ * Names for valid types declared with DMU_OT().
+ */
+ DMU_OTN_UINT8_DATA = DMU_OT(DMU_BSWAP_UINT8, B_FALSE),
+ DMU_OTN_UINT8_METADATA = DMU_OT(DMU_BSWAP_UINT8, B_TRUE),
+ DMU_OTN_UINT16_DATA = DMU_OT(DMU_BSWAP_UINT16, B_FALSE),
+ DMU_OTN_UINT16_METADATA = DMU_OT(DMU_BSWAP_UINT16, B_TRUE),
+ DMU_OTN_UINT32_DATA = DMU_OT(DMU_BSWAP_UINT32, B_FALSE),
+ DMU_OTN_UINT32_METADATA = DMU_OT(DMU_BSWAP_UINT32, B_TRUE),
+ DMU_OTN_UINT64_DATA = DMU_OT(DMU_BSWAP_UINT64, B_FALSE),
+ DMU_OTN_UINT64_METADATA = DMU_OT(DMU_BSWAP_UINT64, B_TRUE),
+ DMU_OTN_ZAP_DATA = DMU_OT(DMU_BSWAP_ZAP, B_FALSE),
+ DMU_OTN_ZAP_METADATA = DMU_OT(DMU_BSWAP_ZAP, B_TRUE),
} dmu_object_type_t;
typedef enum dmu_objset_type {
@@ -220,6 +295,9 @@
*/
#define DMU_POOL_DIRECTORY_OBJECT 1
#define DMU_POOL_CONFIG "config"
+#define DMU_POOL_FEATURES_FOR_WRITE "features_for_write"
+#define DMU_POOL_FEATURES_FOR_READ "features_for_read"
+#define DMU_POOL_FEATURE_DESCRIPTIONS "feature_descriptions"
#define DMU_POOL_ROOT_DATASET "root_dataset"
#define DMU_POOL_SYNC_BPOBJ "sync_bplist"
#define DMU_POOL_ERRLOG_SCRUB "errlog_scrub"
@@ -235,6 +313,7 @@
#define DMU_POOL_CREATION_VERSION "creation_version"
#define DMU_POOL_SCAN "scan"
#define DMU_POOL_FREE_BPOBJ "free_bpobj"
+#define DMU_POOL_BPTREE_OBJ "bptree_obj"
/*
* Allocate an object from this objset. The range of object numbers
@@ -495,7 +574,7 @@
/*
* Free up the data blocks for a defined range of a file. If size is
- * zero, the range from offset to end-of-file is freed.
+ * -1, the range from offset to end-of-file is freed.
*/
int dmu_free_range(objset_t *os, uint64_t object, uint64_t offset,
uint64_t size, dmu_tx_t *tx);
@@ -565,12 +644,18 @@
typedef void arc_byteswap_func_t(void *buf, size_t size);
typedef struct dmu_object_type_info {
- arc_byteswap_func_t *ot_byteswap;
+ dmu_object_byteswap_t ot_byteswap;
boolean_t ot_metadata;
char *ot_name;
} dmu_object_type_info_t;
+typedef struct dmu_object_byteswap_info {
+ arc_byteswap_func_t *ob_func;
+ char *ob_name;
+} dmu_object_byteswap_info_t;
+
extern const dmu_object_type_info_t dmu_ot[DMU_OT_NUMTYPES];
+extern const dmu_object_byteswap_info_t dmu_ot_byteswap[DMU_BSWAP_NUMFUNCS];
/*
* Get information on a DMU object.
@@ -706,8 +791,8 @@
void dmu_traverse_objset(objset_t *os, uint64_t txg_start,
dmu_traverse_cb_t cb, void *arg);
-int dmu_sendbackup(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
- struct file *fp, offset_t *off);
+int dmu_send(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
+ int outfd, struct file *fp, offset_t *off);
int dmu_send_estimate(objset_t *tosnap, objset_t *fromsnap,
boolean_t fromorigin, uint64_t *sizep);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_impl.h
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_impl.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_impl.h Wed Jul 25 16:45:04 2012 +0300
@@ -21,6 +21,8 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2012, Martin Matuska <mm at FreeBSD.org>. All rights reserved.
*/
#ifndef _SYS_DMU_IMPL_H
@@ -31,6 +33,7 @@
#include <sys/dnode.h>
#include <sys/kstat.h>
#include <sys/zfs_context.h>
+#include <sys/zfs_ioctl.h>
#ifdef __cplusplus
extern "C" {
@@ -265,6 +268,33 @@
atomic_add_64(&xuio_stats.stat.value.ui64, (val))
#define XUIOSTAT_BUMP(stat) XUIOSTAT_INCR(stat, 1)
+/*
+ * The list of data whose inclusion in a send stream can be pending from
+ * one call to backup_cb to another. Multiple calls to dump_free() and
+ * dump_freeobjects() can be aggregated into a single DRR_FREE or
+ * DRR_FREEOBJECTS replay record.
+ */
+typedef enum {
+ PENDING_NONE,
+ PENDING_FREE,
+ PENDING_FREEOBJECTS
+} dmu_pendop_t;
+
+typedef struct dmu_sendarg {
+ list_node_t dsa_link;
+ dmu_replay_record_t *dsa_drr;
+ kthread_t *dsa_td;
+ struct file *dsa_fp;
+ int dsa_outfd;
+ struct proc *dsa_proc;
+ offset_t *dsa_off;
+ objset_t *dsa_os;
+ zio_cksum_t dsa_zc;
+ uint64_t dsa_toguid;
+ int dsa_err;
+ dmu_pendop_t dsa_pending_op;
+} dmu_sendarg_t;
+
#ifdef __cplusplus
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_traverse.h
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_traverse.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_traverse.h Wed Jul 25 16:45:04 2012 +0300
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#ifndef _SYS_DMU_TRAVERSE_H
@@ -54,6 +55,9 @@
int traverse_dataset(struct dsl_dataset *ds,
uint64_t txg_start, int flags, blkptr_cb_t func, void *arg);
+int traverse_dataset_destroyed(spa_t *spa, blkptr_t *blkptr,
+ uint64_t txg_start, zbookmark_t *resume, int flags,
+ blkptr_cb_t func, void *arg);
int traverse_pool(spa_t *spa,
uint64_t txg_start, int flags, blkptr_cb_t func, void *arg);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h Wed Jul 25 16:45:04 2012 +0300
@@ -22,7 +22,8 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel at dawidek.net>.
* All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _SYS_DSL_DATASET_H
@@ -87,7 +88,12 @@
uint64_t ds_creation_time; /* seconds since 1970 */
uint64_t ds_creation_txg;
uint64_t ds_deadlist_obj; /* DMU_OT_DEADLIST */
- uint64_t ds_used_bytes;
+ /*
+ * ds_referenced_bytes, ds_compressed_bytes, and ds_uncompressed_bytes
+ * include all blocks referenced by this dataset, including those
+ * shared with any other datasets.
+ */
+ uint64_t ds_referenced_bytes;
uint64_t ds_compressed_bytes;
uint64_t ds_uncompressed_bytes;
uint64_t ds_unique_bytes; /* only relevant to snapshots */
@@ -152,6 +158,9 @@
uint64_t ds_reserved; /* cached refreservation */
uint64_t ds_quota; /* cached refquota */
+ kmutex_t ds_sendstream_lock;
+ list_t ds_sendstreams;
+
/* Protected by ds_lock; keep at end of struct for better locality */
char ds_snapname[MAXNAMELEN];
} dsl_dataset_t;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h Wed Jul 25 16:45:04 2012 +0300
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#ifndef _SYS_DSL_POOL_H
@@ -34,6 +35,7 @@
#include <sys/ddt.h>
#include <sys/arc.h>
#include <sys/bpobj.h>
+#include <sys/bptree.h>
#ifdef __cplusplus
extern "C" {
@@ -48,7 +50,8 @@
/* These macros are for indexing into the zfs_all_blkstats_t. */
#define DMU_OT_DEFERRED DMU_OT_NONE
-#define DMU_OT_TOTAL DMU_OT_NUMTYPES
+#define DMU_OT_OTHER DMU_OT_NUMTYPES /* place holder for DMU_OT() types */
+#define DMU_OT_TOTAL (DMU_OT_NUMTYPES + 1)
typedef struct zfs_blkstat {
uint64_t zb_count;
@@ -85,6 +88,7 @@
uint64_t dp_write_limit;
uint64_t dp_tmp_userrefs_obj;
bpobj_t dp_free_bpobj;
+ uint64_t dp_bptree_obj;
struct dsl_scan *dp_scan;
@@ -110,7 +114,8 @@
zfs_all_blkstats_t *dp_blkstats;
} dsl_pool_t;
-int dsl_pool_open(spa_t *spa, uint64_t txg, dsl_pool_t **dpp);
+int dsl_pool_init(spa_t *spa, uint64_t txg, dsl_pool_t **dpp);
+int dsl_pool_open(dsl_pool_t *dp);
void dsl_pool_close(dsl_pool_t *dp);
dsl_pool_t *dsl_pool_create(spa_t *spa, nvlist_t *zplprops, uint64_t txg);
void dsl_pool_sync(dsl_pool_t *dp, uint64_t txg);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_scan.h
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_scan.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_scan.h Wed Jul 25 16:45:04 2012 +0300
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#ifndef _SYS_DSL_SCAN_H
@@ -79,6 +80,9 @@
uint64_t scn_sync_start_time;
zio_t *scn_zio_root;
+ /* for freeing blocks */
+ boolean_t scn_is_bptree;
+
/* for debugging / information */
uint64_t scn_visited_this_txg;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h Wed Jul 25 16:45:04 2012 +0300
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
@@ -94,7 +94,7 @@
/*
* Size of block to hold the configuration data (a packed nvlist)
*/
-#define SPA_CONFIG_BLOCKSIZE (1 << 14)
+#define SPA_CONFIG_BLOCKSIZE (1ULL << 14)
/*
* The DVA size encodings for LSIZE and PSIZE support blocks up to 32MB.
@@ -262,7 +262,7 @@
DVA_GET_ASIZE(&(bp)->blk_dva[2]))
#define BP_GET_UCSIZE(bp) \
- ((BP_GET_LEVEL(bp) > 0 || dmu_ot[BP_GET_TYPE(bp)].ot_metadata) ? \
+ ((BP_GET_LEVEL(bp) > 0 || DMU_OT_IS_METADATA(BP_GET_TYPE(bp))) ? \
BP_GET_PSIZE(bp) : BP_GET_LSIZE(bp))
#define BP_GET_NDVAS(bp) \
@@ -403,8 +403,8 @@
#include <sys/dmu.h>
#define BP_GET_BUFC_TYPE(bp) \
- (((BP_GET_LEVEL(bp) > 0) || (dmu_ot[BP_GET_TYPE(bp)].ot_metadata)) ? \
- ARC_BUFC_METADATA : ARC_BUFC_DATA);
+ (((BP_GET_LEVEL(bp) > 0) || (DMU_OT_IS_METADATA(BP_GET_TYPE(bp)))) ? \
+ ARC_BUFC_METADATA : ARC_BUFC_DATA)
typedef enum spa_import_type {
SPA_IMPORT_EXISTING,
@@ -415,8 +415,8 @@
extern int spa_open(const char *pool, spa_t **, void *tag);
extern int spa_open_rewind(const char *pool, spa_t **, void *tag,
nvlist_t *policy, nvlist_t **config);
-extern int spa_get_stats(const char *pool, nvlist_t **config,
- char *altroot, size_t buflen);
+extern int spa_get_stats(const char *pool, nvlist_t **config, char *altroot,
+ size_t buflen);
extern int spa_create(const char *pool, nvlist_t *config, nvlist_t *props,
const char *history_str, nvlist_t *zplprops);
extern int spa_import_rootpool(char *devpath, char *devid);
@@ -573,6 +573,7 @@
/* Accessor functions */
extern boolean_t spa_shutting_down(spa_t *spa);
extern struct dsl_pool *spa_get_dsl(spa_t *spa);
+extern boolean_t spa_is_initializing(spa_t *spa);
extern blkptr_t *spa_get_rootblkptr(spa_t *spa);
extern void spa_set_rootblkptr(spa_t *spa, const blkptr_t *bp);
extern void spa_altroot(spa_t *, char *, size_t);
@@ -604,6 +605,8 @@
extern objset_t *spa_meta_objset(spa_t *spa);
/* Miscellaneous support routines */
+extern void spa_activate_mos_feature(spa_t *spa, const char *feature);
+extern void spa_deactivate_mos_feature(spa_t *spa, const char *feature);
extern int spa_rename(const char *oldname, const char *newname);
extern spa_t *spa_by_guid(uint64_t pool_guid, uint64_t device_guid);
extern boolean_t spa_guid_exists(uint64_t pool_guid, uint64_t device_guid);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h Wed Jul 25 16:45:04 2012 +0300
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
@@ -127,6 +127,7 @@
uint64_t spa_import_flags; /* import specific flags */
taskq_t *spa_zio_taskq[ZIO_TYPES][ZIO_TASKQ_TYPES];
dsl_pool_t *spa_dsl_pool;
+ boolean_t spa_is_initializing; /* true while opening pool */
metaslab_class_t *spa_normal_class; /* normal data class */
metaslab_class_t *spa_log_class; /* intent log data class */
uint64_t spa_first_txg; /* first txg after spa_open() */
@@ -144,6 +145,7 @@
list_t spa_state_dirty_list; /* vdevs with dirty state */
spa_aux_vdev_t spa_spares; /* hot spares */
spa_aux_vdev_t spa_l2cache; /* L2ARC cache devices */
+ nvlist_t *spa_label_features; /* Features for reading MOS */
uint64_t spa_config_object; /* MOS object for pool config */
uint64_t spa_config_generation; /* config generation number */
uint64_t spa_syncing_txg; /* txg currently syncing */
@@ -220,7 +222,10 @@
boolean_t spa_autoreplace; /* autoreplace set in open */
int spa_vdev_locks; /* locks grabbed */
uint64_t spa_creation_version; /* version at pool creation */
- uint64_t spa_prev_software_version;
+ uint64_t spa_prev_software_version; /* See ub_software_version */
+ uint64_t spa_feat_for_write_obj; /* required to write to pool */
+ uint64_t spa_feat_for_read_obj; /* required to read from pool */
+ uint64_t spa_feat_desc_obj; /* Feature descriptions */
/*
* spa_refcnt & spa_config_lock must be the last elements
* because refcount_t changes size based on compilation options.
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h Wed Jul 25 16:45:04 2012 +0300
@@ -18,6 +18,7 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
@@ -141,8 +142,8 @@
struct uberblock;
extern uint64_t vdev_label_offset(uint64_t psize, int l, uint64_t offset);
extern int vdev_label_number(uint64_t psise, uint64_t offset);
-extern nvlist_t *vdev_label_read_config(vdev_t *vd);
-extern void vdev_uberblock_load(zio_t *zio, vdev_t *vd, struct uberblock *ub);
+extern nvlist_t *vdev_label_read_config(vdev_t *vd, int label);
+extern void vdev_uberblock_load(vdev_t *, struct uberblock *, nvlist_t **);
typedef enum {
VDEV_LABEL_CREATE, /* create/add a new device */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h Wed Jul 25 16:45:04 2012 +0300
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#ifndef _SYS_VDEV_IMPL_H
@@ -55,7 +56,8 @@
/*
* Virtual device operations
*/
-typedef int vdev_open_func_t(vdev_t *vd, uint64_t *size, uint64_t *ashift);
+typedef int vdev_open_func_t(vdev_t *vd, uint64_t *size, uint64_t *max_size,
+ uint64_t *ashift);
typedef void vdev_close_func_t(vdev_t *vd);
typedef uint64_t vdev_asize_func_t(vdev_t *vd, uint64_t psize);
typedef int vdev_io_start_func_t(zio_t *zio);
@@ -118,6 +120,7 @@
uint64_t vdev_orig_guid; /* orig. guid prior to remove */
uint64_t vdev_asize; /* allocatable device capacity */
uint64_t vdev_min_asize; /* min acceptable asize */
+ uint64_t vdev_max_asize; /* max acceptable asize */
uint64_t vdev_ashift; /* block alignment shift */
uint64_t vdev_state; /* see VDEV_STATE_* #defines */
uint64_t vdev_prevstate; /* used when reopening a vdev */
@@ -199,7 +202,7 @@
* For DTrace to work in userland (libzpool) context, these fields must
* remain at the end of the structure. DTrace will use the kernel's
* CTF definition for 'struct vdev', and since the size of a kmutex_t is
- * larger in userland, the offsets for the rest fields would be
+ * larger in userland, the offsets for the rest of the fields would be
* incorrect.
*/
kmutex_t vdev_dtl_lock; /* vdev_dtl_{map,resilver} */
@@ -254,6 +257,7 @@
#define VDEV_LABEL_START_SIZE (2 * sizeof (vdev_label_t) + VDEV_BOOT_SIZE)
#define VDEV_LABEL_END_SIZE (2 * sizeof (vdev_label_t))
#define VDEV_LABELS 4
+#define VDEV_BEST_LABEL VDEV_LABELS
#define VDEV_ALLOC_LOAD 0
#define VDEV_ALLOC_ADD 1
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap.h
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap.h Wed Jul 25 16:45:04 2012 +0300
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#ifndef _SYS_ZAP_H
@@ -132,6 +133,8 @@
uint64_t zap_create_flags(objset_t *os, int normflags, zap_flags_t flags,
dmu_object_type_t ot, int leaf_blockshift, int indirect_blockshift,
dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx);
+uint64_t zap_create_link(objset_t *os, dmu_object_type_t ot,
+ uint64_t parent_obj, const char *name, dmu_tx_t *tx);
/*
* Create a new zapobj with no attributes from the given (unallocated)
@@ -300,12 +303,6 @@
int zap_lookup_int_key(objset_t *os, uint64_t obj,
uint64_t key, uint64_t *valuep);
-/*
- * They name is a stringified version of key; increment its value by
- * delta. Zero values will be zap_remove()-ed.
- */
-int zap_increment_int(objset_t *os, uint64_t obj, uint64_t key, int64_t delta,
- dmu_tx_t *tx);
int zap_increment(objset_t *os, uint64_t obj, const char *name, int64_t delta,
dmu_tx_t *tx);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfeature.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfeature.h Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#ifndef _SYS_ZFEATURE_H
+#define _SYS_ZFEATURE_H
+
+#include <sys/dmu.h>
+#include <sys/nvpair.h>
+#include "zfeature_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern boolean_t feature_is_supported(objset_t *os, uint64_t obj,
+ uint64_t desc_obj, nvlist_t *unsup_feat);
+
+struct spa;
+extern void spa_feature_create_zap_objects(struct spa *, dmu_tx_t *);
+extern void spa_feature_enable(struct spa *, zfeature_info_t *, dmu_tx_t *);
+extern void spa_feature_incr(struct spa *, zfeature_info_t *, dmu_tx_t *);
+extern void spa_feature_decr(struct spa *, zfeature_info_t *, dmu_tx_t *);
+extern boolean_t spa_feature_is_enabled(struct spa *, zfeature_info_t *);
+extern boolean_t spa_feature_is_active(struct spa *, zfeature_info_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_ZFEATURE_H */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h Wed Jul 25 16:45:04 2012 +0300
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#ifndef _ZIO_H
@@ -270,6 +271,14 @@
#define ZB_ZIL_OBJECT (0ULL)
#define ZB_ZIL_LEVEL (-2LL)
+#define ZB_IS_ZERO(zb) \
+ ((zb)->zb_objset == 0 && (zb)->zb_object == 0 && \
+ (zb)->zb_level == 0 && (zb)->zb_blkid == 0)
+#define ZB_IS_ROOT(zb) \
+ ((zb)->zb_object == ZB_ROOT_OBJECT && \
+ (zb)->zb_level == ZB_ROOT_LEVEL && \
+ (zb)->zb_blkid == ZB_ROOT_BLKID)
+
typedef struct zio_prop {
enum zio_checksum zp_checksum;
enum zio_compress zp_compress;
@@ -287,6 +296,7 @@
typedef void zio_cksum_free_f(void *cbdata, size_t size);
struct zio_bad_cksum; /* defined in zio_checksum.h */
+struct dnode_phys;
struct zio_cksum_report {
struct zio_cksum_report *zcr_next;
@@ -559,6 +569,10 @@
/* Called from spa_sync(), but primarily an injection handler */
extern void spa_handle_ignored_writes(spa_t *spa);
+/* zbookmark functions */
+boolean_t zbookmark_is_before(const struct dnode_phys *dnp,
+ const zbookmark_t *zb1, const zbookmark_t *zb2);
+
#ifdef __cplusplus
}
#endif
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio_impl.h
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio_impl.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio_impl.h Wed Jul 25 16:45:04 2012 +0300
@@ -61,7 +61,7 @@
ZIO_STAGE_READY = 1 << 15, /* RWFCI */
ZIO_STAGE_VDEV_IO_START = 1 << 16, /* RW--I */
- ZIO_STAGE_VDEV_IO_DONE = 1 << 17, /* RW--I */
+ ZIO_STAGE_VDEV_IO_DONE = 1 << 17, /* RW--- */
ZIO_STAGE_VDEV_IO_ASSESS = 1 << 18, /* RW--I */
ZIO_STAGE_CHECKSUM_VERIFY = 1 << 19, /* R---- */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c Wed Jul 25 16:45:04 2012 +0300
@@ -22,7 +22,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@@ -67,12 +67,6 @@
NULL
};
-/* maximum scrub/resilver I/O queue per leaf vdev */
-int zfs_scrub_limit = 10;
-
-TUNABLE_INT("vfs.zfs.scrub_limit", &zfs_scrub_limit);
-SYSCTL_INT(_vfs_zfs, OID_AUTO, scrub_limit, CTLFLAG_RDTUN, &zfs_scrub_limit, 0,
- "Maximum scrub/resilver I/O queue");
/*
* Given a vdev type, return the appropriate ops vector.
@@ -119,7 +113,7 @@
vdev_t *pvd = vd->vdev_parent;
/*
- * The our parent is NULL (inactive spare or cache) or is the root,
+ * If our parent is NULL (inactive spare or cache) or is the root,
* just return our own asize.
*/
if (pvd == NULL)
@@ -748,6 +742,7 @@
mvd->vdev_asize = cvd->vdev_asize;
mvd->vdev_min_asize = cvd->vdev_min_asize;
+ mvd->vdev_max_asize = cvd->vdev_max_asize;
mvd->vdev_ashift = cvd->vdev_ashift;
mvd->vdev_state = cvd->vdev_state;
mvd->vdev_crtxg = cvd->vdev_crtxg;
@@ -1119,7 +1114,8 @@
spa_t *spa = vd->vdev_spa;
int error;
uint64_t osize = 0;
- uint64_t asize, psize;
+ uint64_t max_osize = 0;
+ uint64_t asize, max_asize, psize;
uint64_t ashift = 0;
ASSERT(vd->vdev_open_thread == curthread ||
@@ -1150,7 +1146,7 @@
return (ENXIO);
}
- error = vd->vdev_ops->vdev_op_open(vd, &osize, &ashift);
+ error = vd->vdev_ops->vdev_op_open(vd, &osize, &max_osize, &ashift);
/*
* Reset the vdev_reopening flag so that we actually close
@@ -1208,6 +1204,7 @@
}
osize = P2ALIGN(osize, (uint64_t)sizeof (vdev_label_t));
+ max_osize = P2ALIGN(max_osize, (uint64_t)sizeof (vdev_label_t));
if (vd->vdev_children == 0) {
if (osize < SPA_MINDEVSIZE) {
@@ -1217,6 +1214,8 @@
}
psize = osize;
asize = osize - (VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE);
+ max_asize = max_osize - (VDEV_LABEL_START_SIZE +
+ VDEV_LABEL_END_SIZE);
} else {
if (vd->vdev_parent != NULL && osize < SPA_MINDEVSIZE -
(VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE)) {
@@ -1226,6 +1225,7 @@
}
psize = 0;
asize = osize;
+ max_asize = max_osize;
}
vd->vdev_psize = psize;
@@ -1245,6 +1245,7 @@
* For testing purposes, a higher ashift can be requested.
*/
vd->vdev_asize = asize;
+ vd->vdev_max_asize = max_asize;
vd->vdev_ashift = MAX(ashift, vd->vdev_ashift);
} else {
/*
@@ -1255,6 +1256,7 @@
VDEV_AUX_BAD_LABEL);
return (EINVAL);
}
+ vd->vdev_max_asize = max_asize;
}
/*
@@ -1327,7 +1329,8 @@
uint64_t aux_guid = 0;
nvlist_t *nvl;
- if ((label = vdev_label_read_config(vd)) == NULL) {
+ if ((label = vdev_label_read_config(vd, VDEV_BEST_LABEL)) ==
+ NULL) {
vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
VDEV_AUX_BAD_LABEL);
return (0);
@@ -1968,14 +1971,14 @@
if (!vdev_readable(vd))
return (0);
- if ((label = vdev_label_read_config(vd)) == NULL) {
+ if ((label = vdev_label_read_config(vd, VDEV_BEST_LABEL)) == NULL) {
vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
VDEV_AUX_CORRUPT_DATA);
return (-1);
}
if (nvlist_lookup_uint64(label, ZPOOL_CONFIG_VERSION, &version) != 0 ||
- version > SPA_VERSION ||
+ !SPA_VERSION_IS_SUPPORTED(version) ||
nvlist_lookup_uint64(label, ZPOOL_CONFIG_GUID, &guid) != 0 ||
guid != vd->vdev_guid ||
nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_STATE, &state) != 0) {
@@ -2478,6 +2481,7 @@
vs->vs_rsize = vdev_get_min_asize(vd);
if (vd->vdev_ops->vdev_op_leaf)
vs->vs_rsize += VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE;
+ vs->vs_esize = vd->vdev_max_asize - vd->vdev_asize;
mutex_exit(&vd->vdev_stat_lock);
/*
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c Wed Jul 25 16:45:04 2012 +0300
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@@ -30,6 +31,7 @@
#include <sys/fs/zfs.h>
#include <sys/zio.h>
#include <sys/sunldi.h>
+#include <sys/efi_partition.h>
#include <sys/fm/fs/zfs.h>
/*
@@ -102,8 +104,39 @@
}
}
+static uint64_t
+vdev_disk_get_space(vdev_t *vd, uint64_t capacity, uint_t blksz)
+{
+ ASSERT(vd->vdev_wholedisk);
+
+ vdev_disk_t *dvd = vd->vdev_tsd;
+ dk_efi_t dk_ioc;
+ efi_gpt_t *efi;
+ uint64_t avail_space = 0;
+ int efisize = EFI_LABEL_SIZE * 2;
+
+ dk_ioc.dki_data = kmem_alloc(efisize, KM_SLEEP);
+ dk_ioc.dki_lba = 1;
+ dk_ioc.dki_length = efisize;
+ dk_ioc.dki_data_64 = (uint64_t)(uintptr_t)dk_ioc.dki_data;
+ efi = dk_ioc.dki_data;
+
+ if (ldi_ioctl(dvd->vd_lh, DKIOCGETEFI, (intptr_t)&dk_ioc,
+ FKIOCTL, kcred, NULL) == 0) {
+ uint64_t efi_altern_lba = LE_64(efi->efi_gpt_AlternateLBA);
+
+ zfs_dbgmsg("vdev %s, capacity %llu, altern lba %llu",
+ vd->vdev_path, capacity, efi_altern_lba);
+ if (capacity > efi_altern_lba)
+ avail_space = (capacity - efi_altern_lba) * blksz;
+ }
+ kmem_free(dk_ioc.dki_data, efisize);
+ return (avail_space);
+}
+
static int
-vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift)
+vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
+ uint64_t *ashift)
{
spa_t *spa = vd->vdev_spa;
vdev_disk_t *dvd;
@@ -274,16 +307,6 @@
}
/*
- * If we own the whole disk, try to enable disk write caching.
- * We ignore errors because it's OK if we can't do it.
- */
- if (vd->vdev_wholedisk == 1) {
- int wce = 1;
- (void) ldi_ioctl(dvd->vd_lh, DKIOCSETWCE, (intptr_t)&wce,
- FKIOCTL, kcred, NULL);
- }
-
- /*
* Determine the device's minimum transfer size.
* If the ioctl isn't supported, assume DEV_BSIZE.
*/
@@ -293,6 +316,25 @@
*ashift = highbit(MAX(dkmext.dki_pbsize, SPA_MINBLOCKSIZE)) - 1;
+ if (vd->vdev_wholedisk == 1) {
+ uint64_t capacity = dkmext.dki_capacity - 1;
+ uint64_t blksz = dkmext.dki_lbsize;
+ int wce = 1;
+
+ /*
+ * If we own the whole disk, try to enable disk write caching.
+ * We ignore errors because it's OK if we can't do it.
+ */
+ (void) ldi_ioctl(dvd->vd_lh, DKIOCSETWCE, (intptr_t)&wce,
+ FKIOCTL, kcred, NULL);
+
+ *max_psize = *psize + vdev_disk_get_space(vd, capacity, blksz);
+ zfs_dbgmsg("capacity change: vdev %s, psize %llu, "
+ "max_psize %llu", vd->vdev_path, *psize, *max_psize);
+ } else {
+ *max_psize = *psize;
+ }
+
/*
* Clear the nowritecache bit, so that on a vdev_reopen() we will
* try again.
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c Wed Jul 25 16:45:04 2012 +0300
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@@ -47,7 +48,8 @@
}
static int
-vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift)
+vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
+ uint64_t *ashift)
{
vdev_file_t *vf;
vnode_t *vp;
@@ -125,7 +127,7 @@
return (error);
}
- *psize = vattr.va_size;
+ *max_psize = *psize = vattr.va_size;
*ashift = SPA_MINBLOCKSHIFT;
return (0);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c Wed Jul 25 16:45:04 2012 +0300
@@ -21,6 +21,8 @@
/*
* Copyright (c) 2006 Pawel Jakub Dawidek <pjd at FreeBSD.org>
* All rights reserved.
+ *
+ * Portions Copyright (c) 2012 Martin Matuska <mm at FreeBSD.org>
*/
#include <sys/zfs_context.h>
@@ -405,7 +407,8 @@
}
static int
-vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift)
+vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
+ uint64_t *ashift)
{
struct g_provider *pp;
struct g_consumer *cp;
@@ -488,7 +491,7 @@
/*
* Determine the actual size of the device.
*/
- *psize = pp->mediasize;
+ *max_psize = *psize = pp->mediasize;
/*
* Determine the device's minimum transfer size.
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c Wed Jul 25 16:45:04 2012 +0300
@@ -18,8 +18,10 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
/*
@@ -121,6 +123,8 @@
* txg Transaction group in which this label was written
* pool_guid Unique identifier for this pool
* vdev_tree An nvlist describing vdev tree.
+ * features_for_read
+ * An nvlist of the features necessary for reading the MOS.
*
* Each leaf device label also contains the following:
*
@@ -428,8 +432,13 @@
kmem_free(array, rvd->vdev_children * sizeof (uint64_t));
}
+/*
+ * Returns the configuration from the label of the given vdev. If 'label' is
+ * VDEV_BEST_LABEL, each label of the vdev will be read until a valid
+ * configuration is found; otherwise, only the specified label will be read.
+ */
nvlist_t *
-vdev_label_read_config(vdev_t *vd)
+vdev_label_read_config(vdev_t *vd, int label)
{
spa_t *spa = vd->vdev_spa;
nvlist_t *config = NULL;
@@ -447,6 +456,8 @@
retry:
for (int l = 0; l < VDEV_LABELS; l++) {
+ if (label >= 0 && label < VDEV_LABELS && label != l)
+ continue;
zio = zio_root(spa, NULL, NULL, flags);
@@ -496,7 +507,7 @@
/*
* Read the label, if any, and perform some basic sanity checks.
*/
- if ((label = vdev_label_read_config(vd)) == NULL)
+ if ((label = vdev_label_read_config(vd, VDEV_BEST_LABEL)) == NULL)
return (B_FALSE);
(void) nvlist_lookup_uint64(label, ZPOOL_CONFIG_CREATE_TXG,
@@ -833,7 +844,7 @@
* come back up, we fail to see the uberblock for txg + 1 because, say,
* it was on a mirrored device and the replica to which we wrote txg + 1
* is now offline. If we then make some changes and sync txg + 1, and then
- * the missing replica comes back, then for a new seconds we'll have two
+ * the missing replica comes back, then for a few seconds we'll have two
* conflicting uberblocks on disk with the same txg. The solution is simple:
* among uberblocks with equal txg, choose the one with the latest timestamp.
*/
@@ -853,46 +864,50 @@
return (0);
}
+struct ubl_cbdata {
+ uberblock_t *ubl_ubbest; /* Best uberblock */
+ vdev_t *ubl_vd; /* vdev associated with the above */
+ int ubl_label; /* Label associated with the above */
+};
+
static void
vdev_uberblock_load_done(zio_t *zio)
{
+ vdev_t *vd = zio->io_vd;
spa_t *spa = zio->io_spa;
zio_t *rio = zio->io_private;
uberblock_t *ub = zio->io_data;
- uberblock_t *ubbest = rio->io_private;
+ struct ubl_cbdata *cbp = rio->io_private;
- ASSERT3U(zio->io_size, ==, VDEV_UBERBLOCK_SIZE(zio->io_vd));
+ ASSERT3U(zio->io_size, ==, VDEV_UBERBLOCK_SIZE(vd));
if (zio->io_error == 0 && uberblock_verify(ub) == 0) {
mutex_enter(&rio->io_lock);
if (ub->ub_txg <= spa->spa_load_max_txg &&
- vdev_uberblock_compare(ub, ubbest) > 0)
- *ubbest = *ub;
+ vdev_uberblock_compare(ub, cbp->ubl_ubbest) > 0) {
+ /*
+ * Keep track of the vdev and label in which this
+ * uberblock was found. We will use this information
+ * later to obtain the config nvlist associated with
+ * this uberblock.
+ */
+ *cbp->ubl_ubbest = *ub;
+ cbp->ubl_vd = vd;
+ cbp->ubl_label = vdev_label_number(vd->vdev_psize,
+ zio->io_offset);
+ }
mutex_exit(&rio->io_lock);
}
zio_buf_free(zio->io_data, zio->io_size);
}
-void
-vdev_uberblock_load(zio_t *zio, vdev_t *vd, uberblock_t *ubbest)
+static void
+vdev_uberblock_load_impl(zio_t *zio, vdev_t *vd, int flags,
+ struct ubl_cbdata *cbp)
{
- spa_t *spa = vd->vdev_spa;
- vdev_t *rvd = spa->spa_root_vdev;
- int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL |
- ZIO_FLAG_SPECULATIVE | ZIO_FLAG_TRYHARD;
-
- if (vd == rvd) {
- ASSERT(zio == NULL);
- spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
- zio = zio_root(spa, NULL, ubbest, flags);
- bzero(ubbest, sizeof (uberblock_t));
- }
-
- ASSERT(zio != NULL);
-
for (int c = 0; c < vd->vdev_children; c++)
- vdev_uberblock_load(zio, vd->vdev_child[c], ubbest);
+ vdev_uberblock_load_impl(zio, vd->vdev_child[c], flags, cbp);
if (vd->vdev_ops->vdev_op_leaf && vdev_readable(vd)) {
for (int l = 0; l < VDEV_LABELS; l++) {
@@ -905,11 +920,45 @@
}
}
}
+}
- if (vd == rvd) {
- (void) zio_wait(zio);
- spa_config_exit(spa, SCL_ALL, FTAG);
+/*
+ * Reads the 'best' uberblock from disk along with its associated
+ * configuration. First, we read the uberblock array of each label of each
+ * vdev, keeping track of the uberblock with the highest txg in each array.
+ * Then, we read the configuration from the same label as the best uberblock.
+ */
+void
+vdev_uberblock_load(vdev_t *rvd, uberblock_t *ub, nvlist_t **config)
+{
+ int i;
+ zio_t *zio;
+ spa_t *spa = rvd->vdev_spa;
+ struct ubl_cbdata cb;
+ int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL |
+ ZIO_FLAG_SPECULATIVE | ZIO_FLAG_TRYHARD;
+
+ ASSERT(ub);
+ ASSERT(config);
+
+ bzero(ub, sizeof (uberblock_t));
+ *config = NULL;
+
+ cb.ubl_ubbest = ub;
+ cb.ubl_vd = NULL;
+
+ spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+ zio = zio_root(spa, NULL, &cb, flags);
+ vdev_uberblock_load_impl(zio, rvd, flags, &cb);
+ (void) zio_wait(zio);
+ if (cb.ubl_vd != NULL) {
+ for (i = cb.ubl_label % 2; i < VDEV_LABELS; i += 2) {
+ *config = vdev_label_read_config(cb.ubl_vd, i);
+ if (*config != NULL)
+ break;
+ }
}
+ spa_config_exit(spa, SCL_ALL, FTAG);
}
/*
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c Wed Jul 25 16:45:04 2012 +0300
@@ -23,6 +23,10 @@
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
#include <sys/zfs_context.h>
#include <sys/spa.h>
#include <sys/vdev_impl.h>
@@ -127,7 +131,8 @@
}
static int
-vdev_mirror_open(vdev_t *vd, uint64_t *asize, uint64_t *ashift)
+vdev_mirror_open(vdev_t *vd, uint64_t *asize, uint64_t *max_asize,
+ uint64_t *ashift)
{
int numerrors = 0;
int lasterror = 0;
@@ -149,6 +154,7 @@
}
*asize = MIN(*asize - 1, cvd->vdev_asize - 1) + 1;
+ *max_asize = MIN(*max_asize - 1, cvd->vdev_max_asize - 1) + 1;
*ashift = MAX(*ashift, cvd->vdev_ashift);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c Wed Jul 25 16:45:04 2012 +0300
@@ -24,6 +24,10 @@
*/
/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
* The 'missing' vdev is a special vdev type used only during import. It
* signifies a placeholder in the root vdev for some vdev that we know is
* missing. We pass it down to the kernel to allow the rest of the
@@ -40,7 +44,8 @@
/* ARGSUSED */
static int
-vdev_missing_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift)
+vdev_missing_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
+ uint64_t *ashift)
{
/*
* Really this should just fail. But then the root vdev will be in the
@@ -49,6 +54,7 @@
* will fail the GUID sum check before ever trying to open the pool.
*/
*psize = 0;
+ *max_psize = 0;
*ashift = 0;
return (0);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c Wed Jul 25 16:45:04 2012 +0300
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@@ -1441,7 +1442,8 @@
}
static int
-vdev_raidz_open(vdev_t *vd, uint64_t *asize, uint64_t *ashift)
+vdev_raidz_open(vdev_t *vd, uint64_t *asize, uint64_t *max_asize,
+ uint64_t *ashift)
{
vdev_t *cvd;
uint64_t nparity = vd->vdev_nparity;
@@ -1469,10 +1471,12 @@
}
*asize = MIN(*asize - 1, cvd->vdev_asize - 1) + 1;
+ *max_asize = MIN(*max_asize - 1, cvd->vdev_max_asize - 1) + 1;
*ashift = MAX(*ashift, cvd->vdev_ashift);
}
*asize *= vd->vdev_children;
+ *max_asize *= vd->vdev_children;
if (numerrors > nparity) {
vd->vdev_stat.vs_aux = VDEV_AUX_NO_REPLICAS;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_root.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_root.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_root.c Wed Jul 25 16:45:04 2012 +0300
@@ -23,6 +23,10 @@
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
#include <sys/zfs_context.h>
#include <sys/spa.h>
#include <sys/vdev_impl.h>
@@ -50,7 +54,8 @@
}
static int
-vdev_root_open(vdev_t *vd, uint64_t *asize, uint64_t *ashift)
+vdev_root_open(vdev_t *vd, uint64_t *asize, uint64_t *max_asize,
+ uint64_t *ashift)
{
int lasterror = 0;
int numerrors = 0;
@@ -77,6 +82,7 @@
}
*asize = 0;
+ *max_asize = 0;
*ashift = 0;
return (0);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c Wed Jul 25 16:45:04 2012 +0300
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
/*
@@ -946,6 +947,19 @@
* Helper functions for consumers.
*/
+uint64_t
+zap_create_link(objset_t *os, dmu_object_type_t ot, uint64_t parent_obj,
+ const char *name, dmu_tx_t *tx)
+{
+ uint64_t new_obj;
+
+ VERIFY((new_obj = zap_create(os, ot, DMU_OT_NONE, 0, tx)) > 0);
+ VERIFY(zap_add(os, parent_obj, name, sizeof (uint64_t), 1, &new_obj,
+ tx) == 0);
+
+ return (new_obj);
+}
+
int
zap_value_search(objset_t *os, uint64_t zapobj, uint64_t value, uint64_t mask,
char *name)
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c Wed Jul 25 16:45:04 2012 +0300
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/zio.h>
@@ -472,7 +472,7 @@
{
dmu_object_info_t doi;
dmu_object_info_from_db(db, &doi);
- ASSERT(dmu_ot[doi.doi_type].ot_byteswap == zap_byteswap);
+ ASSERT3U(DMU_OT_BYTESWAP(doi.doi_type), ==, DMU_BSWAP_ZAP);
}
#endif
@@ -596,7 +596,7 @@
{
dmu_object_info_t doi;
dmu_object_info_from_db(db, &doi);
- ASSERT(dmu_ot[doi.doi_type].ot_byteswap == zap_byteswap);
+ ASSERT3U(DMU_OT_BYTESWAP(doi.doi_type), ==, DMU_BSWAP_ZAP);
}
#endif
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfeature.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfeature.c Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,414 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/zfeature.h>
+#include <sys/dmu.h>
+#include <sys/nvpair.h>
+#include <sys/zap.h>
+#include <sys/dmu_tx.h>
+#include "zfeature_common.h"
+#include <sys/spa_impl.h>
+
+/*
+ * ZFS Feature Flags
+ * -----------------
+ *
+ * ZFS feature flags are used to provide fine-grained versioning to the ZFS
+ * on-disk format. Once enabled on a pool feature flags replace the old
+ * spa_version() number.
+ *
+ * Each new on-disk format change will be given a uniquely identifying string
+ * guid rather than a version number. This avoids the problem of different
+ * organizations creating new on-disk formats with the same version number. To
+ * keep feature guids unique they should consist of the reverse dns name of the
+ * organization which implemented the feature and a short name for the feature,
+ * separated by a colon (e.g. com.delphix:async_destroy).
+ *
+ * Reference Counts
+ * ----------------
+ *
+ * Within each pool features can be in one of three states: disabled, enabled,
+ * or active. These states are differentiated by a reference count stored on
+ * disk for each feature:
+ *
+ * 1) If there is no reference count stored on disk the feature is disabled.
+ * 2) If the reference count is 0 a system administrator has enabled the
+ * feature, but the feature has not been used yet, so no on-disk
+ * format changes have been made.
+ * 3) If the reference count is greater than 0 the feature is active.
+ * The format changes required by the feature are currently on disk.
+ * Note that if the feature's format changes are reversed the feature
+ * may choose to set its reference count back to 0.
+ *
+ * Feature flags makes no differentiation between non-zero reference counts
+ * for an active feature (e.g. a reference count of 1 means the same thing as a
+ * reference count of 27834721), but feature implementations may choose to use
+ * the reference count to store meaningful information. For example, a new RAID
+ * implementation might set the reference count to the number of vdevs using
+ * it. If all those disks are removed from the pool the feature goes back to
+ * having a reference count of 0.
+ *
+ * It is the responsibility of the individual features to maintain a non-zero
+ * reference count as long as the feature's format changes are present on disk.
+ *
+ * Dependencies
+ * ------------
+ *
+ * Each feature may depend on other features. The only effect of this
+ * relationship is that when a feature is enabled all of its dependencies are
+ * automatically enabled as well. Any future work to support disabling of
+ * features would need to ensure that features cannot be disabled if other
+ * enabled features depend on them.
+ *
+ * On-disk Format
+ * --------------
+ *
+ * When feature flags are enabled spa_version() is set to SPA_VERSION_FEATURES
+ * (5000). In order for this to work the pool is automatically upgraded to
+ * SPA_VERSION_BEFORE_FEATURES (28) first, so all pre-feature flags on disk
+ * format changes will be in use.
+ *
+ * Information about features is stored in 3 ZAP objects in the pool's MOS.
+ * These objects are linked to by the following names in the pool directory
+ * object:
+ *
+ * 1) features_for_read: feature guid -> reference count
+ * Features needed to open the pool for reading.
+ * 2) features_for_write: feature guid -> reference count
+ * Features needed to open the pool for writing.
+ * 3) feature_descriptions: feature guid -> descriptive string
+ * A human readable string.
+ *
+ * All enabled features appear in either features_for_read or
+ * features_for_write, but not both.
+ *
+ * To open a pool in read-only mode only the features listed in
+ * features_for_read need to be supported.
+ *
+ * To open the pool in read-write mode features in both features_for_read and
+ * features_for_write need to be supported.
+ *
+ * Some features may be required to read the ZAP objects containing feature
+ * information. To allow software to check for compatibility with these features
+ * before the pool is opened their names must be stored in the label in a
+ * new "features_for_read" entry (note that features that are only required
+ * to write to a pool never need to be stored in the label since the
+ * features_for_write ZAP object can be read before the pool is written to).
+ * To save space in the label features must be explicitly marked as needing to
+ * be written to the label. Also, reference counts are not stored in the label,
+ * instead any feature whose reference count drops to 0 is removed from the
+ * label.
+ *
+ * Adding New Features
+ * -------------------
+ *
+ * Features must be registered in zpool_feature_init() function in
+ * zfeature_common.c using the zfeature_register() function. This function
+ * has arguments to specify if the feature should be stored in the
+ * features_for_read or features_for_write ZAP object and if it needs to be
+ * written to the label when active.
+ *
+ * Once a feature is registered it will appear as a "feature@<feature name>"
+ * property which can be set by an administrator. Feature implementors should
+ * use the spa_feature_is_enabled() and spa_feature_is_active() functions to
+ * query the state of a feature and the spa_feature_incr() and
+ * spa_feature_decr() functions to change an enabled feature's reference count.
+ * Reference counts may only be updated in the syncing context.
+ *
+ * Features may not perform enable-time initialization. Instead, any such
+ * initialization should occur when the feature is first used. This design
+ * enforces that on-disk changes be made only when features are used. Code
+ * should only check if a feature is enabled using spa_feature_is_enabled(),
+ * not by relying on any feature specific metadata existing. If a feature is
+ * enabled, but the feature's metadata is not on disk yet then it should be
+ * created as needed.
+ *
+ * As an example, consider the com.delphix:async_destroy feature. This feature
+ * relies on the existence of a bptree in the MOS that store blocks for
+ * asynchronous freeing. This bptree is not created when async_destroy is
+ * enabled. Instead, when a dataset is destroyed spa_feature_is_enabled() is
+ * called to check if async_destroy is enabled. If it is and the bptree object
+ * does not exist yet, the bptree object is created as part of the dataset
+ * destroy and async_destroy's reference count is incremented to indicate it
+ * has made an on-disk format change. Later, after the destroyed dataset's
+ * blocks have all been asynchronously freed there is no longer any use for the
+ * bptree object, so it is destroyed and async_destroy's reference count is
+ * decremented back to 0 to indicate that it has undone its on-disk format
+ * changes.
+ */
+
+typedef enum {
+ FEATURE_ACTION_ENABLE,
+ FEATURE_ACTION_INCR,
+ FEATURE_ACTION_DECR,
+} feature_action_t;
+
+/*
+ * Checks that the features active in the specified object are supported by
+ * this software. Adds each unsupported feature (name -> description) to
+ * the supplied nvlist.
+ */
+boolean_t
+feature_is_supported(objset_t *os, uint64_t obj, uint64_t desc_obj,
+ nvlist_t *unsup_feat)
+{
+ boolean_t supported;
+ zap_cursor_t zc;
+ zap_attribute_t za;
+
+ supported = B_TRUE;
+ for (zap_cursor_init(&zc, os, obj);
+ zap_cursor_retrieve(&zc, &za) == 0;
+ zap_cursor_advance(&zc)) {
+ ASSERT(za.za_integer_length == sizeof (uint64_t) &&
+ za.za_num_integers == 1);
+
+ if (za.za_first_integer != 0 &&
+ !zfeature_is_supported(za.za_name)) {
+ supported = B_FALSE;
+
+ if (unsup_feat != NULL) {
+ char *desc = "";
+ char buf[MAXPATHLEN];
+
+ if (zap_lookup(os, desc_obj, za.za_name,
+ 1, sizeof (buf), buf) == 0)
+ desc = buf;
+
+ VERIFY(nvlist_add_string(unsup_feat, za.za_name,
+ desc) == 0);
+ }
+ }
+ }
+ zap_cursor_fini(&zc);
+
+ return (supported);
+}
+
+static int
+feature_get_refcount(objset_t *os, uint64_t read_obj, uint64_t write_obj,
+ zfeature_info_t *feature, uint64_t *res)
+{
+ int err;
+ uint64_t refcount;
+ uint64_t zapobj = feature->fi_can_readonly ? write_obj : read_obj;
+
+ ASSERT(0 != zapobj);
+
+ err = zap_lookup(os, zapobj, feature->fi_guid, sizeof (uint64_t), 1,
+ &refcount);
+ if (err != 0) {
+ if (err == ENOENT)
+ return (ENOTSUP);
+ else
+ return (err);
+ }
+ *res = refcount;
+ return (0);
+}
+
+static int
+feature_do_action(objset_t *os, uint64_t read_obj, uint64_t write_obj,
+ uint64_t desc_obj, zfeature_info_t *feature, feature_action_t action,
+ dmu_tx_t *tx)
+{
+ int error;
+ uint64_t refcount;
+ uint64_t zapobj = feature->fi_can_readonly ? write_obj : read_obj;
+
+ ASSERT(0 != zapobj);
+ ASSERT(zfeature_is_valid_guid(feature->fi_guid));
+
+ error = zap_lookup(os, zapobj, feature->fi_guid,
+ sizeof (uint64_t), 1, &refcount);
+
+ /*
+ * If we can't ascertain the status of the specified feature, an I/O
+ * error occurred.
+ */
+ if (error != 0 && error != ENOENT)
+ return (error);
+
+ switch (action) {
+ case FEATURE_ACTION_ENABLE:
+ /*
+ * If the feature is already enabled, ignore the request.
+ */
+ if (error == 0)
+ return (0);
+ refcount = 0;
+ break;
+ case FEATURE_ACTION_INCR:
+ if (error == ENOENT)
+ return (ENOTSUP);
+ if (refcount == UINT64_MAX)
+ return (EOVERFLOW);
+ refcount++;
+ break;
+ case FEATURE_ACTION_DECR:
+ if (error == ENOENT)
+ return (ENOTSUP);
+ if (refcount == 0)
+ return (EOVERFLOW);
+ refcount--;
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ if (action == FEATURE_ACTION_ENABLE) {
+ int i;
+
+ for (i = 0; feature->fi_depends[i] != NULL; i++) {
+ zfeature_info_t *dep = feature->fi_depends[i];
+
+ error = feature_do_action(os, read_obj, write_obj,
+ desc_obj, dep, FEATURE_ACTION_ENABLE, tx);
+ if (error != 0)
+ return (error);
+ }
+ }
+
+ error = zap_update(os, zapobj, feature->fi_guid,
+ sizeof (uint64_t), 1, &refcount, tx);
+ if (error != 0)
+ return (error);
+
+ if (action == FEATURE_ACTION_ENABLE) {
+ error = zap_update(os, desc_obj,
+ feature->fi_guid, 1, strlen(feature->fi_desc) + 1,
+ feature->fi_desc, tx);
+ if (error != 0)
+ return (error);
+ }
+
+ if (action == FEATURE_ACTION_INCR && refcount == 1 && feature->fi_mos) {
+ spa_activate_mos_feature(dmu_objset_spa(os), feature->fi_guid);
+ }
+
+ if (action == FEATURE_ACTION_DECR && refcount == 0) {
+ spa_deactivate_mos_feature(dmu_objset_spa(os),
+ feature->fi_guid);
+ }
+
+ return (0);
+}
+
+void
+spa_feature_create_zap_objects(spa_t *spa, dmu_tx_t *tx)
+{
+ /*
+ * We create feature flags ZAP objects in two instances: during pool
+ * creation and during pool upgrade.
+ */
+ ASSERT(dsl_pool_sync_context(spa_get_dsl(spa)) || (!spa->spa_sync_on &&
+ tx->tx_txg == TXG_INITIAL));
+
+ spa->spa_feat_for_read_obj = zap_create_link(spa->spa_meta_objset,
+ DMU_OTN_ZAP_METADATA, DMU_POOL_DIRECTORY_OBJECT,
+ DMU_POOL_FEATURES_FOR_READ, tx);
+ spa->spa_feat_for_write_obj = zap_create_link(spa->spa_meta_objset,
+ DMU_OTN_ZAP_METADATA, DMU_POOL_DIRECTORY_OBJECT,
+ DMU_POOL_FEATURES_FOR_WRITE, tx);
+ spa->spa_feat_desc_obj = zap_create_link(spa->spa_meta_objset,
+ DMU_OTN_ZAP_METADATA, DMU_POOL_DIRECTORY_OBJECT,
+ DMU_POOL_FEATURE_DESCRIPTIONS, tx);
+}
+
+/*
+ * Enable any required dependencies, then enable the requested feature.
+ */
+void
+spa_feature_enable(spa_t *spa, zfeature_info_t *feature, dmu_tx_t *tx)
+{
+ ASSERT3U(spa_version(spa), >=, SPA_VERSION_FEATURES);
+ VERIFY3U(0, ==, feature_do_action(spa->spa_meta_objset,
+ spa->spa_feat_for_read_obj, spa->spa_feat_for_write_obj,
+ spa->spa_feat_desc_obj, feature, FEATURE_ACTION_ENABLE, tx));
+}
+
+/*
+ * If the specified feature has not yet been enabled, this function returns
+ * ENOTSUP; otherwise, this function increments the feature's refcount (or
+ * returns EOVERFLOW if the refcount cannot be incremented). This function must
+ * be called from syncing context.
+ */
+void
+spa_feature_incr(spa_t *spa, zfeature_info_t *feature, dmu_tx_t *tx)
+{
+ ASSERT3U(spa_version(spa), >=, SPA_VERSION_FEATURES);
+ VERIFY3U(0, ==, feature_do_action(spa->spa_meta_objset,
+ spa->spa_feat_for_read_obj, spa->spa_feat_for_write_obj,
+ spa->spa_feat_desc_obj, feature, FEATURE_ACTION_INCR, tx));
+}
+
+/*
+ * If the specified feature has not yet been enabled, this function returns
+ * ENOTSUP; otherwise, this function decrements the feature's refcount (or
+ * returns EOVERFLOW if the refcount is already 0). This function must
+ * be called from syncing context.
+ */
+void
+spa_feature_decr(spa_t *spa, zfeature_info_t *feature, dmu_tx_t *tx)
+{
+ ASSERT3U(spa_version(spa), >=, SPA_VERSION_FEATURES);
+ VERIFY3U(0, ==, feature_do_action(spa->spa_meta_objset,
+ spa->spa_feat_for_read_obj, spa->spa_feat_for_write_obj,
+ spa->spa_feat_desc_obj, feature, FEATURE_ACTION_DECR, tx));
+}
+
+boolean_t
+spa_feature_is_enabled(spa_t *spa, zfeature_info_t *feature)
+{
+ int err;
+ uint64_t refcount;
+
+ if (spa_version(spa) < SPA_VERSION_FEATURES)
+ return (B_FALSE);
+
+ err = feature_get_refcount(spa->spa_meta_objset,
+ spa->spa_feat_for_read_obj, spa->spa_feat_for_write_obj,
+ feature, &refcount);
+ ASSERT(err == 0 || err == ENOTSUP);
+ return (err == 0);
+}
+
+boolean_t
+spa_feature_is_active(spa_t *spa, zfeature_info_t *feature)
+{
+ int err;
+ uint64_t refcount;
+
+ if (spa_version(spa) < SPA_VERSION_FEATURES)
+ return (B_FALSE);
+
+ err = feature_get_refcount(spa->spa_meta_objset,
+ spa->spa_feat_for_read_obj, spa->spa_feat_for_write_obj,
+ feature, &refcount);
+ ASSERT(err == 0 || err == ENOTSUP);
+ return (err == 0 && refcount > 0);
+}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Wed Jul 25 16:45:04 2012 +0300
@@ -18,13 +18,15 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011-2012 Pawel Jakub Dawidek <pawel at dawidek.net>.
* All rights reserved.
* Portions Copyright 2011 Martin Matuska <mm at FreeBSD.org>
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#include <sys/types.h>
@@ -57,6 +59,7 @@
#include <sys/dsl_prop.h>
#include <sys/dsl_deleg.h>
#include <sys/dmu_objset.h>
+#include <sys/dmu_impl.h>
#include <sys/sunddi.h>
#include <sys/policy.h>
#include <sys/zone.h>
@@ -1155,6 +1158,8 @@
/*
* Find a zfsvfs_t for a mounted filesystem, or create our own, in which
* case its z_vfs will be NULL, and it will be opened as the owner.
+ * If 'writer' is set, the z_teardown_lock will be held for RW_WRITER,
+ * which prevents all vnode ops from running.
*/
static int
zfsvfs_hold(const char *name, void *tag, zfsvfs_t **zfvp, boolean_t writer)
@@ -1218,7 +1223,7 @@
(void) nvlist_lookup_uint64(props,
zpool_prop_to_name(ZPOOL_PROP_VERSION), &version);
- if (version < SPA_VERSION_INITIAL || version > SPA_VERSION) {
+ if (!SPA_VERSION_IS_SUPPORTED(version)) {
error = EINVAL;
goto pool_props_bad;
}
@@ -1342,6 +1347,15 @@
return (error);
}
+/*
+ * inputs:
+ * zc_name name of the pool
+ *
+ * outputs:
+ * zc_cookie real errno
+ * zc_nvlist_dst config nvlist
+ * zc_nvlist_dst_size size of config nvlist
+ */
static int
zfs_ioc_pool_stats(zfs_cmd_t *zc)
{
@@ -1443,7 +1457,8 @@
if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
return (error);
- if (zc->zc_cookie < spa_version(spa) || zc->zc_cookie > SPA_VERSION) {
+ if (zc->zc_cookie < spa_version(spa) ||
+ !SPA_VERSION_IS_SUPPORTED(zc->zc_cookie)) {
spa_close(spa, FTAG);
return (EINVAL);
}
@@ -3933,7 +3948,8 @@
}
off = fp->f_offset;
- error = dmu_sendbackup(tosnap, fromsnap, zc->zc_obj, fp, &off);
+ error = dmu_send(tosnap, fromsnap, zc->zc_obj,
+ zc->zc_cookie, fp, &off);
if (off >= 0 && off <= MAXOFFSET_T)
fp->f_offset = off;
@@ -3945,6 +3961,49 @@
return (error);
}
+/*
+ * inputs:
+ * zc_name name of snapshot on which to report progress
+ * zc_cookie file descriptor of send stream
+ *
+ * outputs:
+ * zc_cookie number of bytes written in send stream thus far
+ */
+static int
+zfs_ioc_send_progress(zfs_cmd_t *zc)
+{
+ dsl_dataset_t *ds;
+ dmu_sendarg_t *dsp = NULL;
+ int error;
+
+ if ((error = dsl_dataset_hold(zc->zc_name, FTAG, &ds)) != 0)
+ return (error);
+
+ mutex_enter(&ds->ds_sendstream_lock);
+
+ /*
+ * Iterate over all the send streams currently active on this dataset.
+ * If there's one which matches the specified file descriptor _and_ the
+ * stream was started by the current process, return the progress of
+ * that stream.
+ */
+ for (dsp = list_head(&ds->ds_sendstreams); dsp != NULL;
+ dsp = list_next(&ds->ds_sendstreams, dsp)) {
+ if (dsp->dsa_outfd == zc->zc_cookie &&
+ dsp->dsa_proc == curproc)
+ break;
+ }
+
+ if (dsp != NULL)
+ zc->zc_cookie = *(dsp->dsa_off);
+ else
+ error = ENOENT;
+
+ mutex_exit(&ds->ds_sendstream_lock);
+ dsl_dataset_rele(ds, FTAG);
+ return (error);
+}
+
static int
zfs_ioc_inject_fault(zfs_cmd_t *zc)
{
@@ -4079,6 +4138,22 @@
return (error);
}
+static int
+zfs_ioc_pool_reopen(zfs_cmd_t *zc)
+{
+ spa_t *spa;
+ int error;
+
+ error = spa_open(zc->zc_name, &spa, FTAG);
+ if (error)
+ return (error);
+
+ spa_vdev_state_enter(spa, SCL_NONE);
+ vdev_reopen(spa->spa_root_vdev);
+ (void) spa_vdev_state_exit(spa, NULL, 0);
+ spa_close(spa, FTAG);
+ return (0);
+}
/*
* inputs:
* zc_name name of filesystem
@@ -4946,7 +5021,11 @@
{ zfs_ioc_space_written, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
B_TRUE },
{ zfs_ioc_space_snaps, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
- B_TRUE }
+ B_TRUE },
+ { zfs_ioc_send_progress, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
+ B_FALSE },
+ { zfs_ioc_pool_reopen, zfs_secpolicy_config, POOL_NAME, B_TRUE,
+ B_TRUE },
};
int
@@ -5386,7 +5465,7 @@
tsd_create(&zfs_fsyncer_key, NULL);
tsd_create(&rrw_tsd_key, NULL);
- printf("ZFS storage pool version " SPA_VERSION_STRING "\n");
+ printf("ZFS storage pool version: features support (" SPA_VERSION_STRING ")\n");
root_mount_rel(zfs_root_token);
zfsdev_init();
@@ -5424,4 +5503,3 @@
MODULE_DEPEND(zfsctrl, opensolaris, 1, 1, 1);
MODULE_DEPEND(zfsctrl, krpc, 1, 1, 1);
MODULE_DEPEND(zfsctrl, acl_nfs4, 1, 1, 1);
-MODULE_DEPEND(zfsctrl, acl_posix1e, 1, 1, 1);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Wed Jul 25 16:45:04 2012 +0300
@@ -2278,7 +2278,7 @@
zfs_init(void)
{
- printf("ZFS filesystem version " ZPL_VERSION_STRING "\n");
+ printf("ZFS filesystem version: " ZPL_VERSION_STRING "\n");
/*
* Initialize .zfs directory structures
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Wed Jul 25 16:45:04 2012 +0300
@@ -838,6 +838,12 @@
rl = zfs_range_lock(zp, woff, n, RL_WRITER);
}
+ if (vn_rlimit_fsize(vp, uio, uio->uio_td)) {
+ zfs_range_unlock(rl);
+ ZFS_EXIT(zfsvfs);
+ return (EFBIG);
+ }
+
if (woff >= limit) {
zfs_range_unlock(rl);
ZFS_EXIT(zfsvfs);
@@ -4556,7 +4562,7 @@
ASSERT(vp->v_count <= 1);
vp->v_count = 0;
VI_UNLOCK(vp);
- vrecycle(vp, curthread);
+ vrecycle(vp);
rw_exit(&zfsvfs->z_teardown_inactive_lock);
return;
}
@@ -5696,9 +5702,6 @@
} */ *ap;
{
- if (vn_rlimit_fsize(ap->a_vp, ap->a_uio, ap->a_uio->uio_td))
- return (EFBIG);
-
return (zfs_write(ap->a_vp, ap->a_uio, ioflags(ap->a_ioflag),
ap->a_cred, NULL));
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c Wed Jul 25 16:45:04 2012 +0300
@@ -1428,7 +1428,7 @@
mutex_exit(&zp->z_lock);
ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id);
ASSERT(vp->v_count == 0);
- vrecycle(vp, curthread);
+ vrecycle(vp);
vfslocked = VFS_LOCK_GIANT(zfsvfs->z_vfs);
zfs_rmnode(zp);
VFS_UNLOCK_GIANT(vfslocked);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c Wed Jul 25 16:45:04 2012 +0300
@@ -640,7 +640,7 @@
zp->zp_checksum < ZIO_CHECKSUM_FUNCTIONS &&
zp->zp_compress >= ZIO_COMPRESS_OFF &&
zp->zp_compress < ZIO_COMPRESS_FUNCTIONS &&
- zp->zp_type < DMU_OT_NUMTYPES &&
+ DMU_OT_IS_VALID(zp->zp_type) &&
zp->zp_level < 32 &&
zp->zp_copies > 0 &&
zp->zp_copies <= spa_max_replication(spa) &&
@@ -924,7 +924,7 @@
zio_push_transform(zio, cbuf, psize, psize, zio_decompress);
}
- if (!dmu_ot[BP_GET_TYPE(bp)].ot_metadata && BP_GET_LEVEL(bp) == 0)
+ if (!DMU_OT_IS_METADATA(BP_GET_TYPE(bp)) && BP_GET_LEVEL(bp) == 0)
zio->io_flags |= ZIO_FLAG_DONT_CACHE;
if (BP_GET_TYPE(bp) == DMU_OT_DDT_ZAP)
@@ -3015,3 +3015,45 @@
zio_checksum_verify,
zio_done
};
+
+/* dnp is the dnode for zb1->zb_object */
+boolean_t
+zbookmark_is_before(const dnode_phys_t *dnp, const zbookmark_t *zb1,
+ const zbookmark_t *zb2)
+{
+ uint64_t zb1nextL0, zb2thisobj;
+
+ ASSERT(zb1->zb_objset == zb2->zb_objset);
+ ASSERT(zb2->zb_level == 0);
+
+ /*
+ * A bookmark in the deadlist is considered to be after
+ * everything else.
+ */
+ if (zb2->zb_object == DMU_DEADLIST_OBJECT)
+ return (B_TRUE);
+
+ /* The objset_phys_t isn't before anything. */
+ if (dnp == NULL)
+ return (B_FALSE);
+
+ zb1nextL0 = (zb1->zb_blkid + 1) <<
+ ((zb1->zb_level) * (dnp->dn_indblkshift - SPA_BLKPTRSHIFT));
+
+ zb2thisobj = zb2->zb_object ? zb2->zb_object :
+ zb2->zb_blkid << (DNODE_BLOCK_SHIFT - DNODE_SHIFT);
+
+ if (zb1->zb_object == DMU_META_DNODE_OBJECT) {
+ uint64_t nextobj = zb1nextL0 *
+ (dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT) >> DNODE_SHIFT;
+ return (nextobj <= zb2thisobj);
+ }
+
+ if (zb1->zb_object < zb2thisobj)
+ return (B_TRUE);
+ if (zb1->zb_object > zb2thisobj)
+ return (B_FALSE);
+ if (zb2->zb_object == DMU_META_DNODE_OBJECT)
+ return (B_FALSE);
+ return (zb1nextL0 <= zb2->zb_blkid);
+}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
--- a/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c Wed Jul 25 16:45:04 2012 +0300
@@ -177,15 +177,9 @@
pp = zv->zv_provider;
if (pp == NULL)
return;
- if (zv->zv_volsize == pp->mediasize)
- return;
- /*
- * Changing provider size is not really supported by GEOM, but it
- * should be safe when provider is closed.
- */
- if (zv->zv_total_opens > 0)
- return;
- pp->mediasize = zv->zv_volsize;
+ g_topology_lock();
+ g_resize_provider(pp, zv->zv_volsize);
+ g_topology_unlock();
#endif /* !sun */
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
--- a/head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h Wed Jul 25 16:45:04 2012 +0300
@@ -24,6 +24,10 @@
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
#ifndef _SYS_DTRACE_H
#define _SYS_DTRACE_H
@@ -251,6 +255,10 @@
#define DIF_VAR_ERRNO 0x0120 /* thread errno */
#define DIF_VAR_EXECARGS 0x0121 /* process arguments */
+#if !defined(sun)
+#define DIF_VAR_CPU 0x0200
+#endif
+
#define DIF_SUBR_RAND 0
#define DIF_SUBR_MUTEX_OWNED 1
#define DIF_SUBR_MUTEX_OWNER 2
@@ -477,6 +485,7 @@
#define DTRACEAGG_STDDEV (DTRACEACT_AGGREGATION + 6)
#define DTRACEAGG_QUANTIZE (DTRACEACT_AGGREGATION + 7)
#define DTRACEAGG_LQUANTIZE (DTRACEACT_AGGREGATION + 8)
+#define DTRACEAGG_LLQUANTIZE (DTRACEACT_AGGREGATION + 9)
#define DTRACEACT_ISAGG(x) \
(DTRACEACT_CLASS(x) == DTRACEACT_AGGREGATION)
@@ -511,6 +520,31 @@
(int32_t)(((x) & DTRACE_LQUANTIZE_BASEMASK) >> \
DTRACE_LQUANTIZE_BASESHIFT)
+#define DTRACE_LLQUANTIZE_FACTORSHIFT 48
+#define DTRACE_LLQUANTIZE_FACTORMASK ((uint64_t)UINT16_MAX << 48)
+#define DTRACE_LLQUANTIZE_LOWSHIFT 32
+#define DTRACE_LLQUANTIZE_LOWMASK ((uint64_t)UINT16_MAX << 32)
+#define DTRACE_LLQUANTIZE_HIGHSHIFT 16
+#define DTRACE_LLQUANTIZE_HIGHMASK ((uint64_t)UINT16_MAX << 16)
+#define DTRACE_LLQUANTIZE_NSTEPSHIFT 0
+#define DTRACE_LLQUANTIZE_NSTEPMASK UINT16_MAX
+
+#define DTRACE_LLQUANTIZE_FACTOR(x) \
+ (uint16_t)(((x) & DTRACE_LLQUANTIZE_FACTORMASK) >> \
+ DTRACE_LLQUANTIZE_FACTORSHIFT)
+
+#define DTRACE_LLQUANTIZE_LOW(x) \
+ (uint16_t)(((x) & DTRACE_LLQUANTIZE_LOWMASK) >> \
+ DTRACE_LLQUANTIZE_LOWSHIFT)
+
+#define DTRACE_LLQUANTIZE_HIGH(x) \
+ (uint16_t)(((x) & DTRACE_LLQUANTIZE_HIGHMASK) >> \
+ DTRACE_LLQUANTIZE_HIGHSHIFT)
+
+#define DTRACE_LLQUANTIZE_NSTEP(x) \
+ (uint16_t)(((x) & DTRACE_LLQUANTIZE_NSTEPMASK) >> \
+ DTRACE_LLQUANTIZE_NSTEPSHIFT)
+
#define DTRACE_USTACK_NFRAMES(x) (uint32_t)((x) & UINT32_MAX)
#define DTRACE_USTACK_STRSIZE(x) (uint32_t)((x) >> 32)
#define DTRACE_USTACK_ARG(x, y) \
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
--- a/head/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h Wed Jul 25 16:45:04 2012 +0300
@@ -21,8 +21,10 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2012, Martin Matuska <mm at FreeBSD.org>. All rights reserved.
*/
/* Portions Copyright 2010 Robert Milkowski */
@@ -169,6 +171,8 @@
ZPOOL_PROP_ALLOCATED,
ZPOOL_PROP_READONLY,
ZPOOL_PROP_COMMENT,
+ ZPOOL_PROP_EXPANDSZ,
+ ZPOOL_PROP_FREEING,
ZPOOL_NUM_PROPS
} zpool_prop_t;
@@ -242,6 +246,8 @@
const char *zpool_prop_default_string(zpool_prop_t);
uint64_t zpool_prop_default_numeric(zpool_prop_t);
boolean_t zpool_prop_readonly(zpool_prop_t);
+boolean_t zpool_prop_feature(const char *);
+boolean_t zpool_prop_unsupported(const char *name);
int zpool_prop_index_to_string(zpool_prop_t, uint64_t, const char **);
int zpool_prop_string_to_index(zpool_prop_t, const char *, uint64_t *);
uint64_t zpool_prop_random_value(zpool_prop_t, uint64_t seed);
@@ -349,6 +355,7 @@
#define SPA_VERSION_26 26ULL
#define SPA_VERSION_27 27ULL
#define SPA_VERSION_28 28ULL
+#define SPA_VERSION_5000 5000ULL
/*
* When bumping up SPA_VERSION, make sure GRUB ZFS understands the on-disk
@@ -356,8 +363,8 @@
* and do the appropriate changes. Also bump the version number in
* usr/src/grub/capability.
*/
-#define SPA_VERSION SPA_VERSION_28
-#define SPA_VERSION_STRING "28"
+#define SPA_VERSION SPA_VERSION_5000
+#define SPA_VERSION_STRING "5000"
/*
* Symbolic names for the changes that caused a SPA_VERSION switch.
@@ -408,6 +415,12 @@
#define SPA_VERSION_DEADLISTS SPA_VERSION_26
#define SPA_VERSION_FAST_SNAP SPA_VERSION_27
#define SPA_VERSION_MULTI_REPLACE SPA_VERSION_28
+#define SPA_VERSION_BEFORE_FEATURES SPA_VERSION_28
+#define SPA_VERSION_FEATURES SPA_VERSION_5000
+
+#define SPA_VERSION_IS_SUPPORTED(v) \
+ (((v) >= SPA_VERSION_INITIAL && (v) <= SPA_VERSION_BEFORE_FEATURES) || \
+ ((v) >= SPA_VERSION_FEATURES && (v) <= SPA_VERSION))
/*
* ZPL version - rev'd whenever an incompatible on-disk format change
@@ -505,6 +518,11 @@
#define ZPOOL_CONFIG_BOOTFS "bootfs" /* not stored on disk */
#define ZPOOL_CONFIG_MISSING_DEVICES "missing_vdevs" /* not stored on disk */
#define ZPOOL_CONFIG_LOAD_INFO "load_info" /* not stored on disk */
+#define ZPOOL_CONFIG_REWIND_INFO "rewind_info" /* not stored on disk */
+#define ZPOOL_CONFIG_UNSUP_FEAT "unsup_feat" /* not stored on disk */
+#define ZPOOL_CONFIG_CAN_RDONLY "can_rdonly" /* not stored on disk */
+#define ZPOOL_CONFIG_FEATURES_FOR_READ "features_for_read"
+#define ZPOOL_CONFIG_FEATURE_STATS "feature_stats" /* not stored on disk */
/*
* The persistent vdev state is stored as separate values rather than a single
* 'vdev_state' entry. This is because a device can be in multiple states, such
@@ -583,6 +601,7 @@
VDEV_AUX_BAD_LABEL, /* the label is OK but invalid */
VDEV_AUX_VERSION_NEWER, /* on-disk version is too new */
VDEV_AUX_VERSION_OLDER, /* on-disk version is too old */
+ VDEV_AUX_UNSUP_FEAT, /* unsupported features */
VDEV_AUX_SPARED, /* hot spare used in another pool */
VDEV_AUX_ERR_EXCEEDED, /* too many errors */
VDEV_AUX_IO_FAILURE, /* experienced I/O failure */
@@ -673,6 +692,7 @@
uint64_t vs_space; /* total capacity */
uint64_t vs_dspace; /* deflated capacity */
uint64_t vs_rsize; /* replaceable dev size */
+ uint64_t vs_esize; /* expandable dev size */
uint64_t vs_ops[ZIO_TYPES]; /* operation count */
uint64_t vs_bytes[ZIO_TYPES]; /* bytes read/written */
uint64_t vs_read_errors; /* read errors */
@@ -794,6 +814,8 @@
#define ZFS_IOC_POOL_REGUID _IOWR('Z', 60, struct zfs_cmd)
#define ZFS_IOC_SPACE_WRITTEN _IOWR('Z', 61, struct zfs_cmd)
#define ZFS_IOC_SPACE_SNAPS _IOWR('Z', 62, struct zfs_cmd)
+#define ZFS_IOC_SEND_PROGRESS _IOWR('Z', 63, struct zfs_cmd)
+#define ZFS_IOC_POOL_REOPEN _IOWR('Z', 64, struct zfs_cmd)
/*
* Internal SPA load state. Used by FMA diagnosis engine.
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/contrib/opensolaris/uts/common/sys/nvpair.h
--- a/head/sys/cddl/contrib/opensolaris/uts/common/sys/nvpair.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/contrib/opensolaris/uts/common/sys/nvpair.h Wed Jul 25 16:45:04 2012 +0300
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#ifndef _SYS_NVPAIR_H
@@ -274,6 +275,73 @@
int nvpair_value_double(nvpair_t *, double *);
#endif
+nvlist_t *fnvlist_alloc(void);
+void fnvlist_free(nvlist_t *);
+size_t fnvlist_size(nvlist_t *);
+char *fnvlist_pack(nvlist_t *, size_t *);
+void fnvlist_pack_free(char *, size_t);
+nvlist_t *fnvlist_unpack(char *, size_t);
+nvlist_t *fnvlist_dup(nvlist_t *);
+void fnvlist_merge(nvlist_t *, nvlist_t *);
+
+void fnvlist_add_boolean(nvlist_t *, const char *);
+void fnvlist_add_boolean_value(nvlist_t *, const char *, boolean_t);
+void fnvlist_add_byte(nvlist_t *, const char *, uchar_t);
+void fnvlist_add_int8(nvlist_t *, const char *, int8_t);
+void fnvlist_add_uint8(nvlist_t *, const char *, uint8_t);
+void fnvlist_add_int16(nvlist_t *, const char *, int16_t);
+void fnvlist_add_uint16(nvlist_t *, const char *, uint16_t);
+void fnvlist_add_int32(nvlist_t *, const char *, int32_t);
+void fnvlist_add_uint32(nvlist_t *, const char *, uint32_t);
+void fnvlist_add_int64(nvlist_t *, const char *, int64_t);
+void fnvlist_add_uint64(nvlist_t *, const char *, uint64_t);
+void fnvlist_add_string(nvlist_t *, const char *, const char *);
+void fnvlist_add_nvlist(nvlist_t *, const char *, nvlist_t *);
+void fnvlist_add_nvpair(nvlist_t *, nvpair_t *);
+void fnvlist_add_boolean_array(nvlist_t *, const char *, boolean_t *, uint_t);
+void fnvlist_add_byte_array(nvlist_t *, const char *, uchar_t *, uint_t);
+void fnvlist_add_int8_array(nvlist_t *, const char *, int8_t *, uint_t);
+void fnvlist_add_uint8_array(nvlist_t *, const char *, uint8_t *, uint_t);
+void fnvlist_add_int16_array(nvlist_t *, const char *, int16_t *, uint_t);
+void fnvlist_add_uint16_array(nvlist_t *, const char *, uint16_t *, uint_t);
+void fnvlist_add_int32_array(nvlist_t *, const char *, int32_t *, uint_t);
+void fnvlist_add_uint32_array(nvlist_t *, const char *, uint32_t *, uint_t);
+void fnvlist_add_int64_array(nvlist_t *, const char *, int64_t *, uint_t);
+void fnvlist_add_uint64_array(nvlist_t *, const char *, uint64_t *, uint_t);
+void fnvlist_add_string_array(nvlist_t *, const char *, char * const *, uint_t);
+void fnvlist_add_nvlist_array(nvlist_t *, const char *, nvlist_t **, uint_t);
+
+void fnvlist_remove(nvlist_t *, const char *);
+void fnvlist_remove_nvpair(nvlist_t *, nvpair_t *);
+
+nvpair_t *fnvlist_lookup_nvpair(nvlist_t *nvl, const char *name);
+boolean_t fnvlist_lookup_boolean(nvlist_t *nvl, const char *name);
+boolean_t fnvlist_lookup_boolean_value(nvlist_t *nvl, const char *name);
+uchar_t fnvlist_lookup_byte(nvlist_t *nvl, const char *name);
+int8_t fnvlist_lookup_int8(nvlist_t *nvl, const char *name);
+int16_t fnvlist_lookup_int16(nvlist_t *nvl, const char *name);
+int32_t fnvlist_lookup_int32(nvlist_t *nvl, const char *name);
+int64_t fnvlist_lookup_int64(nvlist_t *nvl, const char *name);
+uint8_t fnvlist_lookup_uint8_t(nvlist_t *nvl, const char *name);
+uint16_t fnvlist_lookup_uint16(nvlist_t *nvl, const char *name);
+uint32_t fnvlist_lookup_uint32(nvlist_t *nvl, const char *name);
+uint64_t fnvlist_lookup_uint64(nvlist_t *nvl, const char *name);
+char *fnvlist_lookup_string(nvlist_t *nvl, const char *name);
+nvlist_t *fnvlist_lookup_nvlist(nvlist_t *nvl, const char *name);
+
+boolean_t fnvpair_value_boolean_value(nvpair_t *nvp);
+uchar_t fnvpair_value_byte(nvpair_t *nvp);
+int8_t fnvpair_value_int8(nvpair_t *nvp);
+int16_t fnvpair_value_int16(nvpair_t *nvp);
+int32_t fnvpair_value_int32(nvpair_t *nvp);
+int64_t fnvpair_value_int64(nvpair_t *nvp);
+uint8_t fnvpair_value_uint8_t(nvpair_t *nvp);
+uint16_t fnvpair_value_uint16(nvpair_t *nvp);
+uint32_t fnvpair_value_uint32(nvpair_t *nvp);
+uint64_t fnvpair_value_uint64(nvpair_t *nvp);
+char *fnvpair_value_string(nvpair_t *nvp);
+nvlist_t *fnvpair_value_nvlist(nvpair_t *nvp);
+
#ifdef __cplusplus
}
#endif
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/dev/dtrace/amd64/dis_tables.c
--- a/head/sys/cddl/dev/dtrace/amd64/dis_tables.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/dev/dtrace/amd64/dis_tables.c Wed Jul 25 16:45:04 2012 +0300
@@ -18,7 +18,7 @@
*
* CDDL HEADER END
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/cddl/dev/dtrace/amd64/dis_tables.c 238169 2012-07-06 14:45:30Z avg $
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
@@ -815,7 +815,7 @@
/* [10] */ TNSZ("movups",XMMO,16), TNSZ("movups",XMMOS,16),TNSZ("movlps",XMMO,8), TNSZ("movlps",XMMOS,8),
/* [14] */ TNSZ("unpcklps",XMMO,16),TNSZ("unpckhps",XMMO,16),TNSZ("movhps",XMMOM,8),TNSZ("movhps",XMMOMS,8),
/* [18] */ IND(dis_op0F18), INVALID, INVALID, INVALID,
-/* [1C] */ INVALID, INVALID, INVALID, INVALID,
+/* [1C] */ INVALID, INVALID, INVALID, TS("nopw", Mw),
}, {
/* [20] */ TSy("mov",SREG), TSy("mov",SREG), TSy("mov",SREG), TSy("mov",SREG),
/* [24] */ TSx("mov",SREG), INVALID, TSx("mov",SREG), INVALID,
@@ -1146,14 +1146,14 @@
/* [1,C] */ TNS("sbbb",IA), TS("sbb",IA), TSx("push",SEG), TSx("pop",SEG),
}, {
/* [2,0] */ TNS("andb",RMw), TS("and",RMw), TNS("andb",MRw), TS("and",MRw),
-/* [2,4] */ TNS("andb",IA), TS("and",IA), TNSx("%es:",OVERRIDE), TNSx("daa",NORM),
+/* [2,4] */ TNS("andb",IA), TS("and",IA), TNS("%es:",OVERRIDE), TNSx("daa",NORM),
/* [2,8] */ TNS("subb",RMw), TS("sub",RMw), TNS("subb",MRw), TS("sub",MRw),
-/* [2,C] */ TNS("subb",IA), TS("sub",IA), TNSx("%cs:",OVERRIDE), TNSx("das",NORM),
+/* [2,C] */ TNS("subb",IA), TS("sub",IA), TNS("%cs:",OVERRIDE), TNSx("das",NORM),
}, {
/* [3,0] */ TNS("xorb",RMw), TS("xor",RMw), TNS("xorb",MRw), TS("xor",MRw),
-/* [3,4] */ TNS("xorb",IA), TS("xor",IA), TNSx("%ss:",OVERRIDE), TNSx("aaa",NORM),
+/* [3,4] */ TNS("xorb",IA), TS("xor",IA), TNS("%ss:",OVERRIDE), TNSx("aaa",NORM),
/* [3,8] */ TNS("cmpb",RMw), TS("cmp",RMw), TNS("cmpb",MRw), TS("cmp",MRw),
-/* [3,C] */ TNS("cmpb",IA), TS("cmp",IA), TNSx("%ds:",OVERRIDE), TNSx("aas",NORM),
+/* [3,C] */ TNS("cmpb",IA), TS("cmp",IA), TNS("%ds:",OVERRIDE), TNSx("aas",NORM),
}, {
/* [4,0] */ TSx("inc",R), TSx("inc",R), TSx("inc",R), TSx("inc",R),
/* [4,4] */ TSx("inc",R), TSx("inc",R), TSx("inc",R), TSx("inc",R),
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/dev/dtrace/amd64/dtrace_subr.c
--- a/head/sys/cddl/dev/dtrace/amd64/dtrace_subr.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/dev/dtrace/amd64/dtrace_subr.c Wed Jul 25 16:45:04 2012 +0300
@@ -19,7 +19,7 @@
*
* CDDL HEADER END
*
- * $FreeBSD: head/sys/cddl/dev/dtrace/amd64/dtrace_subr.c 223758 2011-07-04 12:04:52Z attilio $
+ * $FreeBSD: head/sys/cddl/dev/dtrace/amd64/dtrace_subr.c 238552 2012-07-17 14:36:40Z gnn $
*
*/
/*
@@ -27,6 +27,10 @@
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/types.h>
@@ -43,6 +47,8 @@
extern uintptr_t dtrace_in_probe_addr;
extern int dtrace_in_probe;
+extern void dtrace_getnanotime(struct timespec *tsp);
+
int dtrace_invop(uintptr_t, uintptr_t *, uintptr_t);
typedef struct dtrace_invop_hdlr {
@@ -297,14 +303,15 @@
}
/*
- * If we've executed the original instruction, but haven't performed
- * the jmp back to t->t_dtrace_npc or the clean up of any registers
- * used to emulate %rip-relative instructions in 64-bit mode, do that
- * here and take the signal right away. We detect this condition by
- * seeing if the program counter is the range [scrpc + isz, astpc).
+ * If we have executed the original instruction, but we have performed
+ * neither the jmp back to t->t_dtrace_npc nor the clean up of any
+ * registers used to emulate %rip-relative instructions in 64-bit mode,
+ * we'll save ourselves some effort by doing that here and taking the
+ * signal right away. We detect this condition by seeing if the program
+ * counter is the range [scrpc + isz, astpc).
*/
- if (t->t_dtrace_astpc - rp->r_pc <
- t->t_dtrace_astpc - t->t_dtrace_scrpc - isz) {
+ if (rp->r_pc >= t->t_dtrace_scrpc + isz &&
+ rp->r_pc < t->t_dtrace_astpc) {
#ifdef __amd64
/*
* If there is a scratch register and we're on the
@@ -446,7 +453,7 @@
* (see nsec_scale calculations) taking into account 32-bit shift of
* the higher half and finally add.
*/
- tsc = rdtsc() + tsc_skew[curcpu];
+ tsc = rdtsc() - tsc_skew[curcpu];
lo = tsc;
hi = tsc >> 32;
return (((lo * nsec_scale) >> SCALE_SHIFT) +
@@ -456,8 +463,11 @@
uint64_t
dtrace_gethrestime(void)
{
- printf("%s(%d): XXX\n",__func__,__LINE__);
- return (0);
+ struct timespec current_time;
+
+ dtrace_getnanotime(¤t_time);
+
+ return (current_time.tv_sec * 1000000000ULL + current_time.tv_nsec);
}
/* Function to handle DTrace traps during probes. See amd64/amd64/trap.c */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/dev/dtrace/i386/dis_tables.c
--- a/head/sys/cddl/dev/dtrace/i386/dis_tables.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/dev/dtrace/i386/dis_tables.c Wed Jul 25 16:45:04 2012 +0300
@@ -18,7 +18,7 @@
*
* CDDL HEADER END
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/cddl/dev/dtrace/i386/dis_tables.c 238169 2012-07-06 14:45:30Z avg $
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
@@ -815,7 +815,7 @@
/* [10] */ TNSZ("movups",XMMO,16), TNSZ("movups",XMMOS,16),TNSZ("movlps",XMMO,8), TNSZ("movlps",XMMOS,8),
/* [14] */ TNSZ("unpcklps",XMMO,16),TNSZ("unpckhps",XMMO,16),TNSZ("movhps",XMMOM,8),TNSZ("movhps",XMMOMS,8),
/* [18] */ IND(dis_op0F18), INVALID, INVALID, INVALID,
-/* [1C] */ INVALID, INVALID, INVALID, INVALID,
+/* [1C] */ INVALID, INVALID, INVALID, TS("nopw", Mw),
}, {
/* [20] */ TSy("mov",SREG), TSy("mov",SREG), TSy("mov",SREG), TSy("mov",SREG),
/* [24] */ TSx("mov",SREG), INVALID, TSx("mov",SREG), INVALID,
@@ -1146,14 +1146,14 @@
/* [1,C] */ TNS("sbbb",IA), TS("sbb",IA), TSx("push",SEG), TSx("pop",SEG),
}, {
/* [2,0] */ TNS("andb",RMw), TS("and",RMw), TNS("andb",MRw), TS("and",MRw),
-/* [2,4] */ TNS("andb",IA), TS("and",IA), TNSx("%es:",OVERRIDE), TNSx("daa",NORM),
+/* [2,4] */ TNS("andb",IA), TS("and",IA), TNS("%es:",OVERRIDE), TNSx("daa",NORM),
/* [2,8] */ TNS("subb",RMw), TS("sub",RMw), TNS("subb",MRw), TS("sub",MRw),
-/* [2,C] */ TNS("subb",IA), TS("sub",IA), TNSx("%cs:",OVERRIDE), TNSx("das",NORM),
+/* [2,C] */ TNS("subb",IA), TS("sub",IA), TNS("%cs:",OVERRIDE), TNSx("das",NORM),
}, {
/* [3,0] */ TNS("xorb",RMw), TS("xor",RMw), TNS("xorb",MRw), TS("xor",MRw),
-/* [3,4] */ TNS("xorb",IA), TS("xor",IA), TNSx("%ss:",OVERRIDE), TNSx("aaa",NORM),
+/* [3,4] */ TNS("xorb",IA), TS("xor",IA), TNS("%ss:",OVERRIDE), TNSx("aaa",NORM),
/* [3,8] */ TNS("cmpb",RMw), TS("cmp",RMw), TNS("cmpb",MRw), TS("cmp",MRw),
-/* [3,C] */ TNS("cmpb",IA), TS("cmp",IA), TNSx("%ds:",OVERRIDE), TNSx("aas",NORM),
+/* [3,C] */ TNS("cmpb",IA), TS("cmp",IA), TNS("%ds:",OVERRIDE), TNSx("aas",NORM),
}, {
/* [4,0] */ TSx("inc",R), TSx("inc",R), TSx("inc",R), TSx("inc",R),
/* [4,4] */ TSx("inc",R), TSx("inc",R), TSx("inc",R), TSx("inc",R),
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/cddl/dev/dtrace/i386/dtrace_subr.c
--- a/head/sys/cddl/dev/dtrace/i386/dtrace_subr.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/cddl/dev/dtrace/i386/dtrace_subr.c Wed Jul 25 16:45:04 2012 +0300
@@ -19,7 +19,7 @@
*
* CDDL HEADER END
*
- * $FreeBSD: head/sys/cddl/dev/dtrace/i386/dtrace_subr.c 223758 2011-07-04 12:04:52Z attilio $
+ * $FreeBSD: head/sys/cddl/dev/dtrace/i386/dtrace_subr.c 238552 2012-07-17 14:36:40Z gnn $
*
*/
/*
@@ -27,6 +27,10 @@
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/types.h>
@@ -45,6 +49,8 @@
extern uintptr_t dtrace_in_probe_addr;
extern int dtrace_in_probe;
+extern void dtrace_getnanotime(struct timespec *tsp);
+
int dtrace_invop(uintptr_t, uintptr_t *, uintptr_t);
typedef struct dtrace_invop_hdlr {
@@ -298,14 +304,15 @@
}
/*
- * If we've executed the original instruction, but haven't performed
- * the jmp back to t->t_dtrace_npc or the clean up of any registers
- * used to emulate %rip-relative instructions in 64-bit mode, do that
- * here and take the signal right away. We detect this condition by
- * seeing if the program counter is the range [scrpc + isz, astpc).
+ * If we have executed the original instruction, but we have performed
+ * neither the jmp back to t->t_dtrace_npc nor the clean up of any
+ * registers used to emulate %rip-relative instructions in 64-bit mode,
+ * we'll save ourselves some effort by doing that here and taking the
+ * signal right away. We detect this condition by seeing if the program
+ * counter is the range [scrpc + isz, astpc).
*/
- if (t->t_dtrace_astpc - rp->r_pc <
- t->t_dtrace_astpc - t->t_dtrace_scrpc - isz) {
+ if (rp->r_pc >= t->t_dtrace_scrpc + isz &&
+ rp->r_pc < t->t_dtrace_astpc) {
#ifdef __amd64
/*
* If there is a scratch register and we're on the
@@ -447,7 +454,7 @@
* (see nsec_scale calculations) taking into account 32-bit shift of
* the higher half and finally add.
*/
- tsc = rdtsc() + tsc_skew[curcpu];
+ tsc = rdtsc() - tsc_skew[curcpu];
lo = tsc;
hi = tsc >> 32;
return (((lo * nsec_scale) >> SCALE_SHIFT) +
@@ -457,8 +464,11 @@
uint64_t
dtrace_gethrestime(void)
{
- printf("%s(%d): XXX\n",__func__,__LINE__);
- return (0);
+ struct timespec current_time;
+
+ dtrace_getnanotime(¤t_time);
+
+ return (current_time.tv_sec * 1000000000ULL + current_time.tv_nsec);
}
/* Function to handle DTrace traps during probes. See i386/i386/trap.c */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/freebsd32/freebsd32.h
--- a/head/sys/compat/freebsd32/freebsd32.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/freebsd32/freebsd32.h Wed Jul 25 16:45:04 2012 +0300
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/compat/freebsd32/freebsd32.h 232449 2012-03-03 08:19:18Z jmallett $
+ * $FreeBSD: head/sys/compat/freebsd32/freebsd32.h 236136 2012-05-27 05:24:53Z kib $
*/
#ifndef _COMPAT_FREEBSD32_FREEBSD32_H_
@@ -306,7 +306,7 @@
u_int ki_estcpu;
u_int ki_slptime;
u_int ki_swtime;
- int ki_spareint1;
+ u_int ki_cow;
u_int64_t ki_runtime;
struct timeval32 ki_start;
struct timeval32 ki_childtime;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/freebsd32/freebsd32_misc.c
--- a/head/sys/compat/freebsd32/freebsd32_misc.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/freebsd32/freebsd32_misc.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/freebsd32/freebsd32_misc.c 232475 2012-03-03 21:39:12Z jmallett $");
+__FBSDID("$FreeBSD: head/sys/compat/freebsd32/freebsd32_misc.c 235886 2012-05-24 08:00:26Z gleb $");
#include "opt_compat.h"
#include "opt_inet.h"
@@ -1528,7 +1528,8 @@
int32_t base32;
int error;
- error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base);
+ error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base,
+ NULL, UIO_USERSPACE);
if (error)
return (error);
if (uap->basep != NULL) {
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/freebsd32/freebsd32_proto.h
--- a/head/sys/compat/freebsd32/freebsd32_proto.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/freebsd32/freebsd32_proto.h Wed Jul 25 16:45:04 2012 +0300
@@ -2,8 +2,8 @@
* System call prototypes.
*
* DO NOT EDIT-- this file is automatically generated.
- * $FreeBSD: head/sys/compat/freebsd32/freebsd32_proto.h 232449 2012-03-03 08:19:18Z jmallett $
- * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 227776 2011-11-21 01:26:10Z lstewart
+ * $FreeBSD: head/sys/compat/freebsd32/freebsd32_proto.h 236027 2012-05-25 21:52:57Z ed $
+ * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 236026 2012-05-25 21:50:48Z ed
*/
#ifndef _FREEBSD32_SYSPROTO_H_
@@ -54,11 +54,11 @@
};
struct freebsd32_recvfrom_args {
char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
- char buf_l_[PADL_(u_int32_t)]; u_int32_t buf; char buf_r_[PADR_(u_int32_t)];
- char len_l_[PADL_(u_int32_t)]; u_int32_t len; char len_r_[PADR_(u_int32_t)];
+ char buf_l_[PADL_(uint32_t)]; uint32_t buf; char buf_r_[PADR_(uint32_t)];
+ char len_l_[PADL_(uint32_t)]; uint32_t len; char len_r_[PADR_(uint32_t)];
char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
- char from_l_[PADL_(u_int32_t)]; u_int32_t from; char from_r_[PADR_(u_int32_t)];
- char fromlenaddr_l_[PADL_(u_int32_t)]; u_int32_t fromlenaddr; char fromlenaddr_r_[PADR_(u_int32_t)];
+ char from_l_[PADL_(uint32_t)]; uint32_t from; char from_r_[PADR_(uint32_t)];
+ char fromlenaddr_l_[PADL_(uint32_t)]; uint32_t fromlenaddr; char fromlenaddr_r_[PADR_(uint32_t)];
};
struct ofreebsd32_sigpending_args {
register_t dummy;
@@ -74,8 +74,8 @@
};
struct freebsd32_execve_args {
char fname_l_[PADL_(char *)]; char * fname; char fname_r_[PADR_(char *)];
- char argv_l_[PADL_(u_int32_t *)]; u_int32_t * argv; char argv_r_[PADR_(u_int32_t *)];
- char envv_l_[PADL_(u_int32_t *)]; u_int32_t * envv; char envv_r_[PADR_(u_int32_t *)];
+ char argv_l_[PADL_(uint32_t *)]; uint32_t * argv; char argv_r_[PADR_(uint32_t *)];
+ char envv_l_[PADL_(uint32_t *)]; uint32_t * envv; char envv_r_[PADR_(uint32_t *)];
};
struct freebsd32_mprotect_args {
char addr_l_[PADL_(const void *)]; const void * addr; char addr_r_[PADR_(const void *)];
@@ -175,9 +175,9 @@
char name_l_[PADL_(int *)]; int * name; char name_r_[PADR_(int *)];
char namelen_l_[PADL_(u_int)]; u_int namelen; char namelen_r_[PADR_(u_int)];
char old_l_[PADL_(void *)]; void * old; char old_r_[PADR_(void *)];
- char oldlenp_l_[PADL_(u_int32_t *)]; u_int32_t * oldlenp; char oldlenp_r_[PADR_(u_int32_t *)];
+ char oldlenp_l_[PADL_(uint32_t *)]; uint32_t * oldlenp; char oldlenp_r_[PADR_(uint32_t *)];
char new_l_[PADL_(void *)]; void * new; char new_r_[PADR_(void *)];
- char newlen_l_[PADL_(u_int32_t)]; u_int32_t newlen; char newlen_r_[PADR_(u_int32_t)];
+ char newlen_l_[PADL_(uint32_t)]; uint32_t newlen; char newlen_r_[PADR_(uint32_t)];
};
struct freebsd32_futimes_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
@@ -232,15 +232,15 @@
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char iovp_l_[PADL_(struct iovec32 *)]; struct iovec32 * iovp; char iovp_r_[PADR_(struct iovec32 *)];
char iovcnt_l_[PADL_(u_int)]; u_int iovcnt; char iovcnt_r_[PADR_(u_int)];
- char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
- char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+ char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
};
struct freebsd32_pwritev_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char iovp_l_[PADL_(struct iovec32 *)]; struct iovec32 * iovp; char iovp_r_[PADR_(struct iovec32 *)];
char iovcnt_l_[PADL_(u_int)]; u_int iovcnt; char iovcnt_r_[PADR_(u_int)];
- char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
- char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+ char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
};
struct freebsd32_modstat_args {
char modid_l_[PADL_(int)]; int modid; char modid_r_[PADR_(int)];
@@ -309,8 +309,8 @@
struct freebsd32_sendfile_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
- char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
- char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+ char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
char nbytes_l_[PADL_(size_t)]; size_t nbytes; char nbytes_r_[PADR_(size_t)];
char hdtr_l_[PADL_(struct sf_hdtr32 *)]; struct sf_hdtr32 * hdtr; char hdtr_r_[PADR_(struct sf_hdtr32 *)];
char sbytes_l_[PADL_(off_t *)]; off_t * sbytes; char sbytes_r_[PADR_(off_t *)];
@@ -404,16 +404,16 @@
char buf_l_[PADL_(void *)]; void * buf; char buf_r_[PADR_(void *)];
char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
- char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+ char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
};
struct freebsd32_pwrite_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char buf_l_[PADL_(const void *)]; const void * buf; char buf_r_[PADR_(const void *)];
char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
- char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+ char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
};
struct freebsd32_mmap_args {
char addr_l_[PADL_(caddr_t)]; caddr_t addr; char addr_r_[PADR_(caddr_t)];
@@ -422,42 +422,42 @@
char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char pos1_l_[PADL_(u_int32_t)]; u_int32_t pos1; char pos1_r_[PADR_(u_int32_t)];
- char pos2_l_[PADL_(u_int32_t)]; u_int32_t pos2; char pos2_r_[PADR_(u_int32_t)];
+ char pos1_l_[PADL_(uint32_t)]; uint32_t pos1; char pos1_r_[PADR_(uint32_t)];
+ char pos2_l_[PADL_(uint32_t)]; uint32_t pos2; char pos2_r_[PADR_(uint32_t)];
};
struct freebsd32_lseek_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
- char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+ char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
char whence_l_[PADL_(int)]; int whence; char whence_r_[PADR_(int)];
};
struct freebsd32_truncate_args {
char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char length1_l_[PADL_(u_int32_t)]; u_int32_t length1; char length1_r_[PADR_(u_int32_t)];
- char length2_l_[PADL_(u_int32_t)]; u_int32_t length2; char length2_r_[PADR_(u_int32_t)];
+ char length1_l_[PADL_(uint32_t)]; uint32_t length1; char length1_r_[PADR_(uint32_t)];
+ char length2_l_[PADL_(uint32_t)]; uint32_t length2; char length2_r_[PADR_(uint32_t)];
};
struct freebsd32_ftruncate_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char length1_l_[PADL_(u_int32_t)]; u_int32_t length1; char length1_r_[PADR_(u_int32_t)];
- char length2_l_[PADL_(u_int32_t)]; u_int32_t length2; char length2_r_[PADR_(u_int32_t)];
+ char length1_l_[PADL_(uint32_t)]; uint32_t length1; char length1_r_[PADR_(uint32_t)];
+ char length2_l_[PADL_(uint32_t)]; uint32_t length2; char length2_r_[PADR_(uint32_t)];
};
#else
struct freebsd32_pread_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char buf_l_[PADL_(void *)]; void * buf; char buf_r_[PADR_(void *)];
char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
- char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
- char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+ char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
};
struct freebsd32_pwrite_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char buf_l_[PADL_(const void *)]; const void * buf; char buf_r_[PADR_(const void *)];
char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
- char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
- char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+ char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
};
struct freebsd32_mmap_args {
char addr_l_[PADL_(caddr_t)]; caddr_t addr; char addr_r_[PADR_(caddr_t)];
@@ -465,69 +465,69 @@
char prot_l_[PADL_(int)]; int prot; char prot_r_[PADR_(int)];
char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
- char pos1_l_[PADL_(u_int32_t)]; u_int32_t pos1; char pos1_r_[PADR_(u_int32_t)];
- char pos2_l_[PADL_(u_int32_t)]; u_int32_t pos2; char pos2_r_[PADR_(u_int32_t)];
+ char pos1_l_[PADL_(uint32_t)]; uint32_t pos1; char pos1_r_[PADR_(uint32_t)];
+ char pos2_l_[PADL_(uint32_t)]; uint32_t pos2; char pos2_r_[PADR_(uint32_t)];
};
struct freebsd32_lseek_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
- char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
- char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+ char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
char whence_l_[PADL_(int)]; int whence; char whence_r_[PADR_(int)];
};
struct freebsd32_truncate_args {
char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
- char length1_l_[PADL_(u_int32_t)]; u_int32_t length1; char length1_r_[PADR_(u_int32_t)];
- char length2_l_[PADL_(u_int32_t)]; u_int32_t length2; char length2_r_[PADR_(u_int32_t)];
+ char length1_l_[PADL_(uint32_t)]; uint32_t length1; char length1_r_[PADR_(uint32_t)];
+ char length2_l_[PADL_(uint32_t)]; uint32_t length2; char length2_r_[PADR_(uint32_t)];
};
struct freebsd32_ftruncate_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
- char length1_l_[PADL_(u_int32_t)]; u_int32_t length1; char length1_r_[PADR_(u_int32_t)];
- char length2_l_[PADL_(u_int32_t)]; u_int32_t length2; char length2_r_[PADR_(u_int32_t)];
+ char length1_l_[PADL_(uint32_t)]; uint32_t length1; char length1_r_[PADR_(uint32_t)];
+ char length2_l_[PADL_(uint32_t)]; uint32_t length2; char length2_r_[PADR_(uint32_t)];
};
#endif
#ifdef PAD64_REQUIRED
struct freebsd32_cpuset_setid_args {
char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char id1_l_[PADL_(u_int32_t)]; u_int32_t id1; char id1_r_[PADR_(u_int32_t)];
- char id2_l_[PADL_(u_int32_t)]; u_int32_t id2; char id2_r_[PADR_(u_int32_t)];
+ char id1_l_[PADL_(uint32_t)]; uint32_t id1; char id1_r_[PADR_(uint32_t)];
+ char id2_l_[PADL_(uint32_t)]; uint32_t id2; char id2_r_[PADR_(uint32_t)];
char setid_l_[PADL_(cpusetid_t)]; cpusetid_t setid; char setid_r_[PADR_(cpusetid_t)];
};
#else
struct freebsd32_cpuset_setid_args {
char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
- char id1_l_[PADL_(u_int32_t)]; u_int32_t id1; char id1_r_[PADR_(u_int32_t)];
- char id2_l_[PADL_(u_int32_t)]; u_int32_t id2; char id2_r_[PADR_(u_int32_t)];
+ char id1_l_[PADL_(uint32_t)]; uint32_t id1; char id1_r_[PADR_(uint32_t)];
+ char id2_l_[PADL_(uint32_t)]; uint32_t id2; char id2_r_[PADR_(uint32_t)];
char setid_l_[PADL_(cpusetid_t)]; cpusetid_t setid; char setid_r_[PADR_(cpusetid_t)];
};
#endif
struct freebsd32_cpuset_getid_args {
char level_l_[PADL_(cpulevel_t)]; cpulevel_t level; char level_r_[PADR_(cpulevel_t)];
char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
- char id1_l_[PADL_(u_int32_t)]; u_int32_t id1; char id1_r_[PADR_(u_int32_t)];
- char id2_l_[PADL_(u_int32_t)]; u_int32_t id2; char id2_r_[PADR_(u_int32_t)];
+ char id1_l_[PADL_(uint32_t)]; uint32_t id1; char id1_r_[PADR_(uint32_t)];
+ char id2_l_[PADL_(uint32_t)]; uint32_t id2; char id2_r_[PADR_(uint32_t)];
char setid_l_[PADL_(cpusetid_t *)]; cpusetid_t * setid; char setid_r_[PADR_(cpusetid_t *)];
};
struct freebsd32_cpuset_getaffinity_args {
char level_l_[PADL_(cpulevel_t)]; cpulevel_t level; char level_r_[PADR_(cpulevel_t)];
char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
- char id1_l_[PADL_(u_int32_t)]; u_int32_t id1; char id1_r_[PADR_(u_int32_t)];
- char id2_l_[PADL_(u_int32_t)]; u_int32_t id2; char id2_r_[PADR_(u_int32_t)];
+ char id1_l_[PADL_(uint32_t)]; uint32_t id1; char id1_r_[PADR_(uint32_t)];
+ char id2_l_[PADL_(uint32_t)]; uint32_t id2; char id2_r_[PADR_(uint32_t)];
char cpusetsize_l_[PADL_(size_t)]; size_t cpusetsize; char cpusetsize_r_[PADR_(size_t)];
char mask_l_[PADL_(cpuset_t *)]; cpuset_t * mask; char mask_r_[PADR_(cpuset_t *)];
};
struct freebsd32_cpuset_setaffinity_args {
char level_l_[PADL_(cpulevel_t)]; cpulevel_t level; char level_r_[PADR_(cpulevel_t)];
char which_l_[PADL_(cpuwhich_t)]; cpuwhich_t which; char which_r_[PADR_(cpuwhich_t)];
- char id1_l_[PADL_(u_int32_t)]; u_int32_t id1; char id1_r_[PADR_(u_int32_t)];
- char id2_l_[PADL_(u_int32_t)]; u_int32_t id2; char id2_r_[PADR_(u_int32_t)];
+ char id1_l_[PADL_(uint32_t)]; uint32_t id1; char id1_r_[PADR_(uint32_t)];
+ char id2_l_[PADL_(uint32_t)]; uint32_t id2; char id2_r_[PADR_(uint32_t)];
char cpusetsize_l_[PADL_(size_t)]; size_t cpusetsize; char cpusetsize_r_[PADR_(size_t)];
char mask_l_[PADL_(const cpuset_t *)]; const cpuset_t * mask; char mask_r_[PADR_(const cpuset_t *)];
};
struct freebsd32_fexecve_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
- char argv_l_[PADL_(u_int32_t *)]; u_int32_t * argv; char argv_r_[PADR_(u_int32_t *)];
- char envv_l_[PADL_(u_int32_t *)]; u_int32_t * envv; char envv_r_[PADR_(u_int32_t *)];
+ char argv_l_[PADL_(uint32_t *)]; uint32_t * argv; char argv_r_[PADR_(uint32_t *)];
+ char envv_l_[PADL_(uint32_t *)]; uint32_t * envv; char envv_r_[PADR_(uint32_t *)];
};
struct freebsd32_fstatat_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
@@ -812,8 +812,8 @@
struct freebsd4_freebsd32_sendfile_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
- char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
- char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+ char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
char nbytes_l_[PADL_(size_t)]; size_t nbytes; char nbytes_r_[PADR_(size_t)];
char hdtr_l_[PADL_(struct sf_hdtr32 *)]; struct sf_hdtr32 * hdtr; char hdtr_r_[PADR_(struct sf_hdtr32 *)];
char sbytes_l_[PADL_(off_t *)]; off_t * sbytes; char sbytes_r_[PADR_(off_t *)];
@@ -854,16 +854,16 @@
char buf_l_[PADL_(void *)]; void * buf; char buf_r_[PADR_(void *)];
char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
- char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+ char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
};
struct freebsd6_freebsd32_pwrite_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char buf_l_[PADL_(const void *)]; const void * buf; char buf_r_[PADR_(const void *)];
char nbyte_l_[PADL_(size_t)]; size_t nbyte; char nbyte_r_[PADR_(size_t)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
- char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+ char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
};
struct freebsd6_freebsd32_mmap_args {
char addr_l_[PADL_(caddr_t)]; caddr_t addr; char addr_r_[PADR_(caddr_t)];
@@ -872,27 +872,27 @@
char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char pos1_l_[PADL_(u_int32_t)]; u_int32_t pos1; char pos1_r_[PADR_(u_int32_t)];
- char pos2_l_[PADL_(u_int32_t)]; u_int32_t pos2; char pos2_r_[PADR_(u_int32_t)];
+ char pos1_l_[PADL_(uint32_t)]; uint32_t pos1; char pos1_r_[PADR_(uint32_t)];
+ char pos2_l_[PADL_(uint32_t)]; uint32_t pos2; char pos2_r_[PADR_(uint32_t)];
};
struct freebsd6_freebsd32_lseek_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char offset1_l_[PADL_(u_int32_t)]; u_int32_t offset1; char offset1_r_[PADR_(u_int32_t)];
- char offset2_l_[PADL_(u_int32_t)]; u_int32_t offset2; char offset2_r_[PADR_(u_int32_t)];
+ char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+ char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
char whence_l_[PADL_(int)]; int whence; char whence_r_[PADR_(int)];
};
struct freebsd6_freebsd32_truncate_args {
char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char length1_l_[PADL_(u_int32_t)]; u_int32_t length1; char length1_r_[PADR_(u_int32_t)];
- char length2_l_[PADL_(u_int32_t)]; u_int32_t length2; char length2_r_[PADR_(u_int32_t)];
+ char length1_l_[PADL_(uint32_t)]; uint32_t length1; char length1_r_[PADR_(uint32_t)];
+ char length2_l_[PADL_(uint32_t)]; uint32_t length2; char length2_r_[PADR_(uint32_t)];
};
struct freebsd6_freebsd32_ftruncate_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
- char length1_l_[PADL_(u_int32_t)]; u_int32_t length1; char length1_r_[PADR_(u_int32_t)];
- char length2_l_[PADL_(u_int32_t)]; u_int32_t length2; char length2_r_[PADR_(u_int32_t)];
+ char length1_l_[PADL_(uint32_t)]; uint32_t length1; char length1_r_[PADR_(uint32_t)];
+ char length2_l_[PADL_(uint32_t)]; uint32_t length2; char length2_r_[PADR_(uint32_t)];
};
#ifdef PAD64_REQUIRED
#else
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/freebsd32/freebsd32_syscall.h
--- a/head/sys/compat/freebsd32/freebsd32_syscall.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/freebsd32/freebsd32_syscall.h Wed Jul 25 16:45:04 2012 +0300
@@ -2,8 +2,8 @@
* System call numbers.
*
* DO NOT EDIT-- this file is automatically generated.
- * $FreeBSD: head/sys/compat/freebsd32/freebsd32_syscall.h 232449 2012-03-03 08:19:18Z jmallett $
- * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 227776 2011-11-21 01:26:10Z lstewart
+ * $FreeBSD: head/sys/compat/freebsd32/freebsd32_syscall.h 236027 2012-05-25 21:52:57Z ed $
+ * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 236026 2012-05-25 21:50:48Z ed
*/
#define FREEBSD32_SYS_syscall 0
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/freebsd32/freebsd32_syscalls.c
--- a/head/sys/compat/freebsd32/freebsd32_syscalls.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/freebsd32/freebsd32_syscalls.c Wed Jul 25 16:45:04 2012 +0300
@@ -2,8 +2,8 @@
* System call names.
*
* DO NOT EDIT-- this file is automatically generated.
- * $FreeBSD: head/sys/compat/freebsd32/freebsd32_syscalls.c 232449 2012-03-03 08:19:18Z jmallett $
- * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 227776 2011-11-21 01:26:10Z lstewart
+ * $FreeBSD: head/sys/compat/freebsd32/freebsd32_syscalls.c 236027 2012-05-25 21:52:57Z ed $
+ * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 236026 2012-05-25 21:50:48Z ed
*/
const char *freebsd32_syscallnames[] = {
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/freebsd32/freebsd32_sysent.c
--- a/head/sys/compat/freebsd32/freebsd32_sysent.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/freebsd32/freebsd32_sysent.c Wed Jul 25 16:45:04 2012 +0300
@@ -2,8 +2,8 @@
* System call switch table.
*
* DO NOT EDIT-- this file is automatically generated.
- * $FreeBSD: head/sys/compat/freebsd32/freebsd32_sysent.c 232449 2012-03-03 08:19:18Z jmallett $
- * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 227776 2011-11-21 01:26:10Z lstewart
+ * $FreeBSD: head/sys/compat/freebsd32/freebsd32_sysent.c 236027 2012-05-25 21:52:57Z ed $
+ * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 236026 2012-05-25 21:50:48Z ed
*/
#include "opt_compat.h"
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/freebsd32/freebsd32_systrace_args.c
--- a/head/sys/compat/freebsd32/freebsd32_systrace_args.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/freebsd32/freebsd32_systrace_args.c Wed Jul 25 16:45:04 2012 +0300
@@ -2,7 +2,7 @@
* System call argument to DTrace register array converstion.
*
* DO NOT EDIT-- this file is automatically generated.
- * $FreeBSD: head/sys/compat/freebsd32/freebsd32_systrace_args.c 232449 2012-03-03 08:19:18Z jmallett $
+ * $FreeBSD: head/sys/compat/freebsd32/freebsd32_systrace_args.c 236027 2012-05-25 21:52:57Z ed $
* This file is part of the DTrace syscall provider.
*/
@@ -209,11 +209,11 @@
case 29: {
struct freebsd32_recvfrom_args *p = params;
iarg[0] = p->s; /* int */
- uarg[1] = p->buf; /* u_int32_t */
- uarg[2] = p->len; /* u_int32_t */
+ uarg[1] = p->buf; /* uint32_t */
+ uarg[2] = p->len; /* uint32_t */
iarg[3] = p->flags; /* int */
- uarg[4] = p->from; /* u_int32_t */
- uarg[5] = p->fromlenaddr; /* u_int32_t */
+ uarg[4] = p->from; /* uint32_t */
+ uarg[5] = p->fromlenaddr; /* uint32_t */
*n_args = 6;
break;
}
@@ -402,8 +402,8 @@
case 59: {
struct freebsd32_execve_args *p = params;
uarg[0] = (intptr_t) p->fname; /* char * */
- uarg[1] = (intptr_t) p->argv; /* u_int32_t * */
- uarg[2] = (intptr_t) p->envv; /* u_int32_t * */
+ uarg[1] = (intptr_t) p->argv; /* uint32_t * */
+ uarg[2] = (intptr_t) p->envv; /* uint32_t * */
*n_args = 3;
break;
}
@@ -996,9 +996,9 @@
uarg[0] = (intptr_t) p->name; /* int * */
uarg[1] = p->namelen; /* u_int */
uarg[2] = (intptr_t) p->old; /* void * */
- uarg[3] = (intptr_t) p->oldlenp; /* u_int32_t * */
+ uarg[3] = (intptr_t) p->oldlenp; /* uint32_t * */
uarg[4] = (intptr_t) p->new; /* void * */
- uarg[5] = p->newlen; /* u_int32_t */
+ uarg[5] = p->newlen; /* uint32_t */
*n_args = 6;
break;
}
@@ -1360,8 +1360,8 @@
iarg[0] = p->fd; /* int */
uarg[1] = (intptr_t) p->iovp; /* struct iovec32 * */
uarg[2] = p->iovcnt; /* u_int */
- uarg[3] = p->offset1; /* u_int32_t */
- uarg[4] = p->offset2; /* u_int32_t */
+ uarg[3] = p->offset1; /* uint32_t */
+ uarg[4] = p->offset2; /* uint32_t */
*n_args = 5;
break;
}
@@ -1371,8 +1371,8 @@
iarg[0] = p->fd; /* int */
uarg[1] = (intptr_t) p->iovp; /* struct iovec32 * */
uarg[2] = p->iovcnt; /* u_int */
- uarg[3] = p->offset1; /* u_int32_t */
- uarg[4] = p->offset2; /* u_int32_t */
+ uarg[3] = p->offset1; /* uint32_t */
+ uarg[4] = p->offset2; /* uint32_t */
*n_args = 5;
break;
}
@@ -1933,8 +1933,8 @@
struct freebsd32_sendfile_args *p = params;
iarg[0] = p->fd; /* int */
iarg[1] = p->s; /* int */
- uarg[2] = p->offset1; /* u_int32_t */
- uarg[3] = p->offset2; /* u_int32_t */
+ uarg[2] = p->offset1; /* uint32_t */
+ uarg[3] = p->offset2; /* uint32_t */
uarg[4] = p->nbytes; /* size_t */
uarg[5] = (intptr_t) p->hdtr; /* struct sf_hdtr32 * */
uarg[6] = (intptr_t) p->sbytes; /* off_t * */
@@ -2500,8 +2500,8 @@
uarg[1] = (intptr_t) p->buf; /* void * */
uarg[2] = p->nbyte; /* size_t */
iarg[3] = p->pad; /* int */
- uarg[4] = p->offset1; /* u_int32_t */
- uarg[5] = p->offset2; /* u_int32_t */
+ uarg[4] = p->offset1; /* uint32_t */
+ uarg[5] = p->offset2; /* uint32_t */
*n_args = 6;
break;
}
@@ -2512,8 +2512,8 @@
uarg[1] = (intptr_t) p->buf; /* const void * */
uarg[2] = p->nbyte; /* size_t */
iarg[3] = p->pad; /* int */
- uarg[4] = p->offset1; /* u_int32_t */
- uarg[5] = p->offset2; /* u_int32_t */
+ uarg[4] = p->offset1; /* uint32_t */
+ uarg[5] = p->offset2; /* uint32_t */
*n_args = 6;
break;
}
@@ -2526,8 +2526,8 @@
iarg[3] = p->flags; /* int */
iarg[4] = p->fd; /* int */
iarg[5] = p->pad; /* int */
- uarg[6] = p->pos1; /* u_int32_t */
- uarg[7] = p->pos2; /* u_int32_t */
+ uarg[6] = p->pos1; /* uint32_t */
+ uarg[7] = p->pos2; /* uint32_t */
*n_args = 8;
break;
}
@@ -2536,8 +2536,8 @@
struct freebsd32_lseek_args *p = params;
iarg[0] = p->fd; /* int */
iarg[1] = p->pad; /* int */
- uarg[2] = p->offset1; /* u_int32_t */
- uarg[3] = p->offset2; /* u_int32_t */
+ uarg[2] = p->offset1; /* uint32_t */
+ uarg[3] = p->offset2; /* uint32_t */
iarg[4] = p->whence; /* int */
*n_args = 5;
break;
@@ -2547,8 +2547,8 @@
struct freebsd32_truncate_args *p = params;
uarg[0] = (intptr_t) p->path; /* char * */
iarg[1] = p->pad; /* int */
- uarg[2] = p->length1; /* u_int32_t */
- uarg[3] = p->length2; /* u_int32_t */
+ uarg[2] = p->length1; /* uint32_t */
+ uarg[3] = p->length2; /* uint32_t */
*n_args = 4;
break;
}
@@ -2557,8 +2557,8 @@
struct freebsd32_ftruncate_args *p = params;
iarg[0] = p->fd; /* int */
iarg[1] = p->pad; /* int */
- uarg[2] = p->length1; /* u_int32_t */
- uarg[3] = p->length2; /* u_int32_t */
+ uarg[2] = p->length1; /* uint32_t */
+ uarg[3] = p->length2; /* uint32_t */
*n_args = 4;
break;
}
@@ -2569,8 +2569,8 @@
iarg[0] = p->fd; /* int */
uarg[1] = (intptr_t) p->buf; /* void * */
uarg[2] = p->nbyte; /* size_t */
- uarg[3] = p->offset1; /* u_int32_t */
- uarg[4] = p->offset2; /* u_int32_t */
+ uarg[3] = p->offset1; /* uint32_t */
+ uarg[4] = p->offset2; /* uint32_t */
*n_args = 5;
break;
}
@@ -2580,8 +2580,8 @@
iarg[0] = p->fd; /* int */
uarg[1] = (intptr_t) p->buf; /* const void * */
uarg[2] = p->nbyte; /* size_t */
- uarg[3] = p->offset1; /* u_int32_t */
- uarg[4] = p->offset2; /* u_int32_t */
+ uarg[3] = p->offset1; /* uint32_t */
+ uarg[4] = p->offset2; /* uint32_t */
*n_args = 5;
break;
}
@@ -2593,8 +2593,8 @@
iarg[2] = p->prot; /* int */
iarg[3] = p->flags; /* int */
iarg[4] = p->fd; /* int */
- uarg[5] = p->pos1; /* u_int32_t */
- uarg[6] = p->pos2; /* u_int32_t */
+ uarg[5] = p->pos1; /* uint32_t */
+ uarg[6] = p->pos2; /* uint32_t */
*n_args = 7;
break;
}
@@ -2602,8 +2602,8 @@
case 478: {
struct freebsd32_lseek_args *p = params;
iarg[0] = p->fd; /* int */
- uarg[1] = p->offset1; /* u_int32_t */
- uarg[2] = p->offset2; /* u_int32_t */
+ uarg[1] = p->offset1; /* uint32_t */
+ uarg[2] = p->offset2; /* uint32_t */
iarg[3] = p->whence; /* int */
*n_args = 4;
break;
@@ -2612,8 +2612,8 @@
case 479: {
struct freebsd32_truncate_args *p = params;
uarg[0] = (intptr_t) p->path; /* char * */
- uarg[1] = p->length1; /* u_int32_t */
- uarg[2] = p->length2; /* u_int32_t */
+ uarg[1] = p->length1; /* uint32_t */
+ uarg[2] = p->length2; /* uint32_t */
*n_args = 3;
break;
}
@@ -2621,8 +2621,8 @@
case 480: {
struct freebsd32_ftruncate_args *p = params;
iarg[0] = p->fd; /* int */
- uarg[1] = p->length1; /* u_int32_t */
- uarg[2] = p->length2; /* u_int32_t */
+ uarg[1] = p->length1; /* uint32_t */
+ uarg[2] = p->length2; /* uint32_t */
*n_args = 3;
break;
}
@@ -2665,8 +2665,8 @@
struct freebsd32_cpuset_setid_args *p = params;
iarg[0] = p->which; /* cpuwhich_t */
iarg[1] = p->pad; /* int */
- uarg[2] = p->id1; /* u_int32_t */
- uarg[3] = p->id2; /* u_int32_t */
+ uarg[2] = p->id1; /* uint32_t */
+ uarg[3] = p->id2; /* uint32_t */
iarg[4] = p->setid; /* cpusetid_t */
*n_args = 5;
break;
@@ -2676,8 +2676,8 @@
case 485: {
struct freebsd32_cpuset_setid_args *p = params;
iarg[0] = p->which; /* cpuwhich_t */
- uarg[1] = p->id1; /* u_int32_t */
- uarg[2] = p->id2; /* u_int32_t */
+ uarg[1] = p->id1; /* uint32_t */
+ uarg[2] = p->id2; /* uint32_t */
iarg[3] = p->setid; /* cpusetid_t */
*n_args = 4;
break;
@@ -2688,8 +2688,8 @@
struct freebsd32_cpuset_getid_args *p = params;
iarg[0] = p->level; /* cpulevel_t */
iarg[1] = p->which; /* cpuwhich_t */
- uarg[2] = p->id1; /* u_int32_t */
- uarg[3] = p->id2; /* u_int32_t */
+ uarg[2] = p->id1; /* uint32_t */
+ uarg[3] = p->id2; /* uint32_t */
uarg[4] = (intptr_t) p->setid; /* cpusetid_t * */
*n_args = 5;
break;
@@ -2699,8 +2699,8 @@
struct freebsd32_cpuset_getaffinity_args *p = params;
iarg[0] = p->level; /* cpulevel_t */
iarg[1] = p->which; /* cpuwhich_t */
- uarg[2] = p->id1; /* u_int32_t */
- uarg[3] = p->id2; /* u_int32_t */
+ uarg[2] = p->id1; /* uint32_t */
+ uarg[3] = p->id2; /* uint32_t */
uarg[4] = p->cpusetsize; /* size_t */
uarg[5] = (intptr_t) p->mask; /* cpuset_t * */
*n_args = 6;
@@ -2711,8 +2711,8 @@
struct freebsd32_cpuset_setaffinity_args *p = params;
iarg[0] = p->level; /* cpulevel_t */
iarg[1] = p->which; /* cpuwhich_t */
- uarg[2] = p->id1; /* u_int32_t */
- uarg[3] = p->id2; /* u_int32_t */
+ uarg[2] = p->id1; /* uint32_t */
+ uarg[3] = p->id2; /* uint32_t */
uarg[4] = p->cpusetsize; /* size_t */
uarg[5] = (intptr_t) p->mask; /* const cpuset_t * */
*n_args = 6;
@@ -2753,8 +2753,8 @@
case 492: {
struct freebsd32_fexecve_args *p = params;
iarg[0] = p->fd; /* int */
- uarg[1] = (intptr_t) p->argv; /* u_int32_t * */
- uarg[2] = (intptr_t) p->envv; /* u_int32_t * */
+ uarg[1] = (intptr_t) p->argv; /* uint32_t * */
+ uarg[2] = (intptr_t) p->envv; /* uint32_t * */
*n_args = 3;
break;
}
@@ -2943,7 +2943,7 @@
case 514: {
struct cap_new_args *p = params;
iarg[0] = p->fd; /* int */
- uarg[1] = p->rights; /* u_int64_t */
+ uarg[1] = p->rights; /* uint64_t */
*n_args = 2;
break;
}
@@ -2951,7 +2951,7 @@
case 515: {
struct cap_getrights_args *p = params;
iarg[0] = p->fd; /* int */
- uarg[1] = (intptr_t) p->rightsp; /* u_int64_t * */
+ uarg[1] = (intptr_t) p->rightsp; /* uint64_t * */
*n_args = 2;
break;
}
@@ -3380,19 +3380,19 @@
p = "int";
break;
case 1:
- p = "u_int32_t";
- break;
- case 2:
- p = "u_int32_t";
+ p = "uint32_t";
+ break;
+ case 2:
+ p = "uint32_t";
break;
case 3:
p = "int";
break;
case 4:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 5:
- p = "u_int32_t";
+ p = "uint32_t";
break;
default:
break;
@@ -3679,10 +3679,10 @@
p = "char *";
break;
case 1:
- p = "u_int32_t *";
- break;
- case 2:
- p = "u_int32_t *";
+ p = "uint32_t *";
+ break;
+ case 2:
+ p = "uint32_t *";
break;
default:
break;
@@ -4664,13 +4664,13 @@
p = "void *";
break;
case 3:
- p = "u_int32_t *";
+ p = "uint32_t *";
break;
case 4:
p = "void *";
break;
case 5:
- p = "u_int32_t";
+ p = "uint32_t";
break;
default:
break;
@@ -5217,10 +5217,10 @@
p = "u_int";
break;
case 3:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 4:
- p = "u_int32_t";
+ p = "uint32_t";
break;
default:
break;
@@ -5239,10 +5239,10 @@
p = "u_int";
break;
case 3:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 4:
- p = "u_int32_t";
+ p = "uint32_t";
break;
default:
break;
@@ -6162,10 +6162,10 @@
p = "int";
break;
case 2:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 3:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 4:
p = "size_t";
@@ -7135,10 +7135,10 @@
p = "int";
break;
case 4:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 5:
- p = "u_int32_t";
+ p = "uint32_t";
break;
default:
break;
@@ -7160,10 +7160,10 @@
p = "int";
break;
case 4:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 5:
- p = "u_int32_t";
+ p = "uint32_t";
break;
default:
break;
@@ -7191,10 +7191,10 @@
p = "int";
break;
case 6:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 7:
- p = "u_int32_t";
+ p = "uint32_t";
break;
default:
break;
@@ -7210,10 +7210,10 @@
p = "int";
break;
case 2:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 3:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 4:
p = "int";
@@ -7232,10 +7232,10 @@
p = "int";
break;
case 2:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 3:
- p = "u_int32_t";
+ p = "uint32_t";
break;
default:
break;
@@ -7251,10 +7251,10 @@
p = "int";
break;
case 2:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 3:
- p = "u_int32_t";
+ p = "uint32_t";
break;
default:
break;
@@ -7274,10 +7274,10 @@
p = "size_t";
break;
case 3:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 4:
- p = "u_int32_t";
+ p = "uint32_t";
break;
default:
break;
@@ -7296,10 +7296,10 @@
p = "size_t";
break;
case 3:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 4:
- p = "u_int32_t";
+ p = "uint32_t";
break;
default:
break;
@@ -7324,10 +7324,10 @@
p = "int";
break;
case 5:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 6:
- p = "u_int32_t";
+ p = "uint32_t";
break;
default:
break;
@@ -7340,10 +7340,10 @@
p = "int";
break;
case 1:
- p = "u_int32_t";
- break;
- case 2:
- p = "u_int32_t";
+ p = "uint32_t";
+ break;
+ case 2:
+ p = "uint32_t";
break;
case 3:
p = "int";
@@ -7359,10 +7359,10 @@
p = "char *";
break;
case 1:
- p = "u_int32_t";
- break;
- case 2:
- p = "u_int32_t";
+ p = "uint32_t";
+ break;
+ case 2:
+ p = "uint32_t";
break;
default:
break;
@@ -7375,10 +7375,10 @@
p = "int";
break;
case 1:
- p = "u_int32_t";
- break;
- case 2:
- p = "u_int32_t";
+ p = "uint32_t";
+ break;
+ case 2:
+ p = "uint32_t";
break;
default:
break;
@@ -7448,10 +7448,10 @@
p = "int";
break;
case 2:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 3:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 4:
p = "cpusetid_t";
@@ -7468,10 +7468,10 @@
p = "cpuwhich_t";
break;
case 1:
- p = "u_int32_t";
- break;
- case 2:
- p = "u_int32_t";
+ p = "uint32_t";
+ break;
+ case 2:
+ p = "uint32_t";
break;
case 3:
p = "cpusetid_t";
@@ -7491,10 +7491,10 @@
p = "cpuwhich_t";
break;
case 2:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 3:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 4:
p = "cpusetid_t *";
@@ -7513,10 +7513,10 @@
p = "cpuwhich_t";
break;
case 2:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 3:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 4:
p = "size_t";
@@ -7538,10 +7538,10 @@
p = "cpuwhich_t";
break;
case 2:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 3:
- p = "u_int32_t";
+ p = "uint32_t";
break;
case 4:
p = "size_t";
@@ -7620,10 +7620,10 @@
p = "int";
break;
case 1:
- p = "u_int32_t *";
- break;
- case 2:
- p = "u_int32_t *";
+ p = "uint32_t *";
+ break;
+ case 2:
+ p = "uint32_t *";
break;
default:
break;
@@ -7959,7 +7959,7 @@
p = "int";
break;
case 1:
- p = "u_int64_t";
+ p = "uint64_t";
break;
default:
break;
@@ -7972,7 +7972,7 @@
p = "int";
break;
case 1:
- p = "u_int64_t *";
+ p = "uint64_t *";
break;
default:
break;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/freebsd32/syscalls.master
--- a/head/sys/compat/freebsd32/syscalls.master Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/freebsd32/syscalls.master Wed Jul 25 16:45:04 2012 +0300
@@ -1,4 +1,4 @@
- $FreeBSD: head/sys/compat/freebsd32/syscalls.master 232449 2012-03-03 08:19:18Z jmallett $
+ $FreeBSD: head/sys/compat/freebsd32/syscalls.master 236026 2012-05-25 21:50:48Z ed $
; from: @(#)syscalls.master 8.2 (Berkeley) 1/13/94
; from: src/sys/kern/syscalls.master 1.107
;
@@ -104,9 +104,9 @@
int flags); }
28 AUE_SENDMSG STD { int freebsd32_sendmsg(int s, struct msghdr32 *msg, \
int flags); }
-29 AUE_RECVFROM STD { int freebsd32_recvfrom(int s, u_int32_t buf, \
- u_int32_t len, int flags, u_int32_t from, \
- u_int32_t fromlenaddr); }
+29 AUE_RECVFROM STD { int freebsd32_recvfrom(int s, uint32_t buf, \
+ uint32_t len, int flags, uint32_t from, \
+ uint32_t fromlenaddr); }
30 AUE_ACCEPT NOPROTO { int accept(int s, caddr_t name, \
int *anamelen); }
31 AUE_GETPEERNAME NOPROTO { int getpeername(int fdes, caddr_t asa, \
@@ -152,7 +152,7 @@
58 AUE_READLINK NOPROTO { ssize_t readlink(char *path, char *buf, \
size_t count); }
59 AUE_EXECVE STD { int freebsd32_execve(char *fname, \
- u_int32_t *argv, u_int32_t *envv); }
+ uint32_t *argv, uint32_t *envv); }
60 AUE_UMASK NOPROTO { int umask(int newmask); } umask \
umask_args int
61 AUE_CHROOT NOPROTO { int chroot(char *path); }
@@ -325,10 +325,10 @@
172 AUE_NULL UNIMPL nosys
173 AUE_PREAD COMPAT6 { ssize_t freebsd32_pread(int fd, void *buf, \
size_t nbyte, int pad, \
- u_int32_t offset1, u_int32_t offset2); }
+ uint32_t offset1, uint32_t offset2); }
174 AUE_PWRITE COMPAT6 { ssize_t freebsd32_pwrite(int fd, \
const void *buf, size_t nbyte, int pad, \
- u_int32_t offset1, u_int32_t offset2); }
+ uint32_t offset1, uint32_t offset2); }
175 AUE_NULL UNIMPL nosys
176 AUE_NTP_ADJTIME NOPROTO { int ntp_adjtime(struct timex *tp); }
177 AUE_NULL UNIMPL sfork (BSD/OS 2.x)
@@ -363,21 +363,21 @@
char *buf, u_int count, int32_t *basep); }
197 AUE_MMAP COMPAT6 { caddr_t freebsd32_mmap(caddr_t addr, \
size_t len, int prot, int flags, int fd, \
- int pad, u_int32_t pos1, u_int32_t pos2); }
+ int pad, uint32_t pos1, uint32_t pos2); }
198 AUE_NULL NOPROTO { int nosys(void); } __syscall \
__syscall_args int
199 AUE_LSEEK COMPAT6 { off_t freebsd32_lseek(int fd, int pad, \
- u_int32_t offset1, u_int32_t offset2, \
+ uint32_t offset1, uint32_t offset2, \
int whence); }
200 AUE_TRUNCATE COMPAT6 { int freebsd32_truncate(char *path, \
- int pad, u_int32_t length1, \
- u_int32_t length2); }
+ int pad, uint32_t length1, \
+ uint32_t length2); }
201 AUE_FTRUNCATE COMPAT6 { int freebsd32_ftruncate(int fd, int pad, \
- u_int32_t length1, u_int32_t length2); }
+ uint32_t length1, uint32_t length2); }
202 AUE_SYSCTL STD { int freebsd32_sysctl(int *name, \
u_int namelen, void *old, \
- u_int32_t *oldlenp, void *new, \
- u_int32_t newlen); }
+ uint32_t *oldlenp, void *new, \
+ uint32_t newlen); }
203 AUE_MLOCK NOPROTO { int mlock(const void *addr, \
size_t len); }
204 AUE_MUNLOCK NOPROTO { int munlock(const void *addr, \
@@ -513,11 +513,11 @@
289 AUE_PREADV STD { ssize_t freebsd32_preadv(int fd, \
struct iovec32 *iovp, \
u_int iovcnt, \
- u_int32_t offset1, u_int32_t offset2); }
+ uint32_t offset1, uint32_t offset2); }
290 AUE_PWRITEV STD { ssize_t freebsd32_pwritev(int fd, \
struct iovec32 *iovp, \
u_int iovcnt, \
- u_int32_t offset1, u_int32_t offset2); }
+ uint32_t offset1, uint32_t offset2); }
291 AUE_NULL UNIMPL nosys
292 AUE_NULL UNIMPL nosys
293 AUE_NULL UNIMPL nosys
@@ -591,7 +591,7 @@
struct timespec *interval); }
335 AUE_NULL NOPROTO { int utrace(const void *addr, size_t len); }
336 AUE_SENDFILE COMPAT4 { int freebsd32_sendfile(int fd, int s, \
- u_int32_t offset1, u_int32_t offset2, \
+ uint32_t offset1, uint32_t offset2, \
size_t nbytes, struct sf_hdtr32 *hdtr, \
off_t *sbytes, int flags); }
337 AUE_NULL NOPROTO { int kldsym(int fileid, int cmd, \
@@ -694,7 +694,7 @@
392 AUE_NULL NOPROTO { int uuidgen(struct uuid *store, \
int count); }
393 AUE_SENDFILE STD { int freebsd32_sendfile(int fd, int s, \
- u_int32_t offset1, u_int32_t offset2, \
+ uint32_t offset1, uint32_t offset2, \
size_t nbytes, struct sf_hdtr32 *hdtr, \
off_t *sbytes, int flags); }
394 AUE_NULL UNIMPL mac_syscall
@@ -847,42 +847,42 @@
475 AUE_PREAD STD { ssize_t freebsd32_pread(int fd, \
void *buf,size_t nbyte, \
int pad, \
- u_int32_t offset1, u_int32_t offset2); }
+ uint32_t offset1, uint32_t offset2); }
476 AUE_PWRITE STD { ssize_t freebsd32_pwrite(int fd, \
const void *buf, size_t nbyte, \
int pad, \
- u_int32_t offset1, u_int32_t offset2); }
+ uint32_t offset1, uint32_t offset2); }
477 AUE_MMAP STD { caddr_t freebsd32_mmap(caddr_t addr, \
size_t len, int prot, int flags, int fd, \
int pad, \
- u_int32_t pos1, u_int32_t pos2); }
+ uint32_t pos1, uint32_t pos2); }
478 AUE_LSEEK STD { off_t freebsd32_lseek(int fd, \
int pad, \
- u_int32_t offset1, u_int32_t offset2, \
+ uint32_t offset1, uint32_t offset2, \
int whence); }
479 AUE_TRUNCATE STD { int freebsd32_truncate(char *path, \
int pad, \
- u_int32_t length1, u_int32_t length2); }
+ uint32_t length1, uint32_t length2); }
480 AUE_FTRUNCATE STD { int freebsd32_ftruncate(int fd, \
int pad, \
- u_int32_t length1, u_int32_t length2); }
+ uint32_t length1, uint32_t length2); }
#else
475 AUE_PREAD STD { ssize_t freebsd32_pread(int fd, \
void *buf,size_t nbyte, \
- u_int32_t offset1, u_int32_t offset2); }
+ uint32_t offset1, uint32_t offset2); }
476 AUE_PWRITE STD { ssize_t freebsd32_pwrite(int fd, \
const void *buf, size_t nbyte, \
- u_int32_t offset1, u_int32_t offset2); }
+ uint32_t offset1, uint32_t offset2); }
477 AUE_MMAP STD { caddr_t freebsd32_mmap(caddr_t addr, \
size_t len, int prot, int flags, int fd, \
- u_int32_t pos1, u_int32_t pos2); }
+ uint32_t pos1, uint32_t pos2); }
478 AUE_LSEEK STD { off_t freebsd32_lseek(int fd, \
- u_int32_t offset1, u_int32_t offset2, \
+ uint32_t offset1, uint32_t offset2, \
int whence); }
479 AUE_TRUNCATE STD { int freebsd32_truncate(char *path, \
- u_int32_t length1, u_int32_t length2); }
+ uint32_t length1, uint32_t length2); }
480 AUE_FTRUNCATE STD { int freebsd32_ftruncate(int fd, \
- u_int32_t length1, u_int32_t length2); }
+ uint32_t length1, uint32_t length2); }
#endif
481 AUE_KILL NOPROTO { int thr_kill2(pid_t pid, long id, int sig); }
482 AUE_SHMOPEN NOPROTO { int shm_open(const char *path, int flags, \
@@ -892,25 +892,25 @@
#ifdef PAD64_REQUIRED
485 AUE_NULL STD { int freebsd32_cpuset_setid(cpuwhich_t which, \
int pad, \
- u_int32_t id1, u_int32_t id2, \
+ uint32_t id1, uint32_t id2, \
cpusetid_t setid); }
#else
485 AUE_NULL STD { int freebsd32_cpuset_setid(cpuwhich_t which, \
- u_int32_t id1, u_int32_t id2, \
+ uint32_t id1, uint32_t id2, \
cpusetid_t setid); }
#endif
486 AUE_NULL STD { int freebsd32_cpuset_getid(cpulevel_t level, \
cpuwhich_t which, \
- u_int32_t id1, u_int32_t id2, \
+ uint32_t id1, uint32_t id2, \
cpusetid_t *setid); }
487 AUE_NULL STD { int freebsd32_cpuset_getaffinity( \
cpulevel_t level, cpuwhich_t which, \
- u_int32_t id1, u_int32_t id2, \
+ uint32_t id1, uint32_t id2, \
size_t cpusetsize, \
cpuset_t *mask); }
488 AUE_NULL STD { int freebsd32_cpuset_setaffinity( \
cpulevel_t level, cpuwhich_t which, \
- u_int32_t id1, u_int32_t id2, \
+ uint32_t id1, uint32_t id2, \
size_t cpusetsize, \
const cpuset_t *mask); }
489 AUE_FACCESSAT NOPROTO { int faccessat(int fd, char *path, int amode, \
@@ -920,7 +920,7 @@
491 AUE_FCHOWNAT NOPROTO { int fchownat(int fd, char *path, uid_t uid, \
gid_t gid, int flag); }
492 AUE_FEXECVE STD { int freebsd32_fexecve(int fd, \
- u_int32_t *argv, u_int32_t *envv); }
+ uint32_t *argv, uint32_t *envv); }
493 AUE_FSTATAT STD { int freebsd32_fstatat(int fd, char *path, \
struct stat *buf, int flag); }
494 AUE_FUTIMESAT STD { int freebsd32_futimesat(int fd, char *path, \
@@ -959,9 +959,9 @@
512 AUE_SHMCTL NOSTD { int freebsd32_shmctl(int shmid, int cmd, \
struct shmid_ds32 *buf); }
513 AUE_LPATHCONF NOPROTO { int lpathconf(char *path, int name); }
-514 AUE_CAP_NEW NOPROTO { int cap_new(int fd, u_int64_t rights); }
+514 AUE_CAP_NEW NOPROTO { int cap_new(int fd, uint64_t rights); }
515 AUE_CAP_GETRIGHTS NOPROTO { int cap_getrights(int fd, \
- u_int64_t *rightsp); }
+ uint64_t *rightsp); }
516 AUE_CAP_ENTER NOPROTO { int cap_enter(void); }
517 AUE_CAP_GETMODE NOPROTO { int cap_getmode(u_int *modep); }
518 AUE_PDFORK UNIMPL pdfork
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/ia32/ia32_sysvec.c
--- a/head/sys/compat/ia32/ia32_sysvec.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/ia32/ia32_sysvec.c Wed Jul 25 16:45:04 2012 +0300
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/ia32/ia32_sysvec.c 233127 2012-03-18 19:15:11Z tijl $");
+__FBSDID("$FreeBSD: head/sys/compat/ia32/ia32_sysvec.c 238687 2012-07-22 13:41:45Z kib $");
#include "opt_compat.h"
@@ -117,7 +117,7 @@
.sv_imgact_try = NULL,
.sv_minsigstksz = MINSIGSTKSZ,
.sv_pagesize = IA32_PAGE_SIZE,
- .sv_minuser = 0,
+ .sv_minuser = FREEBSD32_MINUSER,
.sv_maxuser = FREEBSD32_MAXUSER,
.sv_usrstack = FREEBSD32_USRSTACK,
.sv_psstrings = FREEBSD32_PS_STRINGS,
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/ia32/ia32_util.h
--- a/head/sys/compat/ia32/ia32_util.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/ia32/ia32_util.h Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: head/sys/compat/ia32/ia32_util.h 220238 2011-04-01 11:16:29Z kib $
+ * $FreeBSD: head/sys/compat/ia32/ia32_util.h 238687 2012-07-22 13:41:45Z kib $
*/
#ifndef _COMPAT_IA32_IA32_UTIL_H
@@ -35,29 +35,30 @@
#include <vm/vm_param.h>
#include <vm/pmap.h>
-
#include <sys/exec.h>
#include <sys/sysent.h>
#include <sys/cdefs.h>
#ifdef __ia64__
-#define FREEBSD32_MAXUSER ((1ul << 32) - IA32_PAGE_SIZE * 2)
+#define FREEBSD32_MAXUSER ((1ul << 32) - IA32_PAGE_SIZE * 2)
+#define FREEBSD32_MINUSER 0
#define FREEBSD32_SHAREDPAGE 0
-#define FREEBSD32_USRSTACK FREEBSD32_MAXUSER
-#else
+#define FREEBSD32_USRSTACK FREEBSD32_MAXUSER
+#else /* __ia64__ */
#define FREEBSD32_MAXUSER ((1ul << 32) - IA32_PAGE_SIZE)
+#define FREEBSD32_MINUSER 0
#define FREEBSD32_SHAREDPAGE (FREEBSD32_MAXUSER - IA32_PAGE_SIZE)
-#define FREEBSD32_USRSTACK FREEBSD32_SHAREDPAGE
-#endif
+#define FREEBSD32_USRSTACK FREEBSD32_SHAREDPAGE
+#endif /* __ia64 */
#define IA32_PAGE_SIZE 4096
#define IA32_MAXDSIZ (512*1024*1024) /* 512MB */
#define IA32_MAXSSIZ (64*1024*1024) /* 64MB */
-#define IA32_MAXVMEM 0 /* Unlimited */
+#define IA32_MAXVMEM 0 /* Unlimited */
struct syscall_args;
int ia32_fetch_syscall_args(struct thread *td, struct syscall_args *sa);
void ia32_set_syscall_retval(struct thread *, int);
void ia32_fixlimit(struct rlimit *rl, int which);
-#endif
+#endif /* _COMPAT_IA32_IA32_UTIL_H */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/linux/check_error.d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/compat/linux/check_error.d Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,144 @@
+#!/usr/sbin/dtrace -qs
+
+/*-
+ * Copyright (c) 2008-2012 Alexander Leidinger <netchild at 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
+ * in this position and unchanged.
+ * 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: head/sys/compat/linux/check_error.d 235063 2012-05-05 19:42:38Z netchild $
+ */
+
+/*
+ * Report error conditions:
+ * - emulation errors (unsupportet stuff, unknown stuff, ...)
+ * - kernel errors (resource shortage, ...)
+ * - programming errors (errors which can happen, but should not happen)
+ */
+
+linuxulator*:dummy::not_implemented,
+linuxulator*:emul:proc_exit:child_clear_tid_error,
+linuxulator*:emul:proc_exit:futex_failed,
+linuxulator*:emul:linux_schedtail:copyout_error,
+linuxulator*:futex:futex_get:error,
+linuxulator*:futex:futex_sleep:requeue_error,
+linuxulator*:futex:futex_sleep:sleep_error,
+linuxulator*:futex:futex_wait:copyin_error,
+linuxulator*:futex:futex_wait:itimerfix_error,
+linuxulator*:futex:futex_wait:sleep_error,
+linuxulator*:futex:futex_atomic_op:missing_access_check,
+linuxulator*:futex:futex_atomic_op:unimplemented_op,
+linuxulator*:futex:futex_atomic_op:unimplemented_cmp,
+linuxulator*:futex:linux_sys_futex:unimplemented_clockswitch,
+linuxulator*:futex:linux_sys_futex:copyin_error,
+linuxulator*:futex:linux_sys_futex:unhandled_efault,
+linuxulator*:futex:linux_sys_futex:unimplemented_lock_pi,
+linuxulator*:futex:linux_sys_futex:unimplemented_unlock_pi,
+linuxulator*:futex:linux_sys_futex:unimplemented_trylock_pi,
+linuxulator*:futex:linux_sys_futex:unimplemented_wait_requeue_pi,
+linuxulator*:futex:linux_sys_futex:unimplemented_cmp_requeue_pi,
+linuxulator*:futex:linux_sys_futex:unknown_operation,
+linuxulator*:futex:linux_get_robust_list:copyout_error,
+linuxulator*:futex:handle_futex_death:copyin_error,
+linuxulator*:futex:fetch_robust_entry:copyin_error,
+linuxulator*:futex:release_futexes:copyin_error,
+linuxulator*:time:linux_clock_gettime:conversion_error,
+linuxulator*:time:linux_clock_gettime:gettime_error,
+linuxulator*:time:linux_clock_gettime:copyout_error,
+linuxulator*:time:linux_clock_settime:conversion_error,
+linuxulator*:time:linux_clock_settime:settime_error,
+linuxulator*:time:linux_clock_settime:copyin_error,
+linuxulator*:time:linux_clock_getres:conversion_error,
+linuxulator*:time:linux_clock_getres:getres_error,
+linuxulator*:time:linux_clock_getres:copyout_error,
+linuxulator*:time:linux_nanosleep:conversion_error,
+linuxulator*:time:linux_nanosleep:nanosleep_error,
+linuxulator*:time:linux_nanosleep:copyout_error,
+linuxulator*:time:linux_nanosleep:copyin_error,
+linuxulator*:time:linux_clock_nanosleep:copyin_error,
+linuxulator*:time:linux_clock_nanosleep:conversion_error,
+linuxulator*:time:linux_clock_nanosleep:copyout_error,
+linuxulator*:time:linux_clock_nanosleep:nanosleep_error,
+linuxulator*:sysctl:handle_string:copyout_error,
+linuxulator*:sysctl:linux_sysctl:copyin_error,
+linuxulator*:mib:linux_sysctl_osname:sysctl_string_error,
+linuxulator*:mib:linux_sysctl_osrelease:sysctl_string_error,
+linuxulator*:mib:linux_sysctl_oss_version:sysctl_string_error,
+linuxulator*:mib:linux_prison_create:vfs_copyopt_error,
+linuxulator*:mib:linux_prison_check:vfs_copyopt_error,
+linuxulator*:mib:linux_prison_check:vfs_getopt_error,
+linuxulator*:mib:linux_prison_set:vfs_copyopt_error,
+linuxulator*:mib:linux_prison_set:vfs_getopt_error,
+linuxulator*:mib:linux_prison_get:vfs_setopt_error,
+linuxulator*:mib:linux_prison_get:vfs_setopts_error
+{
+ printf("ERROR: %s in %s:%s:%s\n", probename, probeprov, probemod, probefunc);
+ stack();
+ ustack();
+}
+
+linuxulator*:util:linux_driver_get_name_dev:nullcall,
+linuxulator*:util:linux_driver_get_major_minor:nullcall,
+linuxulator*:futex:linux_sys_futex:invalid_cmp_requeue_use,
+linuxulator*:futex:linux_sys_futex:deprecated_requeue,
+linuxulator*:futex:linux_set_robust_list:size_error,
+linuxulator*:time:linux_clock_getres:nullcall
+{
+ printf("WARNING: %s:%s:%s:%s in application %s, maybe an application error?\n", probename, probeprov, probemod, probefunc, execname);
+ stack();
+ ustack();
+}
+
+linuxulator*:util:linux_driver_get_major_minor:notfound
+{
+ printf("WARNING: Application %s failed to find %s in %s:%s:%s, this may or may not be a problem.\n", execname, stringof(args[0]), probename, probeprov, probemod);
+ stack();
+ ustack();
+}
+
+linuxulator*:time:linux_to_native_clockid:unknown_clockid
+{
+ printf("INFO: Application %s tried to use unknown clockid %d. Please report this to freebsd-emulation at FreeBSD.org.\n", execname, arg0);
+}
+
+linuxulator*:time:linux_to_native_clockid:unsupported_clockid,
+linuxulator*:time:linux_clock_nanosleep:unsupported_clockid
+{
+ printf("WARNING: Application %s tried to use unsupported clockid (%d), this may or may not be a problem for the application.\nPatches to support this clockid are welcome on the freebsd-emulation at FreeBSD.org mailinglist.\n", execname, arg0);
+}
+
+linuxulator*:time:linux_clock_nanosleep:unsupported_flags
+{
+ printf("WARNING: Application %s tried to use unsupported flags (%d), this may or may not be a problem for the application.\nPatches to support those flags are welcome on the freebsd-emulation at FreeBSD.org mailinglist.\n", execname, arg0);
+}
+
+linuxulator*:sysctl:linux_sysctl:wrong_length
+{
+ printf("ERROR: Application %s issued a sysctl which failed the length restrictions.\nThe length passed is %d, the min length supported is 1 and the max length supported is %d.\n", execname, arg0, arg1);
+ stack();
+ ustack();
+}
+
+linuxulator*:sysctl:linux_sysctl:unsupported_sysctl
+{
+ printf("ERROR: Application %s issued an unsupported sysctl (%s).\nPatches to support this sysctl are welcome on the freebsd-emulation at FreeBSD.org mailinglist.\n", execname, stringof(args[0]));
+}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/linux/check_internal_locks.d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/compat/linux/check_internal_locks.d Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,132 @@
+#!/usr/sbin/dtrace -qs
+
+/*-
+ * Copyright (c) 2008-2012 Alexander Leidinger <netchild at 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
+ * in this position and unchanged.
+ * 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: head/sys/compat/linux/check_internal_locks.d 235063 2012-05-05 19:42:38Z netchild $
+ */
+
+/**
+ * Check if the internal locks are correctly acquired/released:
+ * - no recursive locking (mtx locks, write locks)
+ * - no unlocking of already unlocked one
+ *
+ * Print stacktrace if a lock is longer locked than about 10sec or more.
+ */
+
+#pragma D option dynvarsize=32m
+#pragma D option specsize=32m
+
+BEGIN
+{
+ check["emul_lock"] = 0;
+ check["emul_shared_rlock"] = 0;
+ check["emul_shared_wlock"] = 0;
+ check["futex_mtx"] = 0;
+}
+
+linuxulator*:locks:emul_lock:locked,
+linuxulator*:locks:emul_shared_wlock:locked,
+linuxulator*:locks:futex_mtx:locked
+/check[probefunc] > 0/
+{
+ printf("ERROR: recursive lock of %s (%p),", probefunc, arg0);
+ printf(" or missing SDT probe in kernel. Stack trace follows:");
+ stack();
+}
+
+linuxulator*:locks:emul_lock:locked,
+linuxulator*:locks:emul_shared_rlock:locked,
+linuxulator*:locks:emul_shared_wlock:locked,
+linuxulator*:locks:futex_mtx:locked
+{
+ ++check[probefunc];
+ @stats[probefunc] = count();
+
+ ts[probefunc] = timestamp;
+ spec[probefunc] = speculation();
+}
+
+linuxulator*:locks:emul_lock:unlock,
+linuxulator*:locks:emul_shared_rlock:unlock,
+linuxulator*:locks:emul_shared_wlock:unlock,
+linuxulator*:locks:futex_mtx:unlock
+/check[probefunc] == 0/
+{
+ printf("ERROR: unlock attemt of unlocked %s (%p),", probefunc, arg0);
+ printf(" missing SDT probe in kernel, or dtrace program started");
+ printf(" while the %s was already held (race condition).", probefunc);
+ printf(" Stack trace follows:");
+ stack();
+}
+
+linuxulator*:locks:emul_lock:unlock,
+linuxulator*:locks:emul_shared_rlock:unlock,
+linuxulator*:locks:emul_shared_wlock:unlock,
+linuxulator*:locks:futex_mtx:unlock
+{
+ discard(spec[probefunc]);
+ spec[probefunc] = 0;
+ --check[probefunc];
+}
+
+/* Timeout handling */
+
+tick-10s
+/spec["emul_lock"] != 0 && timestamp - ts["emul_lock"] >= 9999999000/
+{
+ commit(spec["emul_lock"]);
+ spec["emul_lock"] = 0;
+}
+
+tick-10s
+/spec["emul_shared_wlock"] != 0 && timestamp - ts["emul_shared_wlock"] >= 9999999000/
+{
+ commit(spec["emul_shared_wlock"]);
+ spec["emul_shared_wlock"] = 0;
+}
+
+tick-10s
+/spec["emul_shared_rlock"] != 0 && timestamp - ts["emul_shared_rlock"] >= 9999999000/
+{
+ commit(spec["emul_shared_rlock"]);
+ spec["emul_shared_rlock"] = 0;
+}
+
+tick-10s
+/spec["futex_mtx"] != 0 && timestamp - ts["futex_mtx"] >= 9999999000/
+{
+ commit(spec["futex_mtx"]);
+ spec["futex_mtx"] = 0;
+}
+
+
+/* Statistics */
+
+END
+{
+ printf("Number of locks per type:");
+ printa(@stats);
+}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/linux/linux_dtrace.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/compat/linux/linux_dtrace.h Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 2008-2012 Alexander Leidinger <netchild at 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
+ * in this position and unchanged.
+ * 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: head/sys/compat/linux/linux_dtrace.h 235063 2012-05-05 19:42:38Z netchild $
+ */
+
+#ifndef _LINUX_DTRACE_H_
+#define _LINUX_DTRACE_H_
+
+/**
+ * DTrace support macros for the linuxulator.
+ *
+ * Some wrapper macros to make it more easy to handle the linuxulator
+ * providers and to allow to make the name depend upon the bitsize.
+ *
+ * Basically this is the same as the normal SDT macros in sys/sdt.h. The
+ * difference is that the provider name is automatically inserted, and
+ * we do not use a different name for the probe-description.
+ */
+
+#define LIN_SDT_PROVIDER_DEFINE(x) SDT_PROVIDER_DEFINE(x)
+#define LIN_SDT_PROVIDER_DECLARE(x) SDT_PROVIDER_DECLARE(x)
+
+#define _LIN_SDT_PROBE_DECLARE(a, b, c, d) SDT_PROBE_DECLARE(a, b, c, d)
+#define LIN_SDT_PROBE_DECLARE(a, b, c) _LIN_SDT_PROBE_DECLARE( \
+ LINUX_DTRACE, a, b, c)
+
+#define _LIN_SDT_PROBE_DEFINE0(a, b, c, d) SDT_PROBE_DEFINE(a, \
+ b, c, d, d)
+#define LIN_SDT_PROBE_DEFINE0(a, b, c) _LIN_SDT_PROBE_DEFINE0(\
+ LINUX_DTRACE, a, b, c)
+#define _LIN_SDT_PROBE_DEFINE1(a, b, c, d, e) SDT_PROBE_DEFINE1(a, \
+ b, c, d, d, e)
+#define LIN_SDT_PROBE_DEFINE1(a, b, c, d) _LIN_SDT_PROBE_DEFINE1(\
+ LINUX_DTRACE, a, b, c, d)
+#define _LIN_SDT_PROBE_DEFINE2(a, b, c, d, e, f) SDT_PROBE_DEFINE2(a, \
+ b, c, d, d, e, f)
+#define LIN_SDT_PROBE_DEFINE2(a, b, c, d, e) _LIN_SDT_PROBE_DEFINE2(\
+ LINUX_DTRACE, a, b, c, d, e)
+#define _LIN_SDT_PROBE_DEFINE3(a, b, c, d, e, f, g) SDT_PROBE_DEFINE3(a, \
+ b, c, d, d, e, f, g)
+#define LIN_SDT_PROBE_DEFINE3(a, b, c, d, e, f) _LIN_SDT_PROBE_DEFINE3(\
+ LINUX_DTRACE, a, b, c, d, e, f)
+#define _LIN_SDT_PROBE_DEFINE4(a, b, c, d, e, f, g, h) SDT_PROBE_DEFINE4(a, \
+ b, c, d, d, e, f, g, h)
+#define LIN_SDT_PROBE_DEFINE4(a, b, c, d, e, f, g) _LIN_SDT_PROBE_DEFINE4(\
+ LINUX_DTRACE, a, b, c, d, e, f, g)
+#define _LIN_SDT_PROBE_DEFINE5(a, b, c, d, e, f, g, h, i) \
+ SDT_PROBE_DEFINE5(a, b, c, d, d, e, f, g, h, i)
+#define LIN_SDT_PROBE_DEFINE5(a, b, c, d, e, f, g, h) _LIN_SDT_PROBE_DEFINE5(\
+ LINUX_DTRACE, a, b, c, d, e, f, g, h)
+
+#define _LIN_SDT_PROBE_ARGTYPE(a, b, c, d, e, f) SDT_PROBE_ARGTYPE(a, b,\
+ c, d, e, f)
+#define LIN_SDT_PROBE_ARGTYPE(a, b, c, d, e) _LIN_SDT_PROBE_ARGTYPE( \
+ LINUX_DTRACE, a, b, c, d, e)
+
+#define LIN_SDT_PROBE0(a, b, c) SDT_PROBE1(LINUX_DTRACE, a, b, \
+ c, 0)
+#define LIN_SDT_PROBE1(a, b, c, d) SDT_PROBE1(LINUX_DTRACE, a, b, \
+ c, d)
+#define LIN_SDT_PROBE2(a, b, c, d, e) SDT_PROBE2(LINUX_DTRACE, a, b, \
+ c, d, e)
+#define LIN_SDT_PROBE3(a, b, c, d, e, f) SDT_PROBE3(LINUX_DTRACE, a, b, \
+ c, d, e, f)
+#define LIN_SDT_PROBE4(a, b, c, d, e, f, g) SDT_PROBE4(LINUX_DTRACE, a, b, \
+ c, d, e, f, g)
+#define _LIN_SDT_PROBE5(a, b, c, d, e, f, g, h, i) SDT_PROBE(a, b, c, d, \
+ e, f, g, h, i)
+#define LIN_SDT_PROBE5(a, b, c, d, e, f, g, h) _LIN_SDT_PROBE5(LINUX_DTRACE, \
+ a, b, c, d, e, f, g, h)
+
+#endif /* _LINUX_DTRACE_H_ */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/linux/linux_emul.c
--- a/head/sys/compat/linux/linux_emul.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/linux/linux_emul.c Wed Jul 25 16:45:04 2012 +0300
@@ -27,9 +27,10 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/linux/linux_emul.c 225617 2011-09-16 13:58:51Z kmacy $");
+__FBSDID("$FreeBSD: head/sys/compat/linux/linux_emul.c 235063 2012-05-05 19:42:38Z netchild $");
#include "opt_compat.h"
+#include "opt_kdtrace.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -38,6 +39,7 @@
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
+#include <sys/sdt.h>
#include <sys/sx.h>
#include <sys/proc.h>
#include <sys/syscallsubr.h>
@@ -53,9 +55,64 @@
#include <machine/../linux/linux_proto.h>
#endif
+#include <compat/linux/linux_dtrace.h>
#include <compat/linux/linux_emul.h>
#include <compat/linux/linux_futex.h>
+/**
+ * Special DTrace provider for the linuxulator.
+ *
+ * In this file we define the provider for the entire linuxulator. All
+ * modules (= files of the linuxulator) use it.
+ *
+ * We define a different name depending on the emulated bitsize, see
+ * ../../<ARCH>/linux{,32}/linux.h, e.g.:
+ * native bitsize = linuxulator
+ * amd64, 32bit emulation = linuxulator32
+ */
+LIN_SDT_PROVIDER_DEFINE(LINUX_DTRACE);
+
+/**
+ * Special DTrace module "locks", it covers some linuxulator internal
+ * locks.
+ */
+LIN_SDT_PROBE_DEFINE1(locks, emul_lock, locked, "struct mtx *");
+LIN_SDT_PROBE_DEFINE1(locks, emul_lock, unlock, "struct mtx *");
+LIN_SDT_PROBE_DEFINE1(locks, emul_shared_rlock, locked, "struct sx *");
+LIN_SDT_PROBE_DEFINE1(locks, emul_shared_rlock, unlock, "struct sx *");
+LIN_SDT_PROBE_DEFINE1(locks, emul_shared_wlock, locked, "struct sx *");
+LIN_SDT_PROBE_DEFINE1(locks, emul_shared_wlock, unlock, "struct sx *");
+
+/**
+ * DTrace probes in this module.
+ */
+LIN_SDT_PROBE_DEFINE2(emul, em_find, entry, "struct proc *", "int");
+LIN_SDT_PROBE_DEFINE0(emul, em_find, return);
+LIN_SDT_PROBE_DEFINE3(emul, proc_init, entry, "struct thread *", "pid_t",
+ "int");
+LIN_SDT_PROBE_DEFINE0(emul, proc_init, create_thread);
+LIN_SDT_PROBE_DEFINE0(emul, proc_init, fork);
+LIN_SDT_PROBE_DEFINE0(emul, proc_init, exec);
+LIN_SDT_PROBE_DEFINE0(emul, proc_init, return);
+LIN_SDT_PROBE_DEFINE1(emul, proc_exit, entry, "struct proc *");
+LIN_SDT_PROBE_DEFINE0(emul, proc_exit, futex_failed);
+LIN_SDT_PROBE_DEFINE3(emul, proc_exit, reparent, "pid_t", "pid_t",
+ "struct proc *");
+LIN_SDT_PROBE_DEFINE1(emul, proc_exit, child_clear_tid_error, "int");
+LIN_SDT_PROBE_DEFINE0(emul, proc_exit, return);
+LIN_SDT_PROBE_DEFINE2(emul, proc_exec, entry, "struct proc *",
+ "struct image_params *");
+LIN_SDT_PROBE_DEFINE0(emul, proc_exec, return);
+LIN_SDT_PROBE_DEFINE0(emul, linux_schedtail, entry);
+LIN_SDT_PROBE_DEFINE1(emul, linux_schedtail, copyout_error, "int");
+LIN_SDT_PROBE_DEFINE0(emul, linux_schedtail, return);
+LIN_SDT_PROBE_DEFINE1(emul, linux_set_tid_address, entry, "int *");
+LIN_SDT_PROBE_DEFINE0(emul, linux_set_tid_address, return);
+LIN_SDT_PROBE_DEFINE2(emul, linux_kill_threads, entry, "struct thread *",
+ "int");
+LIN_SDT_PROBE_DEFINE1(emul, linux_kill_threads, kill, "pid_t");
+LIN_SDT_PROBE_DEFINE0(emul, linux_kill_threads, return);
+
struct sx emul_shared_lock;
struct mtx emul_lock;
@@ -65,6 +122,8 @@
{
struct linux_emuldata *em;
+ LIN_SDT_PROBE2(emul, em_find, entry, p, locked);
+
if (locked == EMUL_DOLOCK)
EMUL_LOCK(&emul_lock);
@@ -73,6 +132,7 @@
if (em == NULL && locked == EMUL_DOLOCK)
EMUL_UNLOCK(&emul_lock);
+ LIN_SDT_PROBE1(emul, em_find, return, em);
return (em);
}
@@ -82,8 +142,10 @@
struct linux_emuldata *em, *p_em;
struct proc *p;
+ LIN_SDT_PROBE3(emul, proc_init, entry, td, child, flags);
+
if (child != 0) {
- /* non-exec call */
+ /* fork or create a thread */
em = malloc(sizeof *em, M_LINUX, M_WAITOK | M_ZERO);
em->pid = child;
em->pdeath_signal = 0;
@@ -91,9 +153,12 @@
em->robust_futexes = NULL;
if (flags & LINUX_CLONE_THREAD) {
/* handled later in the code */
+ LIN_SDT_PROBE0(emul, proc_init, create_thread);
} else {
struct linux_emuldata_shared *s;
+ LIN_SDT_PROBE0(emul, proc_init, fork);
+
s = malloc(sizeof *s, M_LINUX, M_WAITOK | M_ZERO);
s->refs = 1;
s->group_pid = child;
@@ -102,6 +167,9 @@
em->shared = s;
}
} else {
+ /* exec */
+ LIN_SDT_PROBE0(emul, proc_init, exec);
+
/* lookup the old one */
em = em_find(td->td_proc, EMUL_DOLOCK);
KASSERT(em != NULL, ("proc_init: emuldata not found in exec case.\n"));
@@ -136,8 +204,7 @@
* rwlock held
*/
}
- }
- if (child != 0) {
+
EMUL_SHARED_WLOCK(&emul_shared_lock);
LIST_INSERT_HEAD(&em->shared->threads, em, threads);
EMUL_SHARED_WUNLOCK(&emul_shared_lock);
@@ -149,6 +216,7 @@
} else
EMUL_UNLOCK(&emul_lock);
+ LIN_SDT_PROBE0(emul, proc_init, return);
return (0);
}
@@ -164,6 +232,8 @@
if (__predict_true(p->p_sysent != &elf_linux_sysvec))
return;
+ LIN_SDT_PROBE1(emul, proc_exit, entry, p);
+
release_futexes(p);
/* find the emuldata */
@@ -173,6 +243,9 @@
/* reparent all procs that are not a thread leader to initproc */
if (em->shared->group_pid != p->p_pid) {
+ LIN_SDT_PROBE3(emul, proc_exit, reparent,
+ em->shared->group_pid, p->p_pid, p);
+
child_clear_tid = em->child_clear_tid;
EMUL_UNLOCK(&emul_lock);
sx_xlock(&proctree_lock);
@@ -208,7 +281,12 @@
error = copyout(&null, child_clear_tid, sizeof(null));
if (error) {
+ LIN_SDT_PROBE1(emul, proc_exit,
+ child_clear_tid_error, error);
+
free(em, M_LINUX);
+
+ LIN_SDT_PROBE0(emul, proc_exit, return);
return;
}
@@ -224,8 +302,10 @@
* this cannot happen at the moment and if this happens it
* probably means there is a user space bug
*/
- if (error)
+ if (error) {
+ LIN_SDT_PROBE0(emul, proc_exit, futex_failed);
printf(LMSG("futex stuff in proc_exit failed.\n"));
+ }
}
/* clean the stuff up */
@@ -250,6 +330,8 @@
EMUL_UNLOCK(&emul_lock);
}
sx_xunlock(&proctree_lock);
+
+ LIN_SDT_PROBE0(emul, proc_exit, return);
}
/*
@@ -260,6 +342,9 @@
void
linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp)
{
+ if (__predict_false(imgp->sysent == &elf_linux_sysvec)) {
+ LIN_SDT_PROBE2(emul, proc_exec, entry, p, imgp);
+ }
if (__predict_false(imgp->sysent == &elf_linux_sysvec
&& p->p_sysent != &elf_linux_sysvec))
linux_proc_init(FIRST_THREAD_IN_PROC(p), p->p_pid, 0);
@@ -297,6 +382,10 @@
free(em, M_LINUX);
}
+
+ if (__predict_false(imgp->sysent == &elf_linux_sysvec)) {
+ LIN_SDT_PROBE0(emul, proc_exec, return);
+ }
}
void
@@ -309,6 +398,8 @@
p = td->td_proc;
+ LIN_SDT_PROBE1(emul, linux_schedtail, entry, p);
+
/* find the emuldata */
em = em_find(p, EMUL_DOLOCK);
@@ -316,10 +407,18 @@
child_set_tid = em->child_set_tid;
EMUL_UNLOCK(&emul_lock);
- if (child_set_tid != NULL)
+ if (child_set_tid != NULL) {
error = copyout(&p->p_pid, (int *)child_set_tid,
sizeof(p->p_pid));
+ if (error != 0) {
+ LIN_SDT_PROBE1(emul, linux_schedtail, copyout_error,
+ error);
+ }
+ }
+
+ LIN_SDT_PROBE0(emul, linux_schedtail, return);
+
return;
}
@@ -328,10 +427,7 @@
{
struct linux_emuldata *em;
-#ifdef DEBUG
- if (ldebug(set_tid_address))
- printf(ARGS(set_tid_address, "%p"), args->tidptr);
-#endif
+ LIN_SDT_PROBE1(emul, linux_set_tid_address, entry, args->tidptr);
/* find the emuldata */
em = em_find(td->td_proc, EMUL_DOLOCK);
@@ -342,6 +438,8 @@
td->td_retval[0] = td->td_proc->p_pid;
EMUL_UNLOCK(&emul_lock);
+
+ LIN_SDT_PROBE0(emul, linux_set_tid_address, return);
return 0;
}
@@ -351,6 +449,8 @@
struct linux_emuldata *em, *td_em, *tmp_em;
struct proc *sp;
+ LIN_SDT_PROBE2(emul, linux_kill_threads, entry, td, sig);
+
td_em = em_find(td->td_proc, EMUL_DONTLOCK);
KASSERT(td_em != NULL, ("linux_kill_threads: emuldata not found.\n"));
@@ -364,9 +464,10 @@
if ((sp->p_flag & P_WEXIT) == 0)
kern_psignal(sp, sig);
PROC_UNLOCK(sp);
-#ifdef DEBUG
- printf(LMSG("linux_kill_threads: kill PID %d\n"), em->pid);
-#endif
+
+ LIN_SDT_PROBE1(emul, linux_kill_threads, kill, em->pid);
}
EMUL_SHARED_RUNLOCK(&emul_shared_lock);
+
+ LIN_SDT_PROBE0(emul, linux_kill_threads, return);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/linux/linux_emul.h
--- a/head/sys/compat/linux/linux_emul.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/linux/linux_emul.h Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/compat/linux/linux_emul.h 235063 2012-05-05 19:42:38Z netchild $
*/
#ifndef _LINUX_EMUL_H_
@@ -64,13 +64,42 @@
struct linux_emuldata *em_find(struct proc *, int locked);
-#define EMUL_LOCK(l) mtx_lock(l)
-#define EMUL_UNLOCK(l) mtx_unlock(l)
+/*
+ * DTrace probes for locks should be fired after locking and before releasing
+ * to prevent races (to provide data/function stability in dtrace, see the
+ * output of "dtrace -v ..." and the corresponding dtrace docs).
+ */
+#define EMUL_LOCK(l) do { \
+ mtx_lock(l); \
+ LIN_SDT_PROBE1(locks, emul_lock, \
+ locked, l); \
+ } while (0)
+#define EMUL_UNLOCK(l) do { \
+ LIN_SDT_PROBE1(locks, emul_lock, \
+ unlock, l); \
+ mtx_unlock(l); \
+ } while (0)
-#define EMUL_SHARED_RLOCK(l) sx_slock(l)
-#define EMUL_SHARED_RUNLOCK(l) sx_sunlock(l)
-#define EMUL_SHARED_WLOCK(l) sx_xlock(l)
-#define EMUL_SHARED_WUNLOCK(l) sx_xunlock(l)
+#define EMUL_SHARED_RLOCK(l) do { \
+ sx_slock(l); \
+ LIN_SDT_PROBE1(locks, emul_shared_rlock, \
+ locked, l); \
+ } while (0)
+#define EMUL_SHARED_RUNLOCK(l) do { \
+ LIN_SDT_PROBE1(locks, emul_shared_rlock, \
+ unlock, l); \
+ sx_sunlock(l); \
+ } while (0)
+#define EMUL_SHARED_WLOCK(l) do { \
+ sx_xlock(l); \
+ LIN_SDT_PROBE1(locks, emul_shared_wlock, \
+ locked, l); \
+ } while (0)
+#define EMUL_SHARED_WUNLOCK(l) do { \
+ LIN_SDT_PROBE1(locks, emul_shared_wlock, \
+ unlock, l); \
+ sx_xunlock(l); \
+ } while (0)
/* for em_find use */
#define EMUL_DOLOCK 1
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/linux/linux_file.c
--- a/head/sys/compat/linux/linux_file.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/linux/linux_file.c Wed Jul 25 16:45:04 2012 +0300
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/linux/linux_file.c 234352 2012-04-16 21:22:02Z jkim $");
+__FBSDID("$FreeBSD: head/sys/compat/linux/linux_file.c 238029 2012-07-02 21:01:03Z kib $");
#include "opt_compat.h"
@@ -357,15 +357,16 @@
return (EBADF);
}
+ off = foffset_lock(fp, 0);
vp = fp->f_vnode;
vfslocked = VFS_LOCK_GIANT(vp->v_mount);
if (vp->v_type != VDIR) {
VFS_UNLOCK_GIANT(vfslocked);
+ foffset_unlock(fp, off, 0);
fdrop(fp, td);
return (EINVAL);
}
- off = fp->f_offset;
buflen = max(LINUX_DIRBLKSIZ, nbytes);
buflen = min(buflen, MAXBSIZE);
@@ -514,7 +515,6 @@
goto eof;
}
- fp->f_offset = off;
if (justone)
nbytes = resid + linuxreclen;
@@ -527,6 +527,7 @@
VOP_UNLOCK(vp, 0);
VFS_UNLOCK_GIANT(vfslocked);
+ foffset_unlock(fp, off, 0);
fdrop(fp, td);
free(buf, M_TEMP);
free(lbuf, M_TEMP);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/linux/linux_fork.c
--- a/head/sys/compat/linux/linux_fork.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/linux/linux_fork.c Wed Jul 25 16:45:04 2012 +0300
@@ -27,9 +27,10 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/linux/linux_fork.c 224987 2011-08-18 22:51:30Z jonathan $");
+__FBSDID("$FreeBSD: head/sys/compat/linux/linux_fork.c 235063 2012-05-05 19:42:38Z netchild $");
#include "opt_compat.h"
+#include "opt_kdtrace.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -38,6 +39,7 @@
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/sched.h>
+#include <sys/sdt.h>
#include <sys/sx.h>
#include <sys/unistd.h>
@@ -48,9 +50,17 @@
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#endif
+#include <compat/linux/linux_dtrace.h>
#include <compat/linux/linux_signal.h>
#include <compat/linux/linux_emul.h>
+/* DTrace init */
+LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
+
+/* Linuxulator-global DTrace probes */
+LIN_SDT_PROBE_DECLARE(locks, emul_lock, locked);
+LIN_SDT_PROBE_DECLARE(locks, emul_lock, unlock);
+
int
linux_fork(struct thread *td, struct linux_fork_args *args)
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/linux/linux_futex.c
--- a/head/sys/compat/linux/linux_futex.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/linux/linux_futex.c Wed Jul 25 16:45:04 2012 +0300
@@ -32,12 +32,13 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/linux/linux_futex.c 227293 2011-11-07 06:44:47Z ed $");
+__FBSDID("$FreeBSD: head/sys/compat/linux/linux_futex.c 235063 2012-05-05 19:42:38Z netchild $");
#if 0
__KERNEL_RCSID(1, "$NetBSD: linux_futex.c,v 1.7 2006/07/24 19:01:49 manu Exp $");
#endif
#include "opt_compat.h"
+#include "opt_kdtrace.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -51,6 +52,7 @@
#include <sys/proc.h>
#include <sys/queue.h>
#include <sys/sched.h>
+#include <sys/sdt.h>
#include <sys/sx.h>
#include <sys/umtx.h>
@@ -61,10 +63,131 @@
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#endif
+#include <compat/linux/linux_dtrace.h>
#include <compat/linux/linux_emul.h>
#include <compat/linux/linux_futex.h>
#include <compat/linux/linux_util.h>
+/* DTrace init */
+LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
+
+/* Linuxulator-global DTrace probes */
+LIN_SDT_PROBE_DECLARE(locks, emul_lock, locked);
+LIN_SDT_PROBE_DECLARE(locks, emul_lock, unlock);
+
+/**
+ * Futex part for the special DTrace module "locks".
+ */
+LIN_SDT_PROBE_DEFINE1(locks, futex_mtx, locked, "struct mtx *");
+LIN_SDT_PROBE_DEFINE1(locks, futex_mtx, unlock, "struct mtx *");
+
+/**
+ * Per futex probes.
+ */
+LIN_SDT_PROBE_DEFINE1(futex, futex, create, "struct sx *");
+LIN_SDT_PROBE_DEFINE1(futex, futex, destroy, "struct sx *");
+
+/**
+ * DTrace probes in this module.
+ */
+LIN_SDT_PROBE_DEFINE2(futex, futex_put, entry, "struct futex *",
+ "struct waiting_proc *");
+LIN_SDT_PROBE_DEFINE3(futex, futex_put, destroy, "uint32_t *", "uint32_t",
+ "int");
+LIN_SDT_PROBE_DEFINE3(futex, futex_put, unlock, "uint32_t *", "uint32_t",
+ "int");
+LIN_SDT_PROBE_DEFINE0(futex, futex_put, return);
+LIN_SDT_PROBE_DEFINE3(futex, futex_get0, entry, "uint32_t *", "struct futex **",
+ "uint32_t");
+LIN_SDT_PROBE_DEFINE1(futex, futex_get0, umtx_key_get_error, "int");
+LIN_SDT_PROBE_DEFINE3(futex, futex_get0, shared, "uint32_t *", "uint32_t",
+ "int");
+LIN_SDT_PROBE_DEFINE1(futex, futex_get0, null, "uint32_t *");
+LIN_SDT_PROBE_DEFINE3(futex, futex_get0, new, "uint32_t *", "uint32_t", "int");
+LIN_SDT_PROBE_DEFINE1(futex, futex_get0, return, "int");
+LIN_SDT_PROBE_DEFINE3(futex, futex_get, entry, "uint32_t *",
+ "struct waiting_proc **", "struct futex **");
+LIN_SDT_PROBE_DEFINE0(futex, futex_get, error);
+LIN_SDT_PROBE_DEFINE1(futex, futex_get, return, "int");
+LIN_SDT_PROBE_DEFINE3(futex, futex_sleep, entry, "struct futex *",
+ "struct waiting_proc **", "int");
+LIN_SDT_PROBE_DEFINE5(futex, futex_sleep, requeue_error, "int", "uint32_t *",
+ "struct waiting_proc *", "uint32_t *", "uint32_t");
+LIN_SDT_PROBE_DEFINE3(futex, futex_sleep, sleep_error, "int", "uint32_t *",
+ "struct waiting_proc *");
+LIN_SDT_PROBE_DEFINE1(futex, futex_sleep, return, "int");
+LIN_SDT_PROBE_DEFINE3(futex, futex_wake, entry, "struct futex *", "int",
+ "uint32_t");
+LIN_SDT_PROBE_DEFINE3(futex, futex_wake, iterate, "uint32_t",
+ "struct waiting_proc *", "uin32_t");
+LIN_SDT_PROBE_DEFINE1(futex, futex_wake, wakeup, "struct waiting_proc *");
+LIN_SDT_PROBE_DEFINE1(futex, futex_wake, return, "int");
+LIN_SDT_PROBE_DEFINE4(futex, futex_requeue, entry, "struct futex *", "int",
+ "struct futex *", "int");
+LIN_SDT_PROBE_DEFINE1(futex, futex_requeue, wakeup, "struct waiting_proc *");
+LIN_SDT_PROBE_DEFINE3(futex, futex_requeue, requeue, "uint32_t *",
+ "struct waiting_proc *", "uint32_t");
+LIN_SDT_PROBE_DEFINE1(futex, futex_requeue, return, "int");
+LIN_SDT_PROBE_DEFINE4(futex, futex_wait, entry, "struct futex *",
+ "struct waiting_proc **", "struct l_timespec *", "uint32_t");
+LIN_SDT_PROBE_DEFINE1(futex, futex_wait, copyin_error, "int");
+LIN_SDT_PROBE_DEFINE1(futex, futex_wait, itimerfix_error, "int");
+LIN_SDT_PROBE_DEFINE1(futex, futex_wait, sleep_error, "int");
+LIN_SDT_PROBE_DEFINE1(futex, futex_wait, return, "int");
+LIN_SDT_PROBE_DEFINE3(futex, futex_atomic_op, entry, "struct thread *",
+ "int", "uint32_t");
+LIN_SDT_PROBE_DEFINE4(futex, futex_atomic_op, decoded_op, "int", "int", "int",
+ "int");
+LIN_SDT_PROBE_DEFINE0(futex, futex_atomic_op, missing_access_check);
+LIN_SDT_PROBE_DEFINE1(futex, futex_atomic_op, unimplemented_op, "int");
+LIN_SDT_PROBE_DEFINE1(futex, futex_atomic_op, unimplemented_cmp, "int");
+LIN_SDT_PROBE_DEFINE1(futex, futex_atomic_op, return, "int");
+LIN_SDT_PROBE_DEFINE2(futex, linux_sys_futex, entry, "struct thread *",
+ "struct linux_sys_futex_args *");
+LIN_SDT_PROBE_DEFINE0(futex, linux_sys_futex, unimplemented_clockswitch);
+LIN_SDT_PROBE_DEFINE1(futex, linux_sys_futex, copyin_error, "int");
+LIN_SDT_PROBE_DEFINE0(futex, linux_sys_futex, invalid_cmp_requeue_use);
+LIN_SDT_PROBE_DEFINE3(futex, linux_sys_futex, debug_wait, "uint32_t *",
+ "uint32_t", "uint32_t");
+LIN_SDT_PROBE_DEFINE4(futex, linux_sys_futex, debug_wait_value_neq,
+ "uint32_t *", "uint32_t", "int", "uint32_t");
+LIN_SDT_PROBE_DEFINE3(futex, linux_sys_futex, debug_wake, "uint32_t *",
+ "uint32_t", "uint32_t");
+LIN_SDT_PROBE_DEFINE5(futex, linux_sys_futex, debug_cmp_requeue, "uint32_t *",
+ "uint32_t", "uint32_t", "uint32_t *", "struct l_timespec *");
+LIN_SDT_PROBE_DEFINE2(futex, linux_sys_futex, debug_cmp_requeue_value_neq,
+ "uint32_t", "int");
+LIN_SDT_PROBE_DEFINE5(futex, linux_sys_futex, debug_wake_op, "uint32_t *",
+ "int", "uint32_t", "uint32_t *", "uint32_t");
+LIN_SDT_PROBE_DEFINE0(futex, linux_sys_futex, unhandled_efault);
+LIN_SDT_PROBE_DEFINE0(futex, linux_sys_futex, unimplemented_lock_pi);
+LIN_SDT_PROBE_DEFINE0(futex, linux_sys_futex, unimplemented_unlock_pi);
+LIN_SDT_PROBE_DEFINE0(futex, linux_sys_futex, unimplemented_trylock_pi);
+LIN_SDT_PROBE_DEFINE0(futex, linux_sys_futex, deprecated_requeue);
+LIN_SDT_PROBE_DEFINE0(futex, linux_sys_futex, unimplemented_wait_requeue_pi);
+LIN_SDT_PROBE_DEFINE0(futex, linux_sys_futex, unimplemented_cmp_requeue_pi);
+LIN_SDT_PROBE_DEFINE1(futex, linux_sys_futex, unknown_operation, "int");
+LIN_SDT_PROBE_DEFINE1(futex, linux_sys_futex, return, "int");
+LIN_SDT_PROBE_DEFINE2(futex, linux_set_robust_list, entry, "struct thread *",
+ "struct linux_set_robust_list_args *");
+LIN_SDT_PROBE_DEFINE0(futex, linux_set_robust_list, size_error);
+LIN_SDT_PROBE_DEFINE1(futex, linux_set_robust_list, return, "int");
+LIN_SDT_PROBE_DEFINE2(futex, linux_get_robust_list, entry, "struct thread *",
+ "struct linux_get_robust_list_args *");
+LIN_SDT_PROBE_DEFINE1(futex, linux_get_robust_list, copyout_error, "int");
+LIN_SDT_PROBE_DEFINE1(futex, linux_get_robust_list, return, "int");
+LIN_SDT_PROBE_DEFINE3(futex, handle_futex_death, entry, "struct proc *",
+ "uint32_t *", "int");
+LIN_SDT_PROBE_DEFINE1(futex, handle_futex_death, copyin_error, "int");
+LIN_SDT_PROBE_DEFINE1(futex, handle_futex_death, return, "int");
+LIN_SDT_PROBE_DEFINE3(futex, fetch_robust_entry, entry,
+ "struct linux_robust_list **", "struct linux_robust_list **", "int *");
+LIN_SDT_PROBE_DEFINE1(futex, fetch_robust_entry, copyin_error, "int");
+LIN_SDT_PROBE_DEFINE1(futex, fetch_robust_entry, return, "int");
+LIN_SDT_PROBE_DEFINE1(futex, release_futexes, entry, "struct proc *");
+LIN_SDT_PROBE_DEFINE1(futex, release_futexes, copyin_error, "int");
+LIN_SDT_PROBE_DEFINE0(futex, release_futexes, return);
+
static MALLOC_DEFINE(M_FUTEX, "futex", "Linux futexes");
static MALLOC_DEFINE(M_FUTEX_WP, "futex wp", "Linux futexes wp");
@@ -90,13 +213,30 @@
#define FUTEX_LOCK(f) sx_xlock(&(f)->f_lck)
#define FUTEX_UNLOCK(f) sx_xunlock(&(f)->f_lck)
-#define FUTEX_INIT(f) sx_init_flags(&(f)->f_lck, "ftlk", SX_DUPOK)
-#define FUTEX_DESTROY(f) sx_destroy(&(f)->f_lck)
+#define FUTEX_INIT(f) do { \
+ sx_init_flags(&(f)->f_lck, "ftlk", \
+ SX_DUPOK); \
+ LIN_SDT_PROBE1(futex, futex, create, \
+ &(f)->f_lck); \
+ } while (0)
+#define FUTEX_DESTROY(f) do { \
+ LIN_SDT_PROBE1(futex, futex, destroy, \
+ &(f)->f_lck); \
+ sx_destroy(&(f)->f_lck); \
+ } while (0)
#define FUTEX_ASSERT_LOCKED(f) sx_assert(&(f)->f_lck, SA_XLOCKED)
struct mtx futex_mtx; /* protects the futex list */
-#define FUTEXES_LOCK mtx_lock(&futex_mtx)
-#define FUTEXES_UNLOCK mtx_unlock(&futex_mtx)
+#define FUTEXES_LOCK do { \
+ mtx_lock(&futex_mtx); \
+ LIN_SDT_PROBE1(locks, futex_mtx, \
+ locked, &futex_mtx); \
+ } while (0)
+#define FUTEXES_UNLOCK do { \
+ LIN_SDT_PROBE1(locks, futex_mtx, \
+ unlock, &futex_mtx); \
+ mtx_unlock(&futex_mtx); \
+ } while (0)
/* flags for futex_get() */
#define FUTEX_CREATE_WP 0x1 /* create waiting_proc */
@@ -123,6 +263,7 @@
static void
futex_put(struct futex *f, struct waiting_proc *wp)
{
+ LIN_SDT_PROBE2(futex, futex_put, entry, f, wp);
FUTEX_ASSERT_LOCKED(f);
if (wp != NULL) {
@@ -137,18 +278,26 @@
FUTEXES_UNLOCK;
FUTEX_UNLOCK(f);
+ LIN_SDT_PROBE3(futex, futex_put, destroy, f->f_uaddr,
+ f->f_refcount, f->f_key.shared);
LINUX_CTR3(sys_futex, "futex_put destroy uaddr %p ref %d "
"shared %d", f->f_uaddr, f->f_refcount, f->f_key.shared);
umtx_key_release(&f->f_key);
FUTEX_DESTROY(f);
free(f, M_FUTEX);
+
+ LIN_SDT_PROBE0(futex, futex_put, return);
return;
}
+ LIN_SDT_PROBE3(futex, futex_put, unlock, f->f_uaddr, f->f_refcount,
+ f->f_key.shared);
LINUX_CTR3(sys_futex, "futex_put uaddr %p ref %d shared %d",
f->f_uaddr, f->f_refcount, f->f_key.shared);
FUTEXES_UNLOCK;
FUTEX_UNLOCK(f);
+
+ LIN_SDT_PROBE0(futex, futex_put, return);
}
static int
@@ -158,12 +307,17 @@
struct umtx_key key;
int error;
+ LIN_SDT_PROBE3(futex, futex_get0, entry, uaddr, newf, flags);
+
*newf = tmpf = NULL;
error = umtx_key_get(uaddr, TYPE_FUTEX, (flags & FUTEX_SHARED) ?
AUTO_SHARE : THREAD_SHARE, &key);
- if (error)
+ if (error) {
+ LIN_SDT_PROBE1(futex, futex_get0, umtx_key_get_error, error);
+ LIN_SDT_PROBE1(futex, futex_get0, return, error);
return (error);
+ }
retry:
FUTEXES_LOCK;
LIST_FOREACH(f, &futex_list, f_list) {
@@ -176,6 +330,9 @@
if (flags & FUTEX_DONTEXISTS) {
FUTEXES_UNLOCK;
umtx_key_release(&key);
+
+ LIN_SDT_PROBE1(futex, futex_get0, return,
+ EINVAL);
return (EINVAL);
}
@@ -189,8 +346,12 @@
FUTEX_LOCK(f);
*newf = f;
+ LIN_SDT_PROBE3(futex, futex_get0, shared, uaddr,
+ f->f_refcount, f->f_key.shared);
LINUX_CTR3(sys_futex, "futex_get uaddr %p ref %d shared %d",
uaddr, f->f_refcount, f->f_key.shared);
+
+ LIN_SDT_PROBE1(futex, futex_get0, return, 0);
return (0);
}
}
@@ -198,7 +359,10 @@
if (flags & FUTEX_DONTCREATE) {
FUTEXES_UNLOCK;
umtx_key_release(&key);
+ LIN_SDT_PROBE1(futex, futex_get0, null, uaddr);
LINUX_CTR1(sys_futex, "futex_get uaddr %p null", uaddr);
+
+ LIN_SDT_PROBE1(futex, futex_get0, return, 0);
return (0);
}
@@ -223,9 +387,13 @@
LIST_INSERT_HEAD(&futex_list, tmpf, f_list);
FUTEXES_UNLOCK;
+ LIN_SDT_PROBE3(futex, futex_get0, new, uaddr, tmpf->f_refcount,
+ tmpf->f_key.shared);
LINUX_CTR3(sys_futex, "futex_get uaddr %p ref %d shared %d new",
uaddr, tmpf->f_refcount, tmpf->f_key.shared);
*newf = tmpf;
+
+ LIN_SDT_PROBE1(futex, futex_get0, return, 0);
return (0);
}
@@ -235,14 +403,20 @@
{
int error;
+ LIN_SDT_PROBE3(futex, futex_get, entry, uaddr, wp, f);
+
if (flags & FUTEX_CREATE_WP) {
*wp = malloc(sizeof(struct waiting_proc), M_FUTEX_WP, M_WAITOK);
(*wp)->wp_flags = 0;
}
error = futex_get0(uaddr, f, flags);
if (error) {
+ LIN_SDT_PROBE0(futex, futex_get, error);
+
if (flags & FUTEX_CREATE_WP)
free(*wp, M_FUTEX_WP);
+
+ LIN_SDT_PROBE1(futex, futex_get, return, error);
return (error);
}
if (flags & FUTEX_CREATE_WP) {
@@ -250,6 +424,7 @@
(*wp)->wp_futex = *f;
}
+ LIN_SDT_PROBE1(futex, futex_get, return, error);
return (error);
}
@@ -259,23 +434,38 @@
int error;
FUTEX_ASSERT_LOCKED(f);
+ LIN_SDT_PROBE3(futex, futex_sleep, entry, f, wp, timeout);
LINUX_CTR4(sys_futex, "futex_sleep enter uaddr %p wp %p timo %d ref %d",
f->f_uaddr, wp, timeout, f->f_refcount);
error = sx_sleep(wp, &f->f_lck, PCATCH, "futex", timeout);
if (wp->wp_flags & FUTEX_WP_REQUEUED) {
KASSERT(f != wp->wp_futex, ("futex != wp_futex"));
- LINUX_CTR5(sys_futex, "futex_sleep out error %d uaddr %p w"
+
+ if (error) {
+ LIN_SDT_PROBE5(futex, futex_sleep, requeue_error, error,
+ f->f_uaddr, wp, wp->wp_futex->f_uaddr,
+ wp->wp_futex->f_refcount);
+ }
+
+ LINUX_CTR5(sys_futex, "futex_sleep out error %d uaddr %p wp"
" %p requeued uaddr %p ref %d",
error, f->f_uaddr, wp, wp->wp_futex->f_uaddr,
wp->wp_futex->f_refcount);
futex_put(f, NULL);
f = wp->wp_futex;
FUTEX_LOCK(f);
- } else
+ } else {
+ if (error) {
+ LIN_SDT_PROBE3(futex, futex_sleep, sleep_error, error,
+ f->f_uaddr, wp);
+ }
LINUX_CTR3(sys_futex, "futex_sleep out error %d uaddr %p wp %p",
error, f->f_uaddr, wp);
+ }
futex_put(f, wp);
+
+ LIN_SDT_PROBE1(futex, futex_sleep, return, error);
return (error);
}
@@ -285,11 +475,17 @@
struct waiting_proc *wp, *wpt;
int count = 0;
- if (bitset == 0)
+ LIN_SDT_PROBE3(futex, futex_wake, entry, f, n, bitset);
+
+ if (bitset == 0) {
+ LIN_SDT_PROBE1(futex, futex_wake, return, EINVAL);
return (EINVAL);
+ }
FUTEX_ASSERT_LOCKED(f);
TAILQ_FOREACH_SAFE(wp, &f->f_waiting_proc, wp_list, wpt) {
+ LIN_SDT_PROBE3(futex, futex_wake, iterate, f->f_uaddr, wp,
+ f->f_refcount);
LINUX_CTR3(sys_futex, "futex_wake uaddr %p wp %p ref %d",
f->f_uaddr, wp, f->f_refcount);
/*
@@ -301,11 +497,13 @@
wp->wp_flags |= FUTEX_WP_REMOVED;
TAILQ_REMOVE(&f->f_waiting_proc, wp, wp_list);
+ LIN_SDT_PROBE1(futex, futex_wake, wakeup, wp);
wakeup_one(wp);
if (++count == n)
break;
}
+ LIN_SDT_PROBE1(futex, futex_wake, return, count);
return (count);
}
@@ -315,6 +513,8 @@
struct waiting_proc *wp, *wpt;
int count = 0;
+ LIN_SDT_PROBE4(futex, futex_requeue, entry, f, n, f2, n2);
+
FUTEX_ASSERT_LOCKED(f);
FUTEX_ASSERT_LOCKED(f2);
@@ -324,8 +524,11 @@
f->f_uaddr, wp);
wp->wp_flags |= FUTEX_WP_REMOVED;
TAILQ_REMOVE(&f->f_waiting_proc, wp, wp_list);
+ LIN_SDT_PROBE1(futex, futex_requeue, wakeup, wp);
wakeup_one(wp);
} else {
+ LIN_SDT_PROBE3(futex, futex_requeue, requeue,
+ f->f_uaddr, wp, f2->f_uaddr);
LINUX_CTR3(sys_futex, "futex_requeue uaddr %p wp %p to %p",
f->f_uaddr, wp, f2->f_uaddr);
wp->wp_flags |= FUTEX_WP_REQUEUED;
@@ -347,6 +550,7 @@
}
}
+ LIN_SDT_PROBE1(futex, futex_requeue, return, count);
return (count);
}
@@ -359,26 +563,42 @@
int timeout_hz;
int error;
- if (bitset == 0)
+ LIN_SDT_PROBE4(futex, futex_wait, entry, f, wp, ts, bitset);
+
+ if (bitset == 0) {
+ LIN_SDT_PROBE1(futex, futex_wait, return, EINVAL);
return (EINVAL);
+ }
+
f->f_bitset = bitset;
if (ts != NULL) {
error = copyin(ts, &timeout, sizeof(timeout));
- if (error)
+ if (error) {
+ LIN_SDT_PROBE1(futex, futex_wait, copyin_error, error);
+ LIN_SDT_PROBE1(futex, futex_wait, return, error);
return (error);
+ }
TIMESPEC_TO_TIMEVAL(&tv, &timeout);
error = itimerfix(&tv);
- if (error)
+ if (error) {
+ LIN_SDT_PROBE1(futex, futex_wait, itimerfix_error,
+ error);
+ LIN_SDT_PROBE1(futex, futex_wait, return, error);
return (error);
+ }
timeout_hz = tvtohz(&tv);
} else
timeout_hz = 0;
error = futex_sleep(f, wp, timeout_hz);
+ if (error) {
+ LIN_SDT_PROBE1(futex, futex_wait, sleep_error, error);
+ }
if (error == EWOULDBLOCK)
error = ETIMEDOUT;
+ LIN_SDT_PROBE1(futex, futex_wait, return, error);
return (error);
}
@@ -391,16 +611,16 @@
int cmparg = (encoded_op << 20) >> 20;
int oldval = 0, ret;
+ LIN_SDT_PROBE3(futex, futex_atomic_op, entry, td, encoded_op, uaddr);
+
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
-#ifdef DEBUG
- if (ldebug(sys_futex))
- printf("futex_atomic_op: op = %d, cmp = %d, oparg = %x, "
- "cmparg = %x, uaddr = %p\n",
- op, cmp, oparg, cmparg, uaddr);
-#endif
+ LIN_SDT_PROBE4(futex, futex_atomic_op, decoded_op, op, cmp, oparg,
+ cmparg);
+
/* XXX: Linux verifies access here and returns EFAULT */
+ LIN_SDT_PROBE0(futex, futex_atomic_op, missing_access_check);
switch (op) {
case FUTEX_OP_SET:
@@ -419,29 +639,42 @@
ret = futex_xorl(oparg, uaddr, &oldval);
break;
default:
+ LIN_SDT_PROBE1(futex, futex_atomic_op, unimplemented_op, op);
ret = -ENOSYS;
break;
}
- if (ret)
+ if (ret) {
+ LIN_SDT_PROBE1(futex, futex_atomic_op, return, ret);
return (ret);
+ }
switch (cmp) {
case FUTEX_OP_CMP_EQ:
- return (oldval == cmparg);
+ ret = (oldval == cmparg);
+ break;
case FUTEX_OP_CMP_NE:
- return (oldval != cmparg);
+ ret = (oldval != cmparg);
+ break;
case FUTEX_OP_CMP_LT:
- return (oldval < cmparg);
+ ret = (oldval < cmparg);
+ break;
case FUTEX_OP_CMP_GE:
- return (oldval >= cmparg);
+ ret = (oldval >= cmparg);
+ break;
case FUTEX_OP_CMP_LE:
- return (oldval <= cmparg);
+ ret = (oldval <= cmparg);
+ break;
case FUTEX_OP_CMP_GT:
- return (oldval > cmparg);
+ ret = (oldval > cmparg);
+ break;
default:
- return (-ENOSYS);
+ LIN_SDT_PROBE1(futex, futex_atomic_op, unimplemented_cmp, cmp);
+ ret = -ENOSYS;
}
+
+ LIN_SDT_PROBE1(futex, futex_atomic_op, return, ret);
+ return (ret);
}
int
@@ -454,6 +687,8 @@
int error;
uint32_t flags;
+ LIN_SDT_PROBE2(futex, linux_sys_futex, entry, td, args);
+
if (args->op & LINUX_FUTEX_PRIVATE_FLAG) {
flags = 0;
args->op &= ~LINUX_FUTEX_PRIVATE_FLAG;
@@ -469,8 +704,12 @@
clockrt = args->op & LINUX_FUTEX_CLOCK_REALTIME;
args->op = args->op & ~LINUX_FUTEX_CLOCK_REALTIME;
if (clockrt && args->op != LINUX_FUTEX_WAIT_BITSET &&
- args->op != LINUX_FUTEX_WAIT_REQUEUE_PI)
+ args->op != LINUX_FUTEX_WAIT_REQUEUE_PI) {
+ LIN_SDT_PROBE0(futex, linux_sys_futex,
+ unimplemented_clockswitch);
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, ENOSYS);
return (ENOSYS);
+ }
error = 0;
f = f2 = NULL;
@@ -481,31 +720,40 @@
/* FALLTHROUGH */
case LINUX_FUTEX_WAIT_BITSET:
-
+ LIN_SDT_PROBE3(futex, linux_sys_futex, debug_wait, args->uaddr,
+ args->val, args->val3);
LINUX_CTR3(sys_futex, "WAIT uaddr %p val %d val3 %d",
args->uaddr, args->val, args->val3);
-#ifdef DEBUG
- if (ldebug(sys_futex))
- printf(ARGS(sys_futex,
- "futex_wait uaddr %p val %d val3 %d"),
- args->uaddr, args->val, args->val3);
-#endif
+
error = futex_get(args->uaddr, &wp, &f,
flags | FUTEX_CREATE_WP);
- if (error)
+ if (error) {
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, error);
return (error);
+ }
+
error = copyin(args->uaddr, &val, sizeof(val));
if (error) {
+ LIN_SDT_PROBE1(futex, linux_sys_futex, copyin_error,
+ error);
LINUX_CTR1(sys_futex, "WAIT copyin failed %d",
error);
futex_put(f, wp);
+
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, error);
return (error);
}
if (val != args->val) {
+ LIN_SDT_PROBE4(futex, linux_sys_futex,
+ debug_wait_value_neq, args->uaddr, args->val, val,
+ args->val3);
LINUX_CTR4(sys_futex,
"WAIT uaddr %p val %d != uval %d val3 %d",
args->uaddr, args->val, val, args->val3);
futex_put(f, wp);
+
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return,
+ EWOULDBLOCK);
return (EWOULDBLOCK);
}
@@ -517,21 +765,22 @@
/* FALLTHROUGH */
case LINUX_FUTEX_WAKE_BITSET:
-
+ LIN_SDT_PROBE3(futex, linux_sys_futex, debug_wake, args->uaddr,
+ args->val, args->val3);
LINUX_CTR3(sys_futex, "WAKE uaddr %p val % d val3 %d",
args->uaddr, args->val, args->val3);
-#ifdef DEBUG
- if (ldebug(sys_futex))
- printf(ARGS(sys_futex, "futex_wake uaddr %p val %d val3 %d"),
- args->uaddr, args->val, args->val3);
-#endif
error = futex_get(args->uaddr, NULL, &f,
flags | FUTEX_DONTCREATE);
- if (error)
+ if (error) {
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, error);
return (error);
+ }
+
if (f == NULL) {
td->td_retval[0] = 0;
+
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, error);
return (error);
}
td->td_retval[0] = futex_wake(f, args->val, args->val3);
@@ -539,29 +788,30 @@
break;
case LINUX_FUTEX_CMP_REQUEUE:
-
+ LIN_SDT_PROBE5(futex, linux_sys_futex, debug_cmp_requeue,
+ args->uaddr, args->val, args->val3, args->uaddr2,
+ args->timeout);
LINUX_CTR5(sys_futex, "CMP_REQUEUE uaddr %p "
"val %d val3 %d uaddr2 %p val2 %d",
args->uaddr, args->val, args->val3, args->uaddr2,
(int)(unsigned long)args->timeout);
-#ifdef DEBUG
- if (ldebug(sys_futex))
- printf(ARGS(sys_futex, "futex_cmp_requeue uaddr %p "
- "val %d val3 %d uaddr2 %p val2 %d"),
- args->uaddr, args->val, args->val3, args->uaddr2,
- (int)(unsigned long)args->timeout);
-#endif
-
/*
* Linux allows this, we would not, it is an incorrect
* usage of declared ABI, so return EINVAL.
*/
- if (args->uaddr == args->uaddr2)
+ if (args->uaddr == args->uaddr2) {
+ LIN_SDT_PROBE0(futex, linux_sys_futex,
+ invalid_cmp_requeue_use);
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, EINVAL);
return (EINVAL);
+ }
+
error = futex_get(args->uaddr, NULL, &f, flags);
- if (error)
+ if (error) {
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, error);
return (error);
+ }
/*
* To avoid deadlocks return EINVAL if second futex
@@ -574,21 +824,31 @@
flags | FUTEX_DONTEXISTS);
if (error) {
futex_put(f, NULL);
+
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, error);
return (error);
}
error = copyin(args->uaddr, &val, sizeof(val));
if (error) {
+ LIN_SDT_PROBE1(futex, linux_sys_futex, copyin_error,
+ error);
LINUX_CTR1(sys_futex, "CMP_REQUEUE copyin failed %d",
error);
futex_put(f2, NULL);
futex_put(f, NULL);
+
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, error);
return (error);
}
if (val != args->val3) {
+ LIN_SDT_PROBE2(futex, linux_sys_futex,
+ debug_cmp_requeue_value_neq, args->val, val);
LINUX_CTR2(sys_futex, "CMP_REQUEUE val %d != uval %d",
args->val, val);
futex_put(f2, NULL);
futex_put(f, NULL);
+
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, EAGAIN);
return (EAGAIN);
}
@@ -599,26 +859,25 @@
break;
case LINUX_FUTEX_WAKE_OP:
-
+ LIN_SDT_PROBE5(futex, linux_sys_futex, debug_wake_op,
+ args->uaddr, args->op, args->val, args->uaddr2, args->val3);
LINUX_CTR5(sys_futex, "WAKE_OP "
"uaddr %p op %d val %x uaddr2 %p val3 %x",
args->uaddr, args->op, args->val,
args->uaddr2, args->val3);
-#ifdef DEBUG
- if (ldebug(sys_futex))
- printf(ARGS(sys_futex, "futex_wake_op "
- "uaddr %p op %d val %x uaddr2 %p val3 %x"),
- args->uaddr, args->op, args->val,
- args->uaddr2, args->val3);
-#endif
error = futex_get(args->uaddr, NULL, &f, flags);
- if (error)
+ if (error) {
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, error);
return (error);
+ }
+
if (args->uaddr != args->uaddr2)
error = futex_get(args->uaddr2, NULL, &f2, flags);
if (error) {
futex_put(f, NULL);
+
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, error);
return (error);
}
@@ -634,11 +893,19 @@
if (f2 != NULL)
futex_put(f2, NULL);
futex_put(f, NULL);
+
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return,
+ -op_ret);
return (-op_ret);
+ } else {
+ LIN_SDT_PROBE0(futex, linux_sys_futex,
+ unhandled_efault);
}
if (f2 != NULL)
futex_put(f2, NULL);
futex_put(f, NULL);
+
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, EFAULT);
return (EFAULT);
}
@@ -666,6 +933,8 @@
linux_msg(td,
"linux_sys_futex: "
"op LINUX_FUTEX_LOCK_PI not implemented\n");
+ LIN_SDT_PROBE0(futex, linux_sys_futex, unimplemented_lock_pi);
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, ENOSYS);
return (ENOSYS);
case LINUX_FUTEX_UNLOCK_PI:
@@ -673,6 +942,8 @@
linux_msg(td,
"linux_sys_futex: "
"op LINUX_FUTEX_UNLOCK_PI not implemented\n");
+ LIN_SDT_PROBE0(futex, linux_sys_futex, unimplemented_unlock_pi);
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, ENOSYS);
return (ENOSYS);
case LINUX_FUTEX_TRYLOCK_PI:
@@ -680,6 +951,9 @@
linux_msg(td,
"linux_sys_futex: "
"op LINUX_FUTEX_TRYLOCK_PI not implemented\n");
+ LIN_SDT_PROBE0(futex, linux_sys_futex,
+ unimplemented_trylock_pi);
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, ENOSYS);
return (ENOSYS);
case LINUX_FUTEX_REQUEUE:
@@ -696,7 +970,11 @@
"linux_sys_futex: "
"unsupported futex_requeue op\n");
em->flags |= LINUX_XDEPR_REQUEUEOP;
+ LIN_SDT_PROBE0(futex, linux_sys_futex,
+ deprecated_requeue);
}
+
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, EINVAL);
return (EINVAL);
case LINUX_FUTEX_WAIT_REQUEUE_PI:
@@ -704,6 +982,9 @@
linux_msg(td,
"linux_sys_futex: "
"op FUTEX_WAIT_REQUEUE_PI not implemented\n");
+ LIN_SDT_PROBE0(futex, linux_sys_futex,
+ unimplemented_wait_requeue_pi);
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, ENOSYS);
return (ENOSYS);
case LINUX_FUTEX_CMP_REQUEUE_PI:
@@ -711,14 +992,21 @@
linux_msg(td,
"linux_sys_futex: "
"op LINUX_FUTEX_CMP_REQUEUE_PI not implemented\n");
+ LIN_SDT_PROBE0(futex, linux_sys_futex,
+ unimplemented_cmp_requeue_pi);
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, ENOSYS);
return (ENOSYS);
default:
linux_msg(td,
"linux_sys_futex: unknown op %d\n", args->op);
+ LIN_SDT_PROBE1(futex, linux_sys_futex, unknown_operation,
+ args->op);
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, ENOSYS);
return (ENOSYS);
}
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, error);
return (error);
}
@@ -727,19 +1015,19 @@
{
struct linux_emuldata *em;
-#ifdef DEBUG
- if (ldebug(set_robust_list))
- printf(ARGS(set_robust_list, "head %p len %d"),
- args->head, args->len);
-#endif
+ LIN_SDT_PROBE2(futex, linux_set_robust_list, entry, td, args);
- if (args->len != sizeof(struct linux_robust_list_head))
+ if (args->len != sizeof(struct linux_robust_list_head)) {
+ LIN_SDT_PROBE0(futex, linux_set_robust_list, size_error);
+ LIN_SDT_PROBE1(futex, linux_set_robust_list, return, EINVAL);
return (EINVAL);
+ }
em = em_find(td->td_proc, EMUL_DOLOCK);
em->robust_futexes = args->head;
EMUL_UNLOCK(&emul_lock);
+ LIN_SDT_PROBE1(futex, linux_set_robust_list, return, 0);
return (0);
}
@@ -751,10 +1039,7 @@
l_size_t len = sizeof(struct linux_robust_list_head);
int error = 0;
-#ifdef DEBUG
- if (ldebug(get_robust_list))
- printf(ARGS(get_robust_list, ""));
-#endif
+ LIN_SDT_PROBE2(futex, linux_get_robust_list, entry, td, args);
if (!args->pid) {
em = em_find(td->td_proc, EMUL_DONTLOCK);
@@ -763,8 +1048,11 @@
struct proc *p;
p = pfind(args->pid);
- if (p == NULL)
+ if (p == NULL) {
+ LIN_SDT_PROBE1(futex, linux_get_robust_list, return,
+ ESRCH);
return (ESRCH);
+ }
em = em_find(p, EMUL_DONTLOCK);
/* XXX: ptrace? */
@@ -772,6 +1060,9 @@
priv_check(td, PRIV_CRED_SETEUID) ||
p_candebug(td, p)) {
PROC_UNLOCK(p);
+
+ LIN_SDT_PROBE1(futex, linux_get_robust_list, return,
+ EPERM);
return (EPERM);
}
head = em->robust_futexes;
@@ -780,11 +1071,20 @@
}
error = copyout(&len, args->len, sizeof(l_size_t));
- if (error)
+ if (error) {
+ LIN_SDT_PROBE1(futex, linux_get_robust_list, copyout_error,
+ error);
+ LIN_SDT_PROBE1(futex, linux_get_robust_list, return, EFAULT);
return (EFAULT);
+ }
error = copyout(head, args->head, sizeof(struct linux_robust_list_head));
+ if (error) {
+ LIN_SDT_PROBE1(futex, linux_get_robust_list, copyout_error,
+ error);
+ }
+ LIN_SDT_PROBE1(futex, linux_get_robust_list, return, error);
return (error);
}
@@ -795,15 +1095,24 @@
struct futex *f;
int error;
+ LIN_SDT_PROBE3(futex, handle_futex_death, entry, p, uaddr, pi);
+
retry:
- if (copyin(uaddr, &uval, 4))
+ error = copyin(uaddr, &uval, 4);
+ if (error) {
+ LIN_SDT_PROBE1(futex, handle_futex_death, copyin_error, error);
+ LIN_SDT_PROBE1(futex, handle_futex_death, return, EFAULT);
return (EFAULT);
+ }
if ((uval & FUTEX_TID_MASK) == p->p_pid) {
mval = (uval & FUTEX_WAITERS) | FUTEX_OWNER_DIED;
nval = casuword32(uaddr, uval, mval);
- if (nval == -1)
+ if (nval == -1) {
+ LIN_SDT_PROBE1(futex, handle_futex_death, return,
+ EFAULT);
return (EFAULT);
+ }
if (nval != uval)
goto retry;
@@ -811,8 +1120,11 @@
if (!pi && (uval & FUTEX_WAITERS)) {
error = futex_get(uaddr, NULL, &f,
FUTEX_DONTCREATE | FUTEX_SHARED);
- if (error)
+ if (error) {
+ LIN_SDT_PROBE1(futex, handle_futex_death,
+ return, error);
return (error);
+ }
if (f != NULL) {
futex_wake(f, 1, FUTEX_BITSET_MATCH_ANY);
futex_put(f, NULL);
@@ -820,6 +1132,7 @@
}
}
+ LIN_SDT_PROBE1(futex, handle_futex_death, return, 0);
return (0);
}
@@ -828,13 +1141,21 @@
struct linux_robust_list **head, int *pi)
{
l_ulong uentry;
+ int error;
- if (copyin((const void *)head, &uentry, sizeof(l_ulong)))
+ LIN_SDT_PROBE3(futex, fetch_robust_entry, entry, entry, head, pi);
+
+ error = copyin((const void *)head, &uentry, sizeof(l_ulong));
+ if (error) {
+ LIN_SDT_PROBE1(futex, fetch_robust_entry, copyin_error, error);
+ LIN_SDT_PROBE1(futex, fetch_robust_entry, return, EFAULT);
return (EFAULT);
+ }
*entry = (void *)(uentry & ~1UL);
*pi = uentry & 1;
+ LIN_SDT_PROBE1(futex, fetch_robust_entry, return, 0);
return (0);
}
@@ -847,31 +1168,49 @@
unsigned int limit = 2048, pi, next_pi, pip;
struct linux_emuldata *em;
l_long futex_offset;
- int rc;
+ int rc, error;
+
+ LIN_SDT_PROBE1(futex, release_futexes, entry, p);
em = em_find(p, EMUL_DONTLOCK);
head = em->robust_futexes;
- if (head == NULL)
+ if (head == NULL) {
+ LIN_SDT_PROBE0(futex, release_futexes, return);
return;
+ }
- if (fetch_robust_entry(&entry, PTRIN(&head->list.next), &pi))
+ if (fetch_robust_entry(&entry, PTRIN(&head->list.next), &pi)) {
+ LIN_SDT_PROBE0(futex, release_futexes, return);
return;
+ }
- if (copyin(&head->futex_offset, &futex_offset, sizeof(futex_offset)))
+ error = copyin(&head->futex_offset, &futex_offset,
+ sizeof(futex_offset));
+ if (error) {
+ LIN_SDT_PROBE1(futex, release_futexes, copyin_error, error);
+ LIN_SDT_PROBE0(futex, release_futexes, return);
return;
+ }
- if (fetch_robust_entry(&pending, PTRIN(&head->pending_list), &pip))
+ if (fetch_robust_entry(&pending, PTRIN(&head->pending_list), &pip)) {
+ LIN_SDT_PROBE0(futex, release_futexes, return);
return;
+ }
while (entry != &head->list) {
rc = fetch_robust_entry(&next_entry, PTRIN(&entry->next), &next_pi);
if (entry != pending)
- if (handle_futex_death(p, (uint32_t *)entry + futex_offset, pi))
+ if (handle_futex_death(p,
+ (uint32_t *)entry + futex_offset, pi)) {
+ LIN_SDT_PROBE0(futex, release_futexes, return);
return;
- if (rc)
+ }
+ if (rc) {
+ LIN_SDT_PROBE0(futex, release_futexes, return);
return;
+ }
entry = next_entry;
pi = next_pi;
@@ -884,4 +1223,6 @@
if (pending)
handle_futex_death(p, (uint32_t *)pending + futex_offset, pip);
+
+ LIN_SDT_PROBE0(futex, release_futexes, return);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/linux/linux_mib.c
--- a/head/sys/compat/linux/linux_mib.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/linux/linux_mib.c Wed Jul 25 16:45:04 2012 +0300
@@ -27,10 +27,14 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/linux/linux_mib.c 227309 2011-11-07 15:43:11Z ed $");
+__FBSDID("$FreeBSD: head/sys/compat/linux/linux_mib.c 235063 2012-05-05 19:42:38Z netchild $");
+
+#include "opt_compat.h"
+#include "opt_kdtrace.h"
#include <sys/param.h>
#include <sys/kernel.h>
+#include <sys/sdt.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
#include <sys/proc.h>
@@ -41,15 +45,81 @@
#include <sys/mutex.h>
#include <sys/sx.h>
-#include "opt_compat.h"
-
#ifdef COMPAT_LINUX32
#include <machine/../linux32/linux.h>
#else
#include <machine/../linux/linux.h>
#endif
+#include <compat/linux/linux_dtrace.h>
#include <compat/linux/linux_mib.h>
+/* DTrace init */
+LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
+
+/**
+ * DTrace probes in this module.
+ */
+LIN_SDT_PROBE_DEFINE0(mib, linux_sysctl_osname, entry);
+LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_osname, sysctl_string_error, "int");
+LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_osname, return, "int");
+
+LIN_SDT_PROBE_DEFINE0(mib, linux_sysctl_osrelease, entry);
+LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_osrelease, sysctl_string_error, "int");
+LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_osrelease, return, "int");
+LIN_SDT_PROBE_DEFINE0(mib, linux_sysctl_oss_version, entry);
+LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_oss_version, sysctl_string_error,
+ "int");
+LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_oss_version, return, "int");
+LIN_SDT_PROBE_DEFINE2(mib, linux_map_osrel, entry, "char *", "int *");
+LIN_SDT_PROBE_DEFINE1(mib, linux_map_osrel, return, "int");
+LIN_SDT_PROBE_DEFINE2(mib, linux_get_prison, entry, "struct prison *",
+ "struct prison **");
+LIN_SDT_PROBE_DEFINE1(mib, linux_get_prison, return, "struct linux_prison *");
+LIN_SDT_PROBE_DEFINE2(mib, linux_alloc_prison, entry, "struct prison *",
+ "struct linux_prison **");
+LIN_SDT_PROBE_DEFINE1(mib, linux_alloc_prison, return, "int");
+LIN_SDT_PROBE_DEFINE2(mib, linux_prison_create, entry, "void *", "void *");
+LIN_SDT_PROBE_DEFINE1(mib, linux_prison_create, vfs_copyopt_error, "int");
+LIN_SDT_PROBE_DEFINE1(mib, linux_prison_create, return, "int");
+LIN_SDT_PROBE_DEFINE2(mib, linux_prison_check, entry, "void *", "void *");
+LIN_SDT_PROBE_DEFINE1(mib, linux_prison_check, vfs_copyopt_error, "int");
+LIN_SDT_PROBE_DEFINE1(mib, linux_prison_check, vfs_getopt_error, "int");
+LIN_SDT_PROBE_DEFINE1(mib, linux_prison_check, return, "int");
+LIN_SDT_PROBE_DEFINE2(mib, linux_prison_set, entry, "void *", "void *");
+LIN_SDT_PROBE_DEFINE1(mib, linux_prison_set, vfs_copyopt_error, "int");
+LIN_SDT_PROBE_DEFINE1(mib, linux_prison_set, vfs_getopt_error, "int");
+LIN_SDT_PROBE_DEFINE1(mib, linux_prison_set, return, "int");
+LIN_SDT_PROBE_DEFINE2(mib, linux_prison_get, entry, "void *", "void *");
+LIN_SDT_PROBE_DEFINE1(mib, linux_prison_get, vfs_setopt_error, "int");
+LIN_SDT_PROBE_DEFINE1(mib, linux_prison_get, vfs_setopts_error, "int");
+LIN_SDT_PROBE_DEFINE1(mib, linux_prison_get, return, "int");
+LIN_SDT_PROBE_DEFINE1(mib, linux_prison_destructor, entry, "void *");
+LIN_SDT_PROBE_DEFINE0(mib, linux_prison_destructor, return);
+LIN_SDT_PROBE_DEFINE0(mib, linux_osd_jail_register, entry);
+LIN_SDT_PROBE_DEFINE0(mib, linux_osd_jail_register, return);
+LIN_SDT_PROBE_DEFINE0(mib, linux_osd_jail_deregister, entry);
+LIN_SDT_PROBE_DEFINE0(mib, linux_osd_jail_deregister, return);
+LIN_SDT_PROBE_DEFINE2(mib, linux_get_osname, entry, "struct thread *",
+ "char *");
+LIN_SDT_PROBE_DEFINE0(mib, linux_get_osname, return);
+LIN_SDT_PROBE_DEFINE2(mib, linux_set_osname, entry, "struct thread *",
+ "char *");
+LIN_SDT_PROBE_DEFINE1(mib, linux_set_osname, return, "int");
+LIN_SDT_PROBE_DEFINE2(mib, linux_get_osrelease, entry, "struct thread *",
+ "char *");
+LIN_SDT_PROBE_DEFINE0(mib, linux_get_osrelease, return);
+LIN_SDT_PROBE_DEFINE1(mib, linux_kernver, entry, "struct thread *");
+LIN_SDT_PROBE_DEFINE1(mib, linux_kernver, return, "int");
+LIN_SDT_PROBE_DEFINE2(mib, linux_set_osrelease, entry, "struct thread *",
+ "char *");
+LIN_SDT_PROBE_DEFINE1(mib, linux_set_osrelease, return, "int");
+LIN_SDT_PROBE_DEFINE1(mib, linux_get_oss_version, entry, "struct thread *");
+LIN_SDT_PROBE_DEFINE1(mib, linux_get_oss_version, return, "int");
+
+LIN_SDT_PROBE_DEFINE2(mib, linux_set_oss_version, entry, "struct thread *",
+ "int");
+LIN_SDT_PROBE_DEFINE1(mib, linux_set_oss_version, return, "int");
+
struct linux_prison {
char pr_osname[LINUX_MAX_UTSNAME];
char pr_osrelease[LINUX_MAX_UTSNAME];
@@ -79,11 +149,19 @@
char osname[LINUX_MAX_UTSNAME];
int error;
+ LIN_SDT_PROBE0(mib, linux_sysctl_osname, entry);
+
linux_get_osname(req->td, osname);
error = sysctl_handle_string(oidp, osname, LINUX_MAX_UTSNAME, req);
- if (error || req->newptr == NULL)
+ if (error != 0 || req->newptr == NULL) {
+ LIN_SDT_PROBE1(mib, linux_sysctl_osname, sysctl_string_error,
+ error);
+ LIN_SDT_PROBE1(mib, linux_sysctl_osname, return, error);
return (error);
+ }
error = linux_set_osname(req->td, osname);
+
+ LIN_SDT_PROBE1(mib, linux_sysctl_osname, return, error);
return (error);
}
@@ -98,11 +176,19 @@
char osrelease[LINUX_MAX_UTSNAME];
int error;
+ LIN_SDT_PROBE0(mib, linux_sysctl_osrelease, entry);
+
linux_get_osrelease(req->td, osrelease);
error = sysctl_handle_string(oidp, osrelease, LINUX_MAX_UTSNAME, req);
- if (error || req->newptr == NULL)
+ if (error != 0 || req->newptr == NULL) {
+ LIN_SDT_PROBE1(mib, linux_sysctl_osrelease, sysctl_string_error,
+ error);
+ LIN_SDT_PROBE1(mib, linux_sysctl_osrelease, return, error);
return (error);
+ }
error = linux_set_osrelease(req->td, osrelease);
+
+ LIN_SDT_PROBE1(mib, linux_sysctl_osrelease, return, error);
return (error);
}
@@ -117,11 +203,19 @@
int oss_version;
int error;
+ LIN_SDT_PROBE0(mib, linux_sysctl_oss_version, entry);
+
oss_version = linux_get_oss_version(req->td);
error = sysctl_handle_int(oidp, &oss_version, 0, req);
- if (error || req->newptr == NULL)
+ if (error != 0 || req->newptr == NULL) {
+ LIN_SDT_PROBE1(mib, linux_sysctl_oss_version,
+ sysctl_string_error, error);
+ LIN_SDT_PROBE1(mib, linux_sysctl_oss_version, return, error);
return (error);
+ }
error = linux_set_oss_version(req->td, oss_version);
+
+ LIN_SDT_PROBE1(mib, linux_sysctl_oss_version, return, error);
return (error);
}
@@ -139,25 +233,37 @@
char *sep, *eosrelease;
int len, v0, v1, v2, v;
+ LIN_SDT_PROBE2(mib, linux_map_osrel, entry, osrelease, osrel);
+
len = strlen(osrelease);
eosrelease = osrelease + len;
v0 = strtol(osrelease, &sep, 10);
- if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.')
+ if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.') {
+ LIN_SDT_PROBE1(mib, linux_map_osrel, return, EINVAL);
return (EINVAL);
+ }
osrelease = sep + 1;
v1 = strtol(osrelease, &sep, 10);
- if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.')
+ if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.') {
+ LIN_SDT_PROBE1(mib, linux_map_osrel, return, EINVAL);
return (EINVAL);
+ }
osrelease = sep + 1;
v2 = strtol(osrelease, &sep, 10);
- if (osrelease == sep || sep != eosrelease)
+ if (osrelease == sep || sep != eosrelease) {
+ LIN_SDT_PROBE1(mib, linux_map_osrel, return, EINVAL);
return (EINVAL);
+ }
v = v0 * 1000000 + v1 * 1000 + v2;
- if (v < 1000000)
+ if (v < 1000000) {
+ LIN_SDT_PROBE1(mib, linux_map_osrel, return, EINVAL);
return (EINVAL);
+ }
*osrel = v;
+
+ LIN_SDT_PROBE1(mib, linux_map_osrel, return, 0);
return (0);
}
@@ -171,6 +277,8 @@
struct prison *pr;
struct linux_prison *lpr;
+ LIN_SDT_PROBE2(mib, linux_get_prison, entry, spr, prp);
+
if (!linux_osd_jail_slot)
/* In case osd_register failed. */
spr = &prison0;
@@ -184,6 +292,8 @@
mtx_unlock(&pr->pr_mtx);
}
*prp = pr;
+
+ LIN_SDT_PROBE1(mib, linux_get_prison, return, lpr);
return (lpr);
}
@@ -198,6 +308,8 @@
struct linux_prison *lpr, *nlpr;
int error;
+ LIN_SDT_PROBE2(mib, linux_alloc_prison, entry, pr, lprp);
+
/* If this prison already has Linux info, return that. */
error = 0;
lpr = linux_find_prison(pr, &ppr);
@@ -230,6 +342,8 @@
*lprp = lpr;
else
mtx_unlock(&pr->pr_mtx);
+
+ LIN_SDT_PROBE1(mib, linux_alloc_prison, return, error);
return (error);
}
@@ -241,16 +355,26 @@
{
struct prison *pr = obj;
struct vfsoptlist *opts = data;
- int jsys;
+ int jsys, error;
- if (vfs_copyopt(opts, "linux", &jsys, sizeof(jsys)) == 0 &&
- jsys == JAIL_SYS_INHERIT)
+ LIN_SDT_PROBE2(mib, linux_prison_create, entry, obj, data);
+
+ error = vfs_copyopt(opts, "linux", &jsys, sizeof(jsys));
+ if (error != 0) {
+ LIN_SDT_PROBE1(mib, linux_prison_create, vfs_copyopt_error,
+ error);
+ } else if (jsys == JAIL_SYS_INHERIT) {
+ LIN_SDT_PROBE1(mib, linux_prison_create, return, 0);
return (0);
+ }
/*
* Inherit a prison's initial values from its parent
* (different from JAIL_SYS_INHERIT which also inherits changes).
*/
- return linux_alloc_prison(pr, NULL);
+ error = linux_alloc_prison(pr, NULL);
+
+ LIN_SDT_PROBE1(mib, linux_prison_create, return, error);
+ return (error);
}
static int
@@ -260,44 +384,81 @@
char *osname, *osrelease;
int error, jsys, len, osrel, oss_version;
+ LIN_SDT_PROBE2(mib, linux_prison_check, entry, obj, data);
+
/* Check that the parameters are correct. */
error = vfs_copyopt(opts, "linux", &jsys, sizeof(jsys));
+ if (error != 0) {
+ LIN_SDT_PROBE1(mib, linux_prison_check, vfs_copyopt_error,
+ error);
+ }
if (error != ENOENT) {
- if (error != 0)
+ if (error != 0) {
+ LIN_SDT_PROBE1(mib, linux_prison_check, return, error);
return (error);
- if (jsys != JAIL_SYS_NEW && jsys != JAIL_SYS_INHERIT)
+ }
+ if (jsys != JAIL_SYS_NEW && jsys != JAIL_SYS_INHERIT) {
+ LIN_SDT_PROBE1(mib, linux_prison_check, return, EINVAL);
return (EINVAL);
+ }
}
error = vfs_getopt(opts, "linux.osname", (void **)&osname, &len);
+ if (error != 0) {
+ LIN_SDT_PROBE1(mib, linux_prison_check, vfs_getopt_error,
+ error);
+ }
if (error != ENOENT) {
- if (error != 0)
+ if (error != 0) {
+ LIN_SDT_PROBE1(mib, linux_prison_check, return, error);
return (error);
- if (len == 0 || osname[len - 1] != '\0')
+ }
+ if (len == 0 || osname[len - 1] != '\0') {
+ LIN_SDT_PROBE1(mib, linux_prison_check, return, EINVAL);
return (EINVAL);
+ }
if (len > LINUX_MAX_UTSNAME) {
vfs_opterror(opts, "linux.osname too long");
+ LIN_SDT_PROBE1(mib, linux_prison_check, return,
+ ENAMETOOLONG);
return (ENAMETOOLONG);
}
}
error = vfs_getopt(opts, "linux.osrelease", (void **)&osrelease, &len);
+ if (error != 0) {
+ LIN_SDT_PROBE1(mib, linux_prison_check, vfs_getopt_error,
+ error);
+ }
if (error != ENOENT) {
- if (error != 0)
+ if (error != 0) {
+ LIN_SDT_PROBE1(mib, linux_prison_check, return, error);
return (error);
- if (len == 0 || osrelease[len - 1] != '\0')
+ }
+ if (len == 0 || osrelease[len - 1] != '\0') {
+ LIN_SDT_PROBE1(mib, linux_prison_check, return, EINVAL);
return (EINVAL);
+ }
if (len > LINUX_MAX_UTSNAME) {
vfs_opterror(opts, "linux.osrelease too long");
+ LIN_SDT_PROBE1(mib, linux_prison_check, return,
+ ENAMETOOLONG);
return (ENAMETOOLONG);
}
error = linux_map_osrel(osrelease, &osrel);
if (error != 0) {
vfs_opterror(opts, "linux.osrelease format error");
+ LIN_SDT_PROBE1(mib, linux_prison_check, return, error);
return (error);
}
}
error = vfs_copyopt(opts, "linux.oss_version", &oss_version,
sizeof(oss_version));
- return (error == ENOENT ? 0 : error);
+ if (error != 0)
+ LIN_SDT_PROBE1(mib, linux_prison_check, vfs_copyopt_error, error);
+
+ if (error == ENOENT)
+ error = 0;
+ LIN_SDT_PROBE1(mib, linux_prison_check, return, error);
+ return (error);
}
static int
@@ -309,22 +470,32 @@
char *osname, *osrelease;
int error, gotversion, jsys, len, oss_version;
+ LIN_SDT_PROBE2(mib, linux_prison_set, entry, obj, data);
+
/* Set the parameters, which should be correct. */
error = vfs_copyopt(opts, "linux", &jsys, sizeof(jsys));
+ if (error != 0)
+ LIN_SDT_PROBE1(mib, linux_prison_set, vfs_copyopt_error, error);
if (error == ENOENT)
jsys = -1;
error = vfs_getopt(opts, "linux.osname", (void **)&osname, &len);
+ if (error != 0)
+ LIN_SDT_PROBE1(mib, linux_prison_set, vfs_getopt_error, error);
if (error == ENOENT)
osname = NULL;
else
jsys = JAIL_SYS_NEW;
error = vfs_getopt(opts, "linux.osrelease", (void **)&osrelease, &len);
+ if (error != 0)
+ LIN_SDT_PROBE1(mib, linux_prison_set, vfs_getopt_error, error);
if (error == ENOENT)
osrelease = NULL;
else
jsys = JAIL_SYS_NEW;
error = vfs_copyopt(opts, "linux.oss_version", &oss_version,
sizeof(oss_version));
+ if (error != 0)
+ LIN_SDT_PROBE1(mib, linux_prison_set, vfs_copyopt_error, error);
if (error == ENOENT)
gotversion = 0;
else {
@@ -346,12 +517,15 @@
error = linux_alloc_prison(pr, &lpr);
if (error) {
mtx_unlock(&pr->pr_mtx);
+ LIN_SDT_PROBE1(mib, linux_prison_set, return, error);
return (error);
}
if (osrelease) {
error = linux_map_osrel(osrelease, &lpr->pr_osrel);
if (error) {
mtx_unlock(&pr->pr_mtx);
+ LIN_SDT_PROBE1(mib, linux_prison_set, return,
+ error);
return (error);
}
strlcpy(lpr->pr_osrelease, osrelease,
@@ -363,6 +537,8 @@
lpr->pr_oss_version = oss_version;
mtx_unlock(&pr->pr_mtx);
}
+
+ LIN_SDT_PROBE1(mib, linux_prison_set, return, 0);
return (0);
}
@@ -385,43 +561,74 @@
static int version0;
+ LIN_SDT_PROBE2(mib, linux_prison_get, entry, obj, data);
+
/* See if this prison is the one with the Linux info. */
lpr = linux_find_prison(pr, &ppr);
i = (ppr == pr) ? JAIL_SYS_NEW : JAIL_SYS_INHERIT;
error = vfs_setopt(opts, "linux", &i, sizeof(i));
- if (error != 0 && error != ENOENT)
- goto done;
+ if (error != 0) {
+ LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopt_error, error);
+ if (error != ENOENT)
+ goto done;
+ }
if (i) {
error = vfs_setopts(opts, "linux.osname", lpr->pr_osname);
- if (error != 0 && error != ENOENT)
- goto done;
+ if (error != 0) {
+ LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopts_error,
+ error);
+ if (error != ENOENT)
+ goto done;
+ }
error = vfs_setopts(opts, "linux.osrelease", lpr->pr_osrelease);
- if (error != 0 && error != ENOENT)
- goto done;
+ if (error != 0) {
+ LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopts_error,
+ error);
+ if (error != ENOENT)
+ goto done;
+ }
error = vfs_setopt(opts, "linux.oss_version",
&lpr->pr_oss_version, sizeof(lpr->pr_oss_version));
- if (error != 0 && error != ENOENT)
- goto done;
+ if (error != 0) {
+ LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopt_error,
+ error);
+ if(error != ENOENT)
+ goto done;
+ }
} else {
/*
* If this prison is inheriting its Linux info, report
* empty/zero parameters.
*/
error = vfs_setopts(opts, "linux.osname", "");
- if (error != 0 && error != ENOENT)
- goto done;
+ if (error != 0) {
+ LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopts_error,
+ error);
+ if(error != ENOENT)
+ goto done;
+ }
error = vfs_setopts(opts, "linux.osrelease", "");
- if (error != 0 && error != ENOENT)
- goto done;
+ if (error != 0) {
+ LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopts_error,
+ error);
+ if(error != ENOENT)
+ goto done;
+ }
error = vfs_setopt(opts, "linux.oss_version", &version0,
sizeof(lpr->pr_oss_version));
- if (error != 0 && error != ENOENT)
- goto done;
+ if (error != 0) {
+ LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopt_error,
+ error);
+ if(error != ENOENT)
+ goto done;
+ }
}
error = 0;
done:
mtx_unlock(&ppr->pr_mtx);
+
+ LIN_SDT_PROBE1(mib, linux_prison_get, return, error);
return (error);
}
@@ -429,7 +636,9 @@
linux_prison_destructor(void *data)
{
+ LIN_SDT_PROBE1(mib, linux_prison_destructor, entry, data);
free(data, M_PRISON);
+ LIN_SDT_PROBE0(mib, linux_prison_destructor, return);
}
void
@@ -443,6 +652,8 @@
[PR_METHOD_CHECK] = linux_prison_check
};
+ LIN_SDT_PROBE0(mib, linux_osd_jail_register, entry);
+
linux_osd_jail_slot =
osd_jail_register(linux_prison_destructor, methods);
if (linux_osd_jail_slot > 0) {
@@ -452,14 +663,20 @@
(void)linux_alloc_prison(pr, NULL);
sx_xunlock(&allprison_lock);
}
+
+ LIN_SDT_PROBE0(mib, linux_osd_jail_register, return);
}
void
linux_osd_jail_deregister(void)
{
+ LIN_SDT_PROBE0(mib, linux_osd_jail_register, entry);
+
if (linux_osd_jail_slot)
osd_jail_deregister(linux_osd_jail_slot);
+
+ LIN_SDT_PROBE0(mib, linux_osd_jail_register, return);
}
void
@@ -468,9 +685,13 @@
struct prison *pr;
struct linux_prison *lpr;
+ LIN_SDT_PROBE2(mib, linux_get_osname, entry, td, dst);
+
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
bcopy(lpr->pr_osname, dst, LINUX_MAX_UTSNAME);
mtx_unlock(&pr->pr_mtx);
+
+ LIN_SDT_PROBE0(mib, linux_get_osname, return);
}
static int
@@ -479,9 +700,13 @@
struct prison *pr;
struct linux_prison *lpr;
+ LIN_SDT_PROBE2(mib, linux_set_osname, entry, td, osname);
+
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
strlcpy(lpr->pr_osname, osname, LINUX_MAX_UTSNAME);
mtx_unlock(&pr->pr_mtx);
+
+ LIN_SDT_PROBE1(mib, linux_set_osname, return, 0);
return (0);
}
@@ -491,9 +716,13 @@
struct prison *pr;
struct linux_prison *lpr;
+ LIN_SDT_PROBE2(mib, linux_get_osrelease, entry, td, dst);
+
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
bcopy(lpr->pr_osrelease, dst, LINUX_MAX_UTSNAME);
mtx_unlock(&pr->pr_mtx);
+
+ LIN_SDT_PROBE0(mib, linux_get_osrelease, return);
}
int
@@ -503,9 +732,13 @@
struct linux_prison *lpr;
int osrel;
+ LIN_SDT_PROBE1(mib, linux_kernver, entry, td);
+
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
osrel = lpr->pr_osrel;
mtx_unlock(&pr->pr_mtx);
+
+ LIN_SDT_PROBE1(mib, linux_kernver, return, osrel);
return (osrel);
}
@@ -516,11 +749,15 @@
struct linux_prison *lpr;
int error;
+ LIN_SDT_PROBE2(mib, linux_set_osrelease, entry, td, osrelease);
+
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
error = linux_map_osrel(osrelease, &lpr->pr_osrel);
if (error == 0)
strlcpy(lpr->pr_osrelease, osrelease, LINUX_MAX_UTSNAME);
mtx_unlock(&pr->pr_mtx);
+
+ LIN_SDT_PROBE1(mib, linux_set_osrelease, return, error);
return (error);
}
@@ -531,9 +768,13 @@
struct linux_prison *lpr;
int version;
+ LIN_SDT_PROBE1(mib, linux_get_oss_version, entry, td);
+
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
version = lpr->pr_oss_version;
mtx_unlock(&pr->pr_mtx);
+
+ LIN_SDT_PROBE1(mib, linux_get_oss_version, return, version);
return (version);
}
@@ -543,13 +784,18 @@
struct prison *pr;
struct linux_prison *lpr;
+ LIN_SDT_PROBE2(mib, linux_set_oss_version, entry, td, oss_version);
+
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
lpr->pr_oss_version = oss_version;
mtx_unlock(&pr->pr_mtx);
+
+ LIN_SDT_PROBE1(mib, linux_set_oss_version, return, 0);
return (0);
}
#if defined(DEBUG) || defined(KTR)
+/* XXX: can be removed when every ldebug(...) and KTR stuff are removed. */
u_char linux_debug_map[howmany(LINUX_SYS_MAXSYSCALL, sizeof(u_char))];
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/linux/linux_misc.c
--- a/head/sys/compat/linux/linux_misc.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/linux/linux_misc.c Wed Jul 25 16:45:04 2012 +0300
@@ -28,9 +28,10 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/linux/linux_misc.c 231885 2012-02-17 23:47:16Z kib $");
+__FBSDID("$FreeBSD: head/sys/compat/linux/linux_misc.c 235063 2012-05-05 19:42:38Z netchild $");
#include "opt_compat.h"
+#include "opt_kdtrace.h"
#include <sys/param.h>
#include <sys/blist.h>
@@ -53,6 +54,7 @@
#include <sys/racct.h>
#include <sys/resourcevar.h>
#include <sys/sched.h>
+#include <sys/sdt.h>
#include <sys/signalvar.h>
#include <sys/stat.h>
#include <sys/syscallsubr.h>
@@ -83,6 +85,7 @@
#include <machine/../linux/linux_proto.h>
#endif
+#include <compat/linux/linux_dtrace.h>
#include <compat/linux/linux_file.h>
#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_signal.h>
@@ -91,6 +94,17 @@
#include <compat/linux/linux_emul.h>
#include <compat/linux/linux_misc.h>
+/* DTrace init */
+LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
+
+/* Linuxulator-global DTrace probes */
+LIN_SDT_PROBE_DECLARE(locks, emul_lock, locked);
+LIN_SDT_PROBE_DECLARE(locks, emul_lock, unlock);
+LIN_SDT_PROBE_DECLARE(locks, emul_shared_rlock, locked);
+LIN_SDT_PROBE_DECLARE(locks, emul_shared_rlock, unlock);
+LIN_SDT_PROBE_DECLARE(locks, emul_shared_wlock, locked);
+LIN_SDT_PROBE_DECLARE(locks, emul_shared_wlock, unlock);
+
int stclohz; /* Statistics clock frequency */
static unsigned int linux_to_bsd_resource[LINUX_RLIM_NLIMITS] = {
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/linux/linux_sysctl.c
--- a/head/sys/compat/linux/linux_sysctl.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/linux/linux_sysctl.c Wed Jul 25 16:45:04 2012 +0300
@@ -27,15 +27,18 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/compat/linux/linux_sysctl.c 235063 2012-05-05 19:42:38Z netchild $");
#include "opt_compat.h"
+#include "opt_kdtrace.h"
#include <sys/param.h>
+#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/proc.h>
+#include <sys/sdt.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/sbuf.h>
@@ -48,6 +51,7 @@
#include <machine/../linux/linux_proto.h>
#endif
+#include <compat/linux/linux_dtrace.h>
#include <compat/linux/linux_util.h>
#define LINUX_CTL_KERN 1
@@ -65,23 +69,49 @@
#define LINUX_KERN_OSREV 3
#define LINUX_KERN_VERSION 4
+/* DTrace init */
+LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
+
+/**
+ * DTrace probes in this module.
+ */
+LIN_SDT_PROBE_DEFINE2(sysctl, handle_string, entry, "struct l___sysctl_args *",
+ "char *");
+LIN_SDT_PROBE_DEFINE1(sysctl, handle_string, copyout_error, "int");
+LIN_SDT_PROBE_DEFINE1(sysctl, handle_string, return, "int");
+LIN_SDT_PROBE_DEFINE2(sysctl, linux_sysctl, entry, "struct l___sysctl_args *",
+ "struct thread *");
+LIN_SDT_PROBE_DEFINE1(sysctl, linux_sysctl, copyin_error, "int");
+LIN_SDT_PROBE_DEFINE2(sysctl, linux_sysctl, wrong_length, "int", "int");
+LIN_SDT_PROBE_DEFINE1(sysctl, linux_sysctl, unsupported_sysctl, "char *");
+LIN_SDT_PROBE_DEFINE1(sysctl, linux_sysctl, return, "int");
+
static int
handle_string(struct l___sysctl_args *la, char *value)
{
int error;
+ LIN_SDT_PROBE2(sysctl, handle_string, entry, la, value);
+
if (la->oldval != 0) {
l_int len = strlen(value);
error = copyout(value, PTRIN(la->oldval), len + 1);
if (!error && la->oldlenp != 0)
error = copyout(&len, PTRIN(la->oldlenp), sizeof(len));
- if (error)
+ if (error) {
+ LIN_SDT_PROBE1(sysctl, handle_string, copyout_error,
+ error);
+ LIN_SDT_PROBE1(sysctl, handle_string, return, error);
return (error);
+ }
}
- if (la->newval != 0)
+ if (la->newval != 0) {
+ LIN_SDT_PROBE1(sysctl, handle_string, return, ENOTDIR);
return (ENOTDIR);
+ }
+ LIN_SDT_PROBE1(sysctl, handle_string, return, 0);
return (0);
}
@@ -91,18 +121,30 @@
struct l___sysctl_args la;
struct sbuf *sb;
l_int *mib;
+ char *sysctl_string;
int error, i;
+ LIN_SDT_PROBE2(sysctl, linux_sysctl, entry, td, args->args);
+
error = copyin(args->args, &la, sizeof(la));
- if (error)
+ if (error) {
+ LIN_SDT_PROBE1(sysctl, linux_sysctl, copyin_error, error);
+ LIN_SDT_PROBE1(sysctl, linux_sysctl, return, error);
return (error);
+ }
- if (la.nlen <= 0 || la.nlen > LINUX_CTL_MAXNAME)
+ if (la.nlen <= 0 || la.nlen > LINUX_CTL_MAXNAME) {
+ LIN_SDT_PROBE2(sysctl, linux_sysctl, wrong_length, la.nlen,
+ LINUX_CTL_MAXNAME);
+ LIN_SDT_PROBE1(sysctl, linux_sysctl, return, ENOTDIR);
return (ENOTDIR);
+ }
mib = malloc(la.nlen * sizeof(l_int), M_TEMP, M_WAITOK);
error = copyin(PTRIN(la.name), mib, la.nlen * sizeof(l_int));
if (error) {
+ LIN_SDT_PROBE1(sysctl, linux_sysctl, copyin_error, error);
+ LIN_SDT_PROBE1(sysctl, linux_sysctl, return, error);
free(mib, M_TEMP);
return (error);
}
@@ -116,6 +158,7 @@
case LINUX_KERN_VERSION:
error = handle_string(&la, version);
free(mib, M_TEMP);
+ LIN_SDT_PROBE1(sysctl, linux_sysctl, return, error);
return (error);
default:
break;
@@ -128,16 +171,23 @@
sb = sbuf_new(NULL, NULL, 20 + la.nlen * 5, SBUF_AUTOEXTEND);
if (sb == NULL) {
linux_msg(td, "sysctl is not implemented");
+ LIN_SDT_PROBE1(sysctl, linux_sysctl, unsupported_sysctl,
+ "unknown sysctl, ENOMEM during lookup");
} else {
sbuf_printf(sb, "sysctl ");
for (i = 0; i < la.nlen; i++)
sbuf_printf(sb, "%c%d", (i) ? ',' : '{', mib[i]);
sbuf_printf(sb, "} is not implemented");
sbuf_finish(sb);
+ sysctl_string = sbuf_data(sb);
linux_msg(td, "%s", sbuf_data(sb));
+ LIN_SDT_PROBE1(sysctl, linux_sysctl, unsupported_sysctl,
+ sysctl_string);
sbuf_delete(sb);
}
free(mib, M_TEMP);
+
+ LIN_SDT_PROBE1(sysctl, linux_sysctl, return, ENOTDIR);
return (ENOTDIR);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/linux/linux_time.c
--- a/head/sys/compat/linux/linux_time.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/linux/linux_time.c Wed Jul 25 16:45:04 2012 +0300
@@ -30,16 +30,19 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/compat/linux/linux_time.c 235063 2012-05-05 19:42:38Z netchild $");
#if 0
__KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp $");
#endif
#include "opt_compat.h"
+#include "opt_kdtrace.h"
#include <sys/param.h>
+#include <sys/kernel.h>
#include <sys/ucred.h>
#include <sys/mount.h>
+#include <sys/sdt.h>
#include <sys/signal.h>
#include <sys/stdint.h>
#include <sys/syscallsubr.h>
@@ -56,6 +59,63 @@
#include <machine/../linux/linux_proto.h>
#endif
+#include <compat/linux/linux_dtrace.h>
+
+/* DTrace init */
+LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
+
+/**
+ * DTrace probes in this module.
+ */
+LIN_SDT_PROBE_DEFINE2(time, native_to_linux_timespec, entry,
+ "struct l_timespec *", "struct timespec *");
+LIN_SDT_PROBE_DEFINE0(time, native_to_linux_timespec, return);
+LIN_SDT_PROBE_DEFINE2(time, linux_to_native_timespec, entry,
+ "struct timespec *", "struct l_timespec *");
+LIN_SDT_PROBE_DEFINE1(time, linux_to_native_timespec, return, "int");
+LIN_SDT_PROBE_DEFINE2(time, linux_to_native_clockid, entry, "clockid_t *",
+ "clockid_t");
+LIN_SDT_PROBE_DEFINE1(time, linux_to_native_clockid, unsupported_clockid,
+ "clockid_t");
+LIN_SDT_PROBE_DEFINE1(time, linux_to_native_clockid, unknown_clockid,
+ "clockid_t");
+LIN_SDT_PROBE_DEFINE1(time, linux_to_native_clockid, return, "int");
+LIN_SDT_PROBE_DEFINE2(time, linux_clock_gettime, entry, "clockid_t",
+ "struct l_timespec *");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime, conversion_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime, gettime_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime, copyout_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime, return, "int");
+LIN_SDT_PROBE_DEFINE2(time, linux_clock_settime, entry, "clockid_t",
+ "struct l_timespec *");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_settime, conversion_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_settime, settime_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_settime, copyin_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_settime, return, "int");
+LIN_SDT_PROBE_DEFINE2(time, linux_clock_getres, entry, "clockid_t",
+ "struct l_timespec *");
+LIN_SDT_PROBE_DEFINE0(time, linux_clock_getres, nullcall);
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, conversion_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, getres_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, copyout_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, return, "int");
+LIN_SDT_PROBE_DEFINE2(time, linux_nanosleep, entry, "const struct l_timespec *",
+ "struct l_timespec *");
+LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, conversion_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, nanosleep_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, copyout_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, copyin_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, return, "int");
+LIN_SDT_PROBE_DEFINE4(time, linux_clock_nanosleep, entry, "clockid_t", "int",
+ "struct l_timespec *", "struct l_timespec *");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, conversion_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, nanosleep_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, copyout_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, copyin_error, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_flags, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_clockid, "int");
+LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, return, "int");
+
static void native_to_linux_timespec(struct l_timespec *,
struct timespec *);
static int linux_to_native_timespec(struct timespec *,
@@ -65,24 +125,38 @@
static void
native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp)
{
+
+ LIN_SDT_PROBE2(time, native_to_linux_timespec, entry, ltp, ntp);
+
ltp->tv_sec = ntp->tv_sec;
ltp->tv_nsec = ntp->tv_nsec;
+
+ LIN_SDT_PROBE0(time, native_to_linux_timespec, return);
}
static int
linux_to_native_timespec(struct timespec *ntp, struct l_timespec *ltp)
{
- if (ltp->tv_sec < 0 || ltp->tv_nsec > (l_long)999999999L)
+
+ LIN_SDT_PROBE2(time, linux_to_native_timespec, entry, ntp, ltp);
+
+ if (ltp->tv_sec < 0 || ltp->tv_nsec > (l_long)999999999L) {
+ LIN_SDT_PROBE1(time, linux_to_native_timespec, return, EINVAL);
return (EINVAL);
+ }
ntp->tv_sec = ltp->tv_sec;
ntp->tv_nsec = ltp->tv_nsec;
+ LIN_SDT_PROBE1(time, linux_to_native_timespec, return, 0);
return (0);
}
static int
linux_to_native_clockid(clockid_t *n, clockid_t l)
{
+
+ LIN_SDT_PROBE2(time, linux_to_native_clockid, entry, n, l);
+
switch (l) {
case LINUX_CLOCK_REALTIME:
*n = CLOCK_REALTIME;
@@ -94,11 +168,20 @@
case LINUX_CLOCK_THREAD_CPUTIME_ID:
case LINUX_CLOCK_REALTIME_HR:
case LINUX_CLOCK_MONOTONIC_HR:
+ LIN_SDT_PROBE1(time, linux_to_native_clockid,
+ unsupported_clockid, l);
+ LIN_SDT_PROBE1(time, linux_to_native_clockid, return, EINVAL);
+ return (EINVAL);
+ break;
default:
+ LIN_SDT_PROBE1(time, linux_to_native_clockid,
+ unknown_clockid, l);
+ LIN_SDT_PROBE1(time, linux_to_native_clockid, return, EINVAL);
return (EINVAL);
break;
}
+ LIN_SDT_PROBE1(time, linux_to_native_clockid, return, 0);
return (0);
}
@@ -110,15 +193,29 @@
clockid_t nwhich = 0; /* XXX: GCC */
struct timespec tp;
+ LIN_SDT_PROBE2(time, linux_clock_gettime, entry, args->which, args->tp);
+
error = linux_to_native_clockid(&nwhich, args->which);
- if (error != 0)
+ if (error != 0) {
+ LIN_SDT_PROBE1(time, linux_clock_gettime, conversion_error,
+ error);
+ LIN_SDT_PROBE1(time, linux_clock_gettime, return, error);
return (error);
+ }
error = kern_clock_gettime(td, nwhich, &tp);
- if (error != 0)
+ if (error != 0) {
+ LIN_SDT_PROBE1(time, linux_clock_gettime, gettime_error, error);
+ LIN_SDT_PROBE1(time, linux_clock_gettime, return, error);
return (error);
+ }
native_to_linux_timespec(<s, &tp);
- return (copyout(<s, args->tp, sizeof lts));
+ error = copyout(<s, args->tp, sizeof lts);
+ if (error != 0)
+ LIN_SDT_PROBE1(time, linux_clock_gettime, copyout_error, error);
+
+ LIN_SDT_PROBE1(time, linux_clock_gettime, return, error);
+ return (error);
}
int
@@ -129,17 +226,35 @@
int error;
clockid_t nwhich = 0; /* XXX: GCC */
+ LIN_SDT_PROBE2(time, linux_clock_settime, entry, args->which, args->tp);
+
error = linux_to_native_clockid(&nwhich, args->which);
+ if (error != 0) {
+ LIN_SDT_PROBE1(time, linux_clock_settime, conversion_error,
+ error);
+ LIN_SDT_PROBE1(time, linux_clock_settime, return, error);
+ return (error);
+ }
+ error = copyin(args->tp, <s, sizeof lts);
+ if (error != 0) {
+ LIN_SDT_PROBE1(time, linux_clock_settime, copyin_error, error);
+ LIN_SDT_PROBE1(time, linux_clock_settime, return, error);
+ return (error);
+ }
+ error = linux_to_native_timespec(&ts, <s);
+ if (error != 0) {
+ LIN_SDT_PROBE1(time, linux_clock_settime, conversion_error,
+ error);
+ LIN_SDT_PROBE1(time, linux_clock_settime, return, error);
+ return (error);
+ }
+
+ error = kern_clock_settime(td, nwhich, &ts);
if (error != 0)
- return (error);
- error = copyin(args->tp, <s, sizeof lts);
- if (error != 0)
- return (error);
- error = linux_to_native_timespec(&ts, <s);
- if (error != 0)
- return (error);
+ LIN_SDT_PROBE1(time, linux_clock_settime, settime_error, error);
- return (kern_clock_settime(td, nwhich, &ts));
+ LIN_SDT_PROBE1(time, linux_clock_settime, return, error);
+ return (error);
}
int
@@ -150,18 +265,35 @@
int error;
clockid_t nwhich = 0; /* XXX: GCC */
- if (args->tp == NULL)
+ LIN_SDT_PROBE2(time, linux_clock_getres, entry, args->which, args->tp);
+
+ if (args->tp == NULL) {
+ LIN_SDT_PROBE0(time, linux_clock_getres, nullcall);
+ LIN_SDT_PROBE1(time, linux_clock_getres, return, 0);
return (0);
+ }
error = linux_to_native_clockid(&nwhich, args->which);
- if (error != 0)
+ if (error != 0) {
+ LIN_SDT_PROBE1(time, linux_clock_getres, conversion_error,
+ error);
+ LIN_SDT_PROBE1(time, linux_clock_getres, return, error);
return (error);
+ }
error = kern_clock_getres(td, nwhich, &ts);
- if (error != 0)
+ if (error != 0) {
+ LIN_SDT_PROBE1(time, linux_clock_getres, getres_error, error);
+ LIN_SDT_PROBE1(time, linux_clock_getres, return, error);
return (error);
+ }
native_to_linux_timespec(<s, &ts);
- return (copyout(<s, args->tp, sizeof lts));
+ error = copyout(<s, args->tp, sizeof lts);
+ if (error != 0)
+ LIN_SDT_PROBE1(time, linux_clock_getres, copyout_error, error);
+
+ LIN_SDT_PROBE1(time, linux_clock_getres, return, error);
+ return (error);
}
int
@@ -172,9 +304,14 @@
struct timespec rqts, rmts;
int error;
+ LIN_SDT_PROBE2(time, linux_nanosleep, entry, args->rqtp, args->rmtp);
+
error = copyin(args->rqtp, &lrqts, sizeof lrqts);
- if (error != 0)
+ if (error != 0) {
+ LIN_SDT_PROBE1(time, linux_nanosleep, copyin_error, error);
+ LIN_SDT_PROBE1(time, linux_nanosleep, return, error);
return (error);
+ }
if (args->rmtp != NULL)
rmtp = &rmts;
@@ -182,19 +319,30 @@
rmtp = NULL;
error = linux_to_native_timespec(&rqts, &lrqts);
- if (error != 0)
+ if (error != 0) {
+ LIN_SDT_PROBE1(time, linux_nanosleep, conversion_error, error);
+ LIN_SDT_PROBE1(time, linux_nanosleep, return, error);
return (error);
+ }
error = kern_nanosleep(td, &rqts, rmtp);
- if (error != 0)
+ if (error != 0) {
+ LIN_SDT_PROBE1(time, linux_nanosleep, nanosleep_error, error);
+ LIN_SDT_PROBE1(time, linux_nanosleep, return, error);
return (error);
+ }
if (args->rmtp != NULL) {
native_to_linux_timespec(&lrmts, rmtp);
error = copyout(&lrmts, args->rmtp, sizeof(lrmts));
- if (error != 0)
+ if (error != 0) {
+ LIN_SDT_PROBE1(time, linux_nanosleep, copyout_error,
+ error);
+ LIN_SDT_PROBE1(time, linux_nanosleep, return, error);
return (error);
+ }
}
+ LIN_SDT_PROBE1(time, linux_nanosleep, return, 0);
return (0);
}
@@ -206,15 +354,31 @@
struct timespec rqts, rmts;
int error;
- if (args->flags != 0)
+ LIN_SDT_PROBE4(time, linux_clock_nanosleep, entry, args->which,
+ args->flags, args->rqtp, args->rmtp);
+
+ if (args->flags != 0) {
+ /* XXX deal with TIMER_ABSTIME */
+ LIN_SDT_PROBE1(time, linux_clock_nanosleep, unsupported_flags,
+ args->flags);
+ LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, EINVAL);
return (EINVAL); /* XXX deal with TIMER_ABSTIME */
+ }
- if (args->which != LINUX_CLOCK_REALTIME)
+ if (args->which != LINUX_CLOCK_REALTIME) {
+ LIN_SDT_PROBE1(time, linux_clock_nanosleep, unsupported_clockid,
+ args->which);
+ LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, EINVAL);
return (EINVAL);
+ }
error = copyin(args->rqtp, &lrqts, sizeof lrqts);
- if (error != 0)
+ if (error != 0) {
+ LIN_SDT_PROBE1(time, linux_clock_nanosleep, copyin_error,
+ error);
+ LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error);
return (error);
+ }
if (args->rmtp != NULL)
rmtp = &rmts;
@@ -222,18 +386,31 @@
rmtp = NULL;
error = linux_to_native_timespec(&rqts, &lrqts);
- if (error != 0)
+ if (error != 0) {
+ LIN_SDT_PROBE1(time, linux_clock_nanosleep, conversion_error,
+ error);
+ LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error);
return (error);
+ }
error = kern_nanosleep(td, &rqts, rmtp);
- if (error != 0)
+ if (error != 0) {
+ LIN_SDT_PROBE1(time, linux_clock_nanosleep, nanosleep_error,
+ error);
+ LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error);
return (error);
+ }
if (args->rmtp != NULL) {
native_to_linux_timespec(&lrmts, rmtp);
error = copyout(&lrmts, args->rmtp, sizeof lrmts );
- if (error != 0)
+ if (error != 0) {
+ LIN_SDT_PROBE1(time, linux_clock_nanosleep,
+ copyout_error, error);
+ LIN_SDT_PROBE1(time, linux_nanosleep, return, error);
return (error);
+ }
}
+ LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, 0);
return (0);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/linux/linux_uid16.c
--- a/head/sys/compat/linux/linux_uid16.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/linux/linux_uid16.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,17 +25,20 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/linux/linux_uid16.c 226253 2011-10-11 13:40:37Z brueffer $");
+__FBSDID("$FreeBSD: head/sys/compat/linux/linux_uid16.c 235063 2012-05-05 19:42:38Z netchild $");
#include "opt_compat.h"
+#include "opt_kdtrace.h"
#include <sys/fcntl.h>
#include <sys/param.h>
+#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/priv.h>
#include <sys/proc.h>
+#include <sys/sdt.h>
#include <sys/syscallsubr.h>
#include <sys/sysproto.h>
#include <sys/systm.h>
@@ -48,8 +51,53 @@
#include <machine/../linux/linux_proto.h>
#endif
+#include <compat/linux/linux_dtrace.h>
#include <compat/linux/linux_util.h>
+/* DTrace init */
+LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
+
+/**
+ * DTrace probes in this module.
+ */
+LIN_SDT_PROBE_DEFINE3(uid16, linux_chown16, entry, "char *", "l_uid16_t",
+ "l_gid16_t");
+LIN_SDT_PROBE_DEFINE1(uid16, linux_chown16, conv_path, "char *");
+LIN_SDT_PROBE_DEFINE1(uid16, linux_chown16, return, "int");
+LIN_SDT_PROBE_DEFINE3(uid16, linux_lchown16, entry, "char *", "l_uid16_t",
+ "l_gid16_t");
+LIN_SDT_PROBE_DEFINE1(uid16, linux_lchown16, conv_path, "char *");
+LIN_SDT_PROBE_DEFINE1(uid16, linux_lchown16, return, "int");
+LIN_SDT_PROBE_DEFINE2(uid16, linux_setgroups16, entry, "l_uint", "l_gid16_t *");
+LIN_SDT_PROBE_DEFINE1(uid16, linux_setgroups16, copyin_error, "int");
+LIN_SDT_PROBE_DEFINE1(uid16, linux_setgroups16, priv_check_cred_error, "int");
+LIN_SDT_PROBE_DEFINE1(uid16, linux_setgroups16, return, "int");
+LIN_SDT_PROBE_DEFINE2(uid16, linux_getgroups16, entry, "l_uint", "l_gid16_t *");
+LIN_SDT_PROBE_DEFINE1(uid16, linux_getgroups16, copyout_error, "int");
+LIN_SDT_PROBE_DEFINE1(uid16, linux_getgroups16, return, "int");
+LIN_SDT_PROBE_DEFINE0(uid16, linux_getgid16, entry);
+LIN_SDT_PROBE_DEFINE1(uid16, linux_getgid16, return, "int");
+LIN_SDT_PROBE_DEFINE0(uid16, linux_getuid16, entry);
+LIN_SDT_PROBE_DEFINE1(uid16, linux_getuid16, return, "int");
+LIN_SDT_PROBE_DEFINE0(uid16, linux_getegid16, entry);
+LIN_SDT_PROBE_DEFINE1(uid16, linux_getegid16, return, "int");
+LIN_SDT_PROBE_DEFINE0(uid16, linux_geteuid16, entry);
+LIN_SDT_PROBE_DEFINE1(uid16, linux_geteuid16, return, "int");
+LIN_SDT_PROBE_DEFINE1(uid16, linux_setgid16, entry, "l_gid16_t");
+LIN_SDT_PROBE_DEFINE1(uid16, linux_setgid16, return, "int");
+LIN_SDT_PROBE_DEFINE1(uid16, linux_setuid16, entry, "l_uid16_t");
+LIN_SDT_PROBE_DEFINE1(uid16, linux_setuid16, return, "int");
+LIN_SDT_PROBE_DEFINE2(uid16, linux_setregid16, entry, "l_git16_t", "l_git16_t");
+LIN_SDT_PROBE_DEFINE1(uid16, linux_setregid16, return, "int");
+LIN_SDT_PROBE_DEFINE2(uid16, linux_setreuid16, entry, "l_uid16_t", "l_uid16_t");
+LIN_SDT_PROBE_DEFINE1(uid16, linux_setreuid16, return, "int");
+LIN_SDT_PROBE_DEFINE3(uid16, linux_setresgid16, entry, "l_gid16_t", "l_gid16_t",
+ "l_gid16_t");
+LIN_SDT_PROBE_DEFINE1(uid16, linux_setresgid16, return, "int");
+LIN_SDT_PROBE_DEFINE3(uid16, linux_setresuid16, entry, "l_uid16_t", "l_uid16_t",
+ "l_uid16_t");
+LIN_SDT_PROBE_DEFINE1(uid16, linux_setresuid16, return, "int");
+
DUMMY(setfsuid16);
DUMMY(setfsgid16);
DUMMY(getresuid16);
@@ -65,13 +113,20 @@
LCONVPATHEXIST(td, args->path, &path);
-#ifdef DEBUG
- if (ldebug(chown16))
- printf(ARGS(chown16, "%s, %d, %d"), path, args->uid, args->gid);
-#endif
+ /*
+ * The DTrace probes have to be after the LCONVPATHEXIST, as
+ * LCONVPATHEXIST may return on its own and we do not want to
+ * have a stray entry without the corresponding return.
+ */
+ LIN_SDT_PROBE3(uid16, linux_chown16, entry, args->path, args->uid,
+ args->gid);
+ LIN_SDT_PROBE1(uid16, linux_chown16, conv_path, path);
+
error = kern_chown(td, path, UIO_SYSSPACE, CAST_NOCHG(args->uid),
CAST_NOCHG(args->gid));
LFREEPATH(path);
+
+ LIN_SDT_PROBE1(uid16, linux_chown16, return, error);
return (error);
}
@@ -83,14 +138,20 @@
LCONVPATHEXIST(td, args->path, &path);
-#ifdef DEBUG
- if (ldebug(lchown16))
- printf(ARGS(lchown16, "%s, %d, %d"), path, args->uid,
- args->gid);
-#endif
+ /*
+ * The DTrace probes have to be after the LCONVPATHEXIST, as
+ * LCONVPATHEXIST may return on its own and we do not want to
+ * have a stray entry without the corresponding return.
+ */
+ LIN_SDT_PROBE3(uid16, linux_lchown16, entry, args->path, args->uid,
+ args->gid);
+ LIN_SDT_PROBE1(uid16, linux_lchown16, conv_path, path);
+
error = kern_lchown(td, path, UIO_SYSSPACE, CAST_NOCHG(args->uid),
CAST_NOCHG(args->gid));
LFREEPATH(path);
+
+ LIN_SDT_PROBE1(uid16, linux_lchown16, return, error);
return (error);
}
@@ -103,17 +164,19 @@
int ngrp, error;
struct proc *p;
-#ifdef DEBUG
- if (ldebug(setgroups16))
- printf(ARGS(setgroups16, "%d, *"), args->gidsetsize);
-#endif
+ LIN_SDT_PROBE2(uid16, linux_setgroups16, entry, args->gidsetsize,
+ args->gidset);
ngrp = args->gidsetsize;
- if (ngrp < 0 || ngrp >= ngroups_max + 1)
+ if (ngrp < 0 || ngrp >= ngroups_max + 1) {
+ LIN_SDT_PROBE1(uid16, linux_setgroups16, return, EINVAL);
return (EINVAL);
+ }
linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_TEMP, M_WAITOK);
error = copyin(args->gidset, linux_gidset, ngrp * sizeof(l_gid16_t));
if (error) {
+ LIN_SDT_PROBE1(uid16, linux_setgroups16, copyin_error, error);
+ LIN_SDT_PROBE1(uid16, linux_setgroups16, return, error);
free(linux_gidset, M_TEMP);
return (error);
}
@@ -131,6 +194,9 @@
if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, 0)) != 0) {
PROC_UNLOCK(p);
crfree(newcred);
+
+ LIN_SDT_PROBE1(uid16, linux_setgroups16, priv_check_cred_error,
+ error);
goto out;
}
@@ -154,6 +220,8 @@
error = 0;
out:
free(linux_gidset, M_TEMP);
+
+ LIN_SDT_PROBE1(uid16, linux_setgroups16, return, error);
return (error);
}
@@ -165,10 +233,8 @@
gid_t *bsd_gidset;
int bsd_gidsetsz, ngrp, error;
-#ifdef DEBUG
- if (ldebug(getgroups16))
- printf(ARGS(getgroups16, "%d, *"), args->gidsetsize);
-#endif
+ LIN_SDT_PROBE2(uid16, linux_getgroups16, entry, args->gidsetsize,
+ args->gidset);
cred = td->td_ucred;
bsd_gidset = cred->cr_groups;
@@ -182,11 +248,15 @@
if ((ngrp = args->gidsetsize) == 0) {
td->td_retval[0] = bsd_gidsetsz;
+
+ LIN_SDT_PROBE1(uid16, linux_getgroups16, return, 0);
return (0);
}
- if (ngrp < bsd_gidsetsz)
+ if (ngrp < bsd_gidsetsz) {
+ LIN_SDT_PROBE1(uid16, linux_getgroups16, return, EINVAL);
return (EINVAL);
+ }
ngrp = 0;
linux_gidset = malloc(bsd_gidsetsz * sizeof(*linux_gidset),
@@ -198,10 +268,15 @@
error = copyout(linux_gidset, args->gidset, ngrp * sizeof(l_gid16_t));
free(linux_gidset, M_TEMP);
- if (error)
+ if (error) {
+ LIN_SDT_PROBE1(uid16, linux_getgroups16, copyout_error, error);
+ LIN_SDT_PROBE1(uid16, linux_getgroups16, return, error);
return (error);
+ }
td->td_retval[0] = ngrp;
+
+ LIN_SDT_PROBE1(uid16, linux_getgroups16, return, 0);
return (0);
}
@@ -219,7 +294,11 @@
linux_getgid16(struct thread *td, struct linux_getgid16_args *args)
{
+ LIN_SDT_PROBE0(uid16, linux_getgid16, entry);
+
td->td_retval[0] = td->td_ucred->cr_rgid;
+
+ LIN_SDT_PROBE1(uid16, linux_getgid16, return, 0);
return (0);
}
@@ -227,7 +306,11 @@
linux_getuid16(struct thread *td, struct linux_getuid16_args *args)
{
+ LIN_SDT_PROBE0(uid16, linux_getuid16, entry);
+
td->td_retval[0] = td->td_ucred->cr_ruid;
+
+ LIN_SDT_PROBE1(uid16, linux_getuid16, return, 0);
return (0);
}
@@ -235,74 +318,124 @@
linux_getegid16(struct thread *td, struct linux_getegid16_args *args)
{
struct getegid_args bsd;
+ int error;
- return (sys_getegid(td, &bsd));
+ LIN_SDT_PROBE0(uid16, linux_getegid16, entry);
+
+ error = sys_getegid(td, &bsd);
+
+ LIN_SDT_PROBE1(uid16, linux_getegid16, return, error);
+ return (error);
}
int
linux_geteuid16(struct thread *td, struct linux_geteuid16_args *args)
{
struct geteuid_args bsd;
+ int error;
- return (sys_geteuid(td, &bsd));
+ LIN_SDT_PROBE0(uid16, linux_geteuid16, entry);
+
+ error = sys_geteuid(td, &bsd);
+
+ LIN_SDT_PROBE1(uid16, linux_geteuid16, return, error);
+ return (error);
}
int
linux_setgid16(struct thread *td, struct linux_setgid16_args *args)
{
struct setgid_args bsd;
+ int error;
+
+ LIN_SDT_PROBE1(uid16, linux_setgid16, entry, args->gid);
bsd.gid = args->gid;
- return (sys_setgid(td, &bsd));
+ error = sys_setgid(td, &bsd);
+
+ LIN_SDT_PROBE1(uid16, linux_setgid16, return, error);
+ return (error);
}
int
linux_setuid16(struct thread *td, struct linux_setuid16_args *args)
{
struct setuid_args bsd;
+ int error;
+
+ LIN_SDT_PROBE1(uid16, linux_setuid16, entry, args->uid);
bsd.uid = args->uid;
- return (sys_setuid(td, &bsd));
+ error = sys_setuid(td, &bsd);
+
+ LIN_SDT_PROBE1(uid16, linux_setuid16, return, error);
+ return (error);
}
int
linux_setregid16(struct thread *td, struct linux_setregid16_args *args)
{
struct setregid_args bsd;
+ int error;
+
+ LIN_SDT_PROBE2(uid16, linux_setregid16, entry, args->rgid, args->egid);
bsd.rgid = CAST_NOCHG(args->rgid);
bsd.egid = CAST_NOCHG(args->egid);
- return (sys_setregid(td, &bsd));
+ error = sys_setregid(td, &bsd);
+
+ LIN_SDT_PROBE1(uid16, linux_setregid16, return, error);
+ return (error);
}
int
linux_setreuid16(struct thread *td, struct linux_setreuid16_args *args)
{
struct setreuid_args bsd;
+ int error;
+
+ LIN_SDT_PROBE2(uid16, linux_setreuid16, entry, args->ruid, args->euid);
bsd.ruid = CAST_NOCHG(args->ruid);
bsd.euid = CAST_NOCHG(args->euid);
- return (sys_setreuid(td, &bsd));
+ error = sys_setreuid(td, &bsd);
+
+ LIN_SDT_PROBE1(uid16, linux_setreuid16, return, error);
+ return (error);
}
int
linux_setresgid16(struct thread *td, struct linux_setresgid16_args *args)
{
struct setresgid_args bsd;
+ int error;
+
+ LIN_SDT_PROBE3(uid16, linux_setresgid16, entry, args->rgid, args->egid,
+ args->sgid);
bsd.rgid = CAST_NOCHG(args->rgid);
bsd.egid = CAST_NOCHG(args->egid);
bsd.sgid = CAST_NOCHG(args->sgid);
- return (sys_setresgid(td, &bsd));
+ error = sys_setresgid(td, &bsd);
+
+ LIN_SDT_PROBE1(uid16, linux_setresgid16, return, error);
+ return (error);
}
int
linux_setresuid16(struct thread *td, struct linux_setresuid16_args *args)
{
struct setresuid_args bsd;
+ int error;
+
+ LIN_SDT_PROBE3(uid16, linux_setresuid16, entry, args->ruid, args->euid,
+ args->suid);
bsd.ruid = CAST_NOCHG(args->ruid);
bsd.euid = CAST_NOCHG(args->euid);
bsd.suid = CAST_NOCHG(args->suid);
- return (sys_setresuid(td, &bsd));
+ error = sys_setresuid(td, &bsd);
+
+ LIN_SDT_PROBE1(uid16, linux_setresuid16, return, error);
+ return (error);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/linux/linux_util.c
--- a/head/sys/compat/linux/linux_util.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/linux/linux_util.c Wed Jul 25 16:45:04 2012 +0300
@@ -30,19 +30,22 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/linux/linux_util.c 231378 2012-02-10 12:35:57Z ed $");
+__FBSDID("$FreeBSD: head/sys/compat/linux/linux_util.c 235063 2012-05-05 19:42:38Z netchild $");
#include "opt_compat.h"
+#include "opt_kdtrace.h"
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/fcntl.h>
#include <sys/lock.h>
#include <sys/malloc.h>
+#include <sys/kernel.h>
#include <sys/linker_set.h>
#include <sys/mutex.h>
#include <sys/namei.h>
#include <sys/proc.h>
+#include <sys/sdt.h>
#include <sys/syscallsubr.h>
#include <sys/systm.h>
#include <sys/vnode.h>
@@ -56,8 +59,42 @@
#include <machine/../linux/linux.h>
#endif
+#include <compat/linux/linux_dtrace.h>
+
const char linux_emul_path[] = "/compat/linux";
+/* DTrace init */
+LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
+
+/**
+ * DTrace probes in this module.
+ */
+LIN_SDT_PROBE_DEFINE5(util, linux_emul_convpath, entry, "const char *",
+ "enum uio_seg", "char **", "int", "int");
+LIN_SDT_PROBE_DEFINE1(util, linux_emul_convpath, return, "int");
+LIN_SDT_PROBE_DEFINE1(util, linux_msg, entry, "const char *");
+LIN_SDT_PROBE_DEFINE0(util, linux_msg, return);
+LIN_SDT_PROBE_DEFINE2(util, linux_driver_get_name_dev, entry, "device_t",
+ "const char *");
+LIN_SDT_PROBE_DEFINE0(util, linux_driver_get_name_dev, nullcall);
+LIN_SDT_PROBE_DEFINE1(util, linux_driver_get_name_dev, return, "char *");
+LIN_SDT_PROBE_DEFINE3(util, linux_driver_get_major_minor, entry, "char *",
+ "int *", "int *");
+LIN_SDT_PROBE_DEFINE0(util, linux_driver_get_major_minor, nullcall);
+LIN_SDT_PROBE_DEFINE1(util, linux_driver_get_major_minor, notfound, "char *");
+LIN_SDT_PROBE_DEFINE3(util, linux_driver_get_major_minor, return, "int",
+ "int", "int");
+LIN_SDT_PROBE_DEFINE0(util, linux_get_char_devices, entry);
+LIN_SDT_PROBE_DEFINE1(util, linux_get_char_devices, return, "char *");
+LIN_SDT_PROBE_DEFINE1(util, linux_free_get_char_devices, entry, "char *");
+LIN_SDT_PROBE_DEFINE0(util, linux_free_get_char_devices, return);
+LIN_SDT_PROBE_DEFINE1(util, linux_device_register_handler, entry,
+ "struct linux_device_handler *");
+LIN_SDT_PROBE_DEFINE1(util, linux_device_register_handler, return, "int");
+LIN_SDT_PROBE_DEFINE1(util, linux_device_unregister_handler, entry,
+ "struct linux_device_handler *");
+LIN_SDT_PROBE_DEFINE1(util, linux_device_unregister_handler, return, "int");
+
/*
* Search an alternate path before passing pathname arguments on to
* system calls. Useful for keeping a separate 'emulation tree'.
@@ -66,17 +103,19 @@
* named file, i.e. we check if the directory it should be in exists.
*/
int
-linux_emul_convpath(td, path, pathseg, pbuf, cflag, dfd)
- struct thread *td;
- const char *path;
- enum uio_seg pathseg;
- char **pbuf;
- int cflag;
- int dfd;
+linux_emul_convpath(struct thread *td, const char *path, enum uio_seg pathseg,
+ char **pbuf, int cflag, int dfd)
{
+ int retval;
- return (kern_alternate_path(td, linux_emul_path, path, pathseg, pbuf,
- cflag, dfd));
+ LIN_SDT_PROBE5(util, linux_emul_convpath, entry, path, pathseg, pbuf,
+ cflag, dfd);
+
+ retval = kern_alternate_path(td, linux_emul_path, path, pathseg, pbuf,
+ cflag, dfd);
+
+ LIN_SDT_PROBE1(util, linux_emul_convpath, return, retval);
+ return (retval);
}
void
@@ -85,12 +124,16 @@
va_list ap;
struct proc *p;
+ LIN_SDT_PROBE1(util, linux_msg, entry, fmt);
+
p = td->td_proc;
printf("linux: pid %d (%s): ", (int)p->p_pid, p->p_comm);
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
printf("\n");
+
+ LIN_SDT_PROBE0(util, linux_msg, return);
}
struct device_element
@@ -113,13 +156,23 @@
struct device_element *de;
const char *device_name = device_get_name(dev);
- if (device_name == NULL)
+ LIN_SDT_PROBE2(util, linux_driver_get_name_dev, entry, dev,
+ device_name);
+
+ if (device_name == NULL) {
+ LIN_SDT_PROBE0(util, linux_driver_get_name_dev, nullcall);
+ LIN_SDT_PROBE1(util, linux_driver_get_name_dev, return, NULL);
return NULL;
+ }
TAILQ_FOREACH(de, &devices, list) {
- if (strcmp(device_name, de->entry.bsd_driver_name) == 0)
+ if (strcmp(device_name, de->entry.bsd_driver_name) == 0) {
+ LIN_SDT_PROBE1(util, linux_driver_get_name_dev, return,
+ de->entry.linux_driver_name);
return (de->entry.linux_driver_name);
+ }
}
+ LIN_SDT_PROBE1(util, linux_driver_get_name_dev, return, NULL);
return NULL;
}
@@ -128,8 +181,15 @@
{
struct device_element *de;
- if (node == NULL || major == NULL || minor == NULL)
+ LIN_SDT_PROBE3(util, linux_driver_get_major_minor, entry, node, major,
+ minor);
+
+ if (node == NULL || major == NULL || minor == NULL) {
+ LIN_SDT_PROBE0(util, linux_driver_get_major_minor, nullcall);
+ LIN_SDT_PROBE3(util, linux_driver_get_major_minor, return, 1,
+ 0, 0);
return 1;
+ }
if (strlen(node) > strlen("pts/") &&
strncmp(node, "pts/", strlen("pts/")) == 0) {
@@ -143,6 +203,9 @@
devno = strtoul(node + strlen("pts/"), NULL, 10);
*major = 136 + (devno / 256);
*minor = devno % 256;
+
+ LIN_SDT_PROBE3(util, linux_driver_get_major_minor, return, 0,
+ *major, *minor);
return 0;
}
@@ -150,10 +213,15 @@
if (strcmp(node, de->entry.bsd_device_name) == 0) {
*major = de->entry.linux_major;
*minor = de->entry.linux_minor;
+
+ LIN_SDT_PROBE3(util, linux_driver_get_major_minor,
+ return, 0, *major, *minor);
return 0;
}
}
+ LIN_SDT_PROBE1(util, linux_driver_get_major_minor, notfound, node);
+ LIN_SDT_PROBE3(util, linux_driver_get_major_minor, return, 1, 0, 0);
return 1;
}
@@ -165,6 +233,8 @@
char formated[256];
int current_size = 0, string_size = 1024;
+ LIN_SDT_PROBE0(util, linux_get_char_devices, entry);
+
string = malloc(string_size, M_LINUX, M_WAITOK);
string[0] = '\000';
last = "";
@@ -191,13 +261,19 @@
}
}
+ LIN_SDT_PROBE1(util, linux_get_char_devices, return, string);
return string;
}
void
linux_free_get_char_devices(char *string)
{
+
+ LIN_SDT_PROBE1(util, linux_get_char_devices, entry, string);
+
free(string, M_LINUX);
+
+ LIN_SDT_PROBE0(util, linux_get_char_devices, return);
}
static int linux_major_starting = 200;
@@ -207,11 +283,15 @@
{
struct device_element *de;
- if (d == NULL)
+ LIN_SDT_PROBE1(util, linux_device_register_handler, entry, d);
+
+ if (d == NULL) {
+ LIN_SDT_PROBE1(util, linux_device_register_handler, return,
+ EINVAL);
return (EINVAL);
+ }
- de = malloc(sizeof(*de),
- M_LINUX, M_WAITOK);
+ de = malloc(sizeof(*de), M_LINUX, M_WAITOK);
if (d->linux_major < 0) {
d->linux_major = linux_major_starting++;
}
@@ -220,6 +300,7 @@
/* Add the element to the list, sorted on span. */
TAILQ_INSERT_TAIL(&devices, de, list);
+ LIN_SDT_PROBE1(util, linux_device_register_handler, return, 0);
return (0);
}
@@ -228,16 +309,25 @@
{
struct device_element *de;
- if (d == NULL)
+ LIN_SDT_PROBE1(util, linux_device_unregister_handler, entry, d);
+
+ if (d == NULL) {
+ LIN_SDT_PROBE1(util, linux_device_unregister_handler, return,
+ EINVAL);
return (EINVAL);
+ }
TAILQ_FOREACH(de, &devices, list) {
if (bcmp(d, &de->entry, sizeof(*d)) == 0) {
TAILQ_REMOVE(&devices, de, list);
free(de, M_LINUX);
+
+ LIN_SDT_PROBE1(util, linux_device_unregister_handler,
+ return, 0);
return (0);
}
}
+ LIN_SDT_PROBE1(util, linux_device_unregister_handler, return, EINVAL);
return (EINVAL);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/linux/linux_util.h
--- a/head/sys/compat/linux/linux_util.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/linux/linux_util.h Wed Jul 25 16:45:04 2012 +0300
@@ -28,7 +28,7 @@
*
* from: svr4_util.h,v 1.5 1994/11/18 02:54:31 christos Exp
* from: linux_util.h,v 1.2 1995/03/05 23:23:50 fvdl Exp
- * $FreeBSD: head/sys/compat/linux/linux_util.h 231378 2012-02-10 12:35:57Z ed $
+ * $FreeBSD: head/sys/compat/linux/linux_util.h 235063 2012-05-05 19:42:38Z netchild $
*/
#ifndef _LINUX_UTIL_H_
@@ -68,15 +68,23 @@
#define LFREEPATH(path) free(path, M_TEMP)
#define DUMMY(s) \
+LIN_SDT_PROBE_DEFINE0(dummy, s, entry); \
+LIN_SDT_PROBE_DEFINE0(dummy, s, not_implemented); \
+LIN_SDT_PROBE_DEFINE1(dummy, s, return, "int"); \
int \
linux_ ## s(struct thread *td, struct linux_ ## s ## _args *args) \
{ \
static pid_t pid; \
\
+ LIN_SDT_PROBE0(dummy, s, entry); \
+ \
if (pid != td->td_proc->p_pid) { \
linux_msg(td, "syscall %s not implemented", #s); \
+ LIN_SDT_PROBE0(dummy, s, not_implemented); \
pid = td->td_proc->p_pid; \
}; \
+ \
+ LIN_SDT_PROBE1(dummy, s, return, ENOSYS); \
return (ENOSYS); \
} \
struct __hack
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/linux/stats_timing.d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/compat/linux/stats_timing.d Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,94 @@
+#!/usr/sbin/dtrace -qs
+
+/*-
+ * Copyright (c) 2008-2012 Alexander Leidinger <netchild at 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
+ * in this position and unchanged.
+ * 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: head/sys/compat/linux/stats_timing.d 235063 2012-05-05 19:42:38Z netchild $
+ */
+
+/**
+ * Some statistics (all per provider):
+ * - number of calls to a function per executable binary (not per PID!)
+ * - allows to see where an optimization would be beneficial for a given
+ * application
+ * - graph of CPU time spend in functions per executable binary
+ * - together with the number of calls to this function this allows
+ * to determine if a kernel optimization would be beneficial / is
+ * possible for a given application
+ * - graph of longest running (CPU-time!) function in total
+ * - may help finding problem cases in the kernel code
+ * - timing statistics for the emul_lock
+ * - graph of longest held (CPU-time!) locks
+ */
+
+#pragma D option dynvarsize=32m
+
+linuxulator*:::entry
+{
+ self->time[probefunc] = vtimestamp;
+ @calls[probeprov, execname, probefunc] = count();
+}
+
+linuxulator*:::return
+/self->time[probefunc] != 0/
+{
+ this->timediff = self->time[probefunc] - vtimestamp;
+
+ @stats[probeprov, execname, probefunc] = quantize(this->timediff);
+ @longest[probeprov, probefunc] = max(this->timediff);
+
+ self->time[probefunc] = 0;
+}
+
+linuxulator*:::locked
+{
+ self->lock[arg0] = vtimestamp;
+}
+
+linuxulator*:::unlock
+/self->lock[arg0] != 0/
+{
+ this->timediff = self->lock[arg0] - vtimestamp;
+
+ @lockstats[probefunc] = quantize(this->timediff);
+ @longlock[probefunc] = max(this->timediff);
+
+ self->lock[arg0] = 0;
+}
+
+END
+{
+ printf("Number of calls per provider/application/kernel function:");
+ printa(@calls);
+ printf("CPU-timing statistics per provider/application/kernel function (in ns):");
+ printa(@stats);
+ printf("Longest running (CPU-time!) functions per provider (in ns):");
+ printa(@longest);
+ printf("Lock CPU-timing statistics:");
+ printa(@lockstats);
+ printf("Longest running (CPU-time!) locks:");
+ printa(@longlock);
+}
+
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/linux/trace_futexes.d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/compat/linux/trace_futexes.d Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,182 @@
+#!/usr/sbin/dtrace -qs
+
+/*-
+ * Copyright (c) 2011-2012 Alexander Leidinger <netchild at 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
+ * in this position and unchanged.
+ * 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: head/sys/compat/linux/trace_futexes.d 235063 2012-05-05 19:42:38Z netchild $
+ */
+
+/**
+ * Trace futex operations:
+ * - internal locks
+ * - size of the futex list
+ * - report error conditions (emulation errors, kernel errors,
+ * programming errors)
+ * - execution time (wallclock) of futex related functions
+ */
+
+#pragma D option specsize=32m
+
+/* Error conditions */
+linuxulator*:futex:futex_get:error,
+linuxulator*:futex:futex_sleep:requeue_error,
+linuxulator*:futex:futex_sleep:sleep_error,
+linuxulator*:futex:futex_wait:copyin_error,
+linuxulator*:futex:futex_wait:itimerfix_error,
+linuxulator*:futex:futex_wait:sleep_error,
+linuxulator*:futex:futex_atomic_op:missing_access_check,
+linuxulator*:futex:futex_atomic_op:unimplemented_op,
+linuxulator*:futex:futex_atomic_op:unimplemented_cmp,
+linuxulator*:futex:linux_sys_futex:unimplemented_clockswitch,
+linuxulator*:futex:linux_sys_futex:copyin_error,
+linuxulator*:futex:linux_sys_futex:unhandled_efault,
+linuxulator*:futex:linux_sys_futex:unimplemented_lock_pi,
+linuxulator*:futex:linux_sys_futex:unimplemented_unlock_pi,
+linuxulator*:futex:linux_sys_futex:unimplemented_trylock_pi,
+linuxulator*:futex:linux_sys_futex:unimplemented_wait_requeue_pi,
+linuxulator*:futex:linux_sys_futex:unimplemented_cmp_requeue_pi,
+linuxulator*:futex:linux_sys_futex:unknown_operation,
+linuxulator*:futex:linux_get_robust_list:copyout_error,
+linuxulator*:futex:handle_futex_death:copyin_error,
+linuxulator*:futex:fetch_robust_entry:copyin_error,
+linuxulator*:futex:release_futexes:copyin_error
+{
+ printf("ERROR: %s in %s:%s:%s\n", probename, probeprov, probemod,
+ probefunc);
+ stack();
+ ustack();
+}
+
+linuxulator*:futex:linux_sys_futex:invalid_cmp_requeue_use,
+linuxulator*:futex:linux_sys_futex:deprecated_requeue,
+linuxulator*:futex:linux_set_robust_list:size_error
+{
+ printf("WARNING: %s:%s:%s:%s in application %s, maybe an application error?\n",
+ probename, probeprov, probemod, probefunc, execname);
+ stack();
+ ustack();
+}
+
+
+/* Per futex checks/statistics */
+
+linuxulator*:futex:futex:create
+{
+ ++futex_count;
+ @max_futexes = max(futex_count);
+}
+
+linuxulator*:futex:futex:destroy
+/futex_count == 0/
+{
+ printf("ERROR: Request to destroy a futex which was not created,\n");
+ printf(" or this script was started after some futexes where\n");
+ printf(" created. Stack trace:\n");
+ stack();
+ ustack();
+}
+
+linuxulator*:futex:futex:destroy
+{
+ --futex_count;
+}
+
+
+/* Internal locks */
+
+linuxulator*:locks:futex_mtx:locked
+{
+ ++check[probefunc, arg0];
+ @stats[probefunc] = count();
+
+ ts[probefunc] = timestamp;
+ spec[probefunc] = speculation();
+ printf("Stacktrace of last lock operation of the %s:\n", probefunc);
+ stack();
+}
+
+linuxulator*:locks:futex_mtx:unlock
+/check[probefunc, arg0] == 0/
+{
+ printf("ERROR: unlock attemt of unlocked %s (%p),", probefunc, arg0);
+ printf(" missing SDT probe in kernel, or dtrace program started");
+ printf(" while the %s was already held (race condition).", probefunc);
+ printf(" Stack trace follows:");
+ stack();
+}
+
+linuxulator*:locks:futex_mtx:unlock
+{
+ discard(spec[probefunc]);
+ spec[probefunc] = 0;
+ --check[probefunc, arg0];
+}
+
+/* Timeout handling for internal locks */
+
+tick-10s
+/spec["futex_mtx"] != 0 && timestamp - ts["futex_mtx"] >= 9999999000/
+{
+ commit(spec["futex_mtx"]);
+ spec["futex_mtx"] = 0;
+}
+
+
+/* Timing statistings */
+
+linuxulator*:futex::entry
+{
+ self->time[probefunc] = timestamp;
+ @calls[probeprov, execname, probefunc] = count();
+}
+
+linuxulator*:futex::return
+/self->time[probefunc] != 0/
+{
+ this->timediff = self->time[probefunc] - timestamp;
+
+ @timestats[probeprov, execname, probefunc] = quantize(this->timediff);
+ @longest[probeprov, probefunc] = max(this->timediff);
+
+ self->time[probefunc] = 0;
+}
+
+
+/* Statistics */
+
+END
+{
+ printf("Number of locks per type:");
+ printa(@stats);
+ printf("Number of maximum number of futexes in the futex list:");
+ printa(@max_futexes);
+ printf("Number of futexes still existing: %d", futex_count);
+ printf("Number of calls per provider/application/kernel function:");
+ printa(@calls);
+ printf("Wallclock-timing statistics per provider/application/kernel function (in ns):");
+ printa(@timestats);
+ printf("Longest running (wallclock!) functions per provider (in ns):");
+ printa(@longest);
+}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/compat/ndis/subr_ntoskrnl.c
--- a/head/sys/compat/ndis/subr_ntoskrnl.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/compat/ndis/subr_ntoskrnl.c Wed Jul 25 16:45:04 2012 +0300
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/ndis/subr_ntoskrnl.c 229004 2011-12-30 17:18:09Z dim $");
+__FBSDID("$FreeBSD: head/sys/compat/ndis/subr_ntoskrnl.c 236213 2012-05-29 01:48:06Z kevlo $");
#include <sys/ctype.h>
#include <sys/unistd.h>
@@ -3591,6 +3591,7 @@
if (bootverbose) {
va_start(ap, fmt);
vprintf(fmt, ap);
+ va_end(ap);
}
return (STATUS_SUCCESS);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/acpica_prep.sh
--- a/head/sys/contrib/dev/acpica/acpica_prep.sh Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/acpica_prep.sh Wed Jul 25 16:45:04 2012 +0300
@@ -1,5 +1,5 @@
#!/bin/sh
-# $FreeBSD: head/sys/contrib/dev/acpica/acpica_prep.sh 233250 2012-03-20 21:37:52Z jkim $
+# $FreeBSD: head/sys/contrib/dev/acpica/acpica_prep.sh 235945 2012-05-24 23:12:30Z jkim $
#
# Unpack an ACPI CA drop and restructure it to fit the FreeBSD layout
#
@@ -10,8 +10,8 @@
fi
src=$1
-wrk=`realpath ./_acpi_ca_unpack`
-dst=`realpath ./acpi_ca_destination`
+wrk="$(realpath .)/_acpi_ca_unpack"
+dst="$(realpath .)/acpi_ca_destination"
# files that should keep their full directory path
fulldirs="common compiler components include os_specific"
@@ -31,7 +31,7 @@
actbl2.h actbl3.h actypes.h acutils.h amlcode.h amlresrc.h \
platform/acenv.h platform/acfreebsd.h platform/acgcc.h"
comp_headers="aslcompiler.h asldefine.h aslglobal.h aslmessages.h \
- asltypes.h dtcompiler.h dttemplate.h preprocess.h"
+ aslsupport.l asltypes.h dtcompiler.h dttemplate.h preprocess.h"
platform_headers="acfreebsd.h acgcc.h"
# pre-clean
@@ -67,7 +67,8 @@
xargs sed -i "" -e "s|[\"<]$H[\">]|\<contrib/dev/acpica/include/$H\>|g"
done
for H in ${comp_headers}; do
- find ${dst}/common ${dst}/compiler -name "*.[chly]" -type f | \
+ find ${dst}/common ${dst}/compiler ${dst}/components \
+ -name "*.[chly]" -type f | \
xargs sed -i "" -e "s|[\"<]$H[\">]|\<contrib/dev/acpica/compiler/$H\>|g"
done
for H in ${platform_headers}; do
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/changes.txt
--- a/head/sys/contrib/dev/acpica/changes.txt Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/changes.txt Wed Jul 25 16:45:04 2012 +0300
@@ -1,8 +1,277 @@
+----------------------------------------
+11 July 2012. Summary of changes for version 20120711:
+
+This release is available at https://www.acpica.org/downloads The ACPI 5.0
+specification is available at www.acpi.info
+
+1) ACPICA Kernel-resident Subsystem:
+
+Fixed a possible fault in the return package object repair code. Fixes a
+problem that can occur when a lone package object is wrapped with an outer
+package object in order to force conformance to the ACPI specification. Can
+affect these predefined names: _ALR, _MLS, _PSS, _TRT, _TSS, _PRT, _HPX, _DLM,
+_CSD, _PSD, _TSD.
+
+Removed code to disable/enable bus master arbitration (ARB_DIS bit in the
+PM2_CNT register) in the ACPICA sleep/wake interfaces. Management of the
+ARB_DIS bit must be implemented in the host-dependent C3 processor power state
+support. Note, ARB_DIS is obsolete and only applies to older chipsets, both
+Intel and other vendors. (for Intel: ICH4-M and earlier)
+
+This change removes the code to disable/enable bus master arbitration during
+suspend/resume. Use of the ARB_DIS bit in the optional PM2_CNT register causes
+resume problems on some machines. The change has been in use for over seven
+years within Linux.
+
+Implemented two new external interfaces to support host-directed dynamic ACPI
+table load and unload. They are intended to simplify the host implementation
+of hot-plug support:
+ AcpiLoadTable: Load an SSDT from a buffer into the namespace.
+ AcpiUnloadParentTable: Unload an SSDT via a named object owned by the table.
+See the ACPICA reference for additional details. Adds one new file,
+components/tables/tbxfload.c
+
+Implemented and deployed two new interfaces for errors and warnings that are
+known to be caused by BIOS/firmware issues:
+ AcpiBiosError: Prints "ACPI Firmware Error" message.
+ AcpiBiosWarning: Prints "ACPI Firmware Warning" message.
+Deployed these new interfaces in the ACPICA Table Manager code for ACPI table
+and FADT errors. Additional deployment to be completed as appropriate in the
+future. The associated conditional macros are ACPI_BIOS_ERROR and
+ACPI_BIOS_WARNING. See the ACPICA reference for additional details. ACPICA BZ
+843.
+
+Implicit notify support: ensure that no memory allocation occurs within a
+critical region. This fix moves a memory allocation outside of the time that a
+spinlock is held. Fixes issues on systems that do not allow this behavior.
+Jung-uk Kim.
+
+Split exception code utilities and tables into a new file, utilities/utexcep.c
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The debug
+version of the code includes the debug output trace mechanism and has a much
+larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 93.1K Code, 25.1K Data, 118.2K Total
+ Debug Version: 172.9K Code, 73.6K Data, 246.5K Total
+ Current Release:
+ Non-Debug Version: 93.5K Code, 25.3K Data, 118.8K Total
+ Debug Version: 173.7K Code, 74.0K Data, 247.7K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Fixed a parser problem for hosts where EOF is defined as -1 instead of
+0. Jung-uk Kim.
+
+Debugger: Enhanced the "tables" command to emit additional information about
+the current set of ACPI tables, including the owner ID and flags decode.
+
+Debugger: Reimplemented the "unload" command to use the new
+AcpiUnloadParentTable external interface. This command was disable previously
+due to need for an unload interface.
+
+AcpiHelp: Added a new option to decode ACPICA exception codes. The -e option
+will decode 16-bit hex status codes (ACPI_STATUS) to name strings.
+
+----------------------------------------
+20 June 2012. Summary of changes for version 20120620:
+
+This release is available at https://www.acpica.org/downloads
+The ACPI 5.0 specification is available at www.acpi.info
+
+1) ACPICA Kernel-resident Subsystem:
+
+Implemented support to expand the "implicit notify" feature to allow multiple
+devices to be notified by a single GPE. This feature automatically generates a
+runtime device notification in the absence of a BIOS-provided GPE control
+method (_Lxx/_Exx) or a host-installed handler for the GPE. Implicit notify is
+provided by ACPICA for Windows compatibility, and is a workaround for BIOS AML
+code errors. See the description of the AcpiSetupGpeForWake interface in the
+APCICA reference. Bob Moore, Rafael Wysocki. ACPICA BZ 918.
+
+Changed some comments and internal function names to simplify and ensure
+correctness of the Linux code translation. No functional changes.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The debug
+version of the code includes the debug output trace mechanism and has a much
+larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 93.0K Code, 25.1K Data, 118.1K Total
+ Debug Version: 172.7K Code, 73.6K Data, 246.3K Total
+ Current Release:
+ Non-Debug Version: 93.1K Code, 25.1K Data, 118.2K Total
+ Debug Version: 172.9K Code, 73.6K Data, 246.5K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Disassembler: Added support to emit short, commented descriptions for the ACPI
+predefined names in order to improve the readability of the disassembled
+output. ACPICA BZ 959. Changes include:
+ 1) Emit descriptions for all standard predefined names (_INI, _STA, _PRW,
+etc.)
+ 2) Emit generic descriptions for the special names (_Exx, _Qxx, etc.)
+ 3) Emit descriptions for the resource descriptor names (_MIN, _LEN, etc.)
+
+AcpiSrc: Fixed several long-standing Linux code translation issues. Argument
+descriptions in function headers are now translated properly to lower case and
+underscores. ACPICA BZ 961. Also fixes translation problems such as these:
+(old -> new)
+ i_aSL -> iASL
+ 00-7_f -> 00-7F
+ 16_k -> 16K
+ local_fADT -> local_FADT
+ execute_oSI -> execute_OSI
+
+iASL: Fixed a problem where null bytes were inadvertently emitted into some
+listing files.
+
+iASL: Added the existing debug options to the standard help screen. There are
+no longer two different help screens. ACPICA BZ 957.
+
+AcpiHelp: Fixed some typos in the various predefined name descriptions. Also
+expand some of the descriptions where appropriate.
+
+iASL: Fixed the -ot option (display compile times/statistics). Was not working
+properly for standard output; only worked for the debug file case.
+
+----------------------------------------
+18 May 2012. Summary of changes for version 20120518:
+
+
+1) ACPICA Core Subsystem:
+
+Added a new OSL interface, AcpiOsWaitEventsComplete. This interface is defined
+to block until asynchronous events such as notifies and GPEs have completed.
+Within ACPICA, it is only called before a notify or GPE handler is
+removed/uninstalled. It also may be useful for the host OS within related
+drivers such as the Embedded Controller driver. See the ACPICA reference for
+additional information. ACPICA BZ 868.
+
+ACPI Tables: Added a new error message for a possible overflow failure during
+the conversion of FADT 32-bit legacy register addresses to internal common 64-
+bit GAS structure representation. The GAS has a one-byte "bit length" field,
+thus limiting the register length to 255 bits. ACPICA BZ 953.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The debug
+version of the code includes the debug output trace mechanism and has a much
+larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 92.9K Code, 25.0K Data, 117.9K Total
+ Debug Version: 172.6K Code, 73.4K Data, 246.0K Total
+ Current Release:
+ Non-Debug Version: 93.0K Code, 25.1K Data, 118.1K Total
+ Debug Version: 172.7K Code, 73.6K Data, 246.3K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Added the ACPI 5.0 "PCC" keyword for use in the Register() ASL macro.
+This keyword was added late in the ACPI 5.0 release cycle and was not
+implemented until now.
+
+Disassembler: Added support for Operation Region externals. Adds missing
+support for operation regions that are defined in another table, and
+referenced locally via a Field or BankField ASL operator. Now generates the
+correct External statement.
+
+Disassembler: Several additional fixes for the External() statement generation
+related to some ASL operators. Also, order the External() statements
+alphabetically in the disassembler output. Fixes the External() generation for
+the Create* field, Alias, and Scope operators:
+ 1) Create* buffer field operators - fix type mismatch warning on disassembly
+ 2) Alias - implement missing External support
+ 3) Scope - fix to make sure all necessary externals are emitted.
+
+iASL: Improved pathname support. For include files, merge the prefix pathname
+with the file pathname and eliminate unnecessary components. Convert
+backslashes in all pathnames to forward slashes, for readability. Include file
+pathname changes affect both #include and Include() type operators.
+
+iASL/DTC/Preprocessor: Gracefully handle early EOF. Handle an EOF at the end
+of a valid line by inserting a newline and then returning the EOF during the
+next call to GetNextLine. Prevents the line from being ignored due to EOF
+condition.
+
+iASL: Implemented some changes to enhance the IDE support (-vi option.) Error
+and Warning messages are now correctly recognized for both the source code
+browser and the global error and warning counts.
+
+----------------------------------------
+20 April 2012. Summary of changes for version 20120420:
+
+
+1) ACPICA Core Subsystem:
+
+Implemented support for multiple notify handlers. This change adds support to
+allow multiple system and device notify handlers on Device, Thermal Zone, and
+Processor objects. This can simplify the host OS notification implementation.
+Also re-worked and restructured the entire notify support code to simplify
+handler installation, handler removal, notify event queuing, and notify
+dispatch to handler(s). Note: there can still only be two global notify
+handlers - one for system notifies and one for device notifies. There are no
+changes to the existing handler install/remove interfaces. Lin Ming, Bob
+Moore, Rafael Wysocki.
+
+Fixed a regression in the package repair code where the object reference
+count was calculated incorrectly. Regression was introduced in the commit
+"Support to add Package wrappers".
+
+Fixed a couple possible memory leaks in the AML parser, in the error recovery
+path. Jesper Juhl, Lin Ming.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 92.9K Code, 25.0K Data, 117.9K Total
+ Debug Version: 172.5K Code, 73.2K Data, 245.7K Total
+ Current Release:
+ Non-Debug Version: 92.9K Code, 25.0K Data, 117.9K Total
+ Debug Version: 172.6K Code, 73.4K Data, 246.0K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Fixed a problem with the resource descriptor support where the length
+of the StartDependentFn and StartDependentFnNoPrio descriptors were not
+included in cumulative descriptor offset, resulting in incorrect values for
+resource tags within resource descriptors appearing after a StartDependent*
+descriptor. Reported by Petr Vandrovec. ACPICA BZ 949.
+
+iASL and Preprocessor: Implemented full support for the #line directive to
+correctly track original source file line numbers through the .i preprocessor
+output file - for error and warning messages.
+
+iASL: Expand the allowable byte constants for address space IDs. Previously,
+the allowable range was 0x80-0xFF (user-defined spaces), now the range is
+0x0A-0xFF to allow for custom and new IDs without changing the compiler.
+
+iASL: Add option to treat all warnings as errors (-we). ACPICA BZ 948.
+
+iASL: Add option to completely disable the preprocessor (-Pn).
+
+iASL: Now emit all error/warning messages to standard error (stderr) by
+default (instead of the previous stdout).
+
+ASL Test Suite (ASLTS): Reduce iASL warnings due to use of Switch(). Update
+for resource descriptor offset fix above. Update/cleanup error output
+routines. Enable and send iASL errors/warnings to an error logfile
+(error.txt). Send all other iASL output to a logfile (compiler.txt). Fixed
+several extraneous "unrecognized operator" messages.
+
----------------------------------------
20 March 2012. Summary of changes for version 20120320:
-This release is available at www.acpica.org/downloads.
-The ACPI 5.0 specification is available at www.acpi.info.
1) ACPICA Core Subsystem:
@@ -93,8 +362,6 @@
----------------------------------------
15 February 2012. Summary of changes for version 20120215:
-This release is available at www.acpica.org/downloads.
-The ACPI 5.0 specification is available at www.acpi.info.
1) ACPICA Core Subsystem:
@@ -185,8 +452,6 @@
----------------------------------------
11 January 2012. Summary of changes for version 20120111:
-This release is available at www.acpica.org/downloads.
-The ACPI 5.0 specification is available at www.acpi.info.
1) ACPICA Core Subsystem:
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/common/adfile.c
--- a/head/sys/contrib/dev/acpica/common/adfile.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/common/adfile.c Wed Jul 25 16:45:04 2012 +0300
@@ -298,20 +298,24 @@
return (AE_NO_MEMORY);
}
- Substring = strrchr (DirectoryPath, '\\');
+ /* Convert backslashes to slashes in the entire path */
+
+ UtConvertBackslashes (DirectoryPath);
+
+ /* Backup to last slash or colon */
+
+ Substring = strrchr (DirectoryPath, '/');
if (!Substring)
{
- Substring = strrchr (DirectoryPath, '/');
- if (!Substring)
- {
- Substring = strrchr (DirectoryPath, ':');
- }
+ Substring = strrchr (DirectoryPath, ':');
}
+ /* Extract the simple filename */
+
if (!Substring)
{
+ Filename = FlStrdup (DirectoryPath);
DirectoryPath[0] = 0;
- Filename = FlStrdup (InputPath);
}
else
{
@@ -326,7 +330,6 @@
*OutDirectoryPath = DirectoryPath;
*OutFilename = Filename;
-
return (AE_OK);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/common/adwalk.c
--- a/head/sys/contrib/dev/acpica/common/adwalk.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/common/adwalk.c Wed Jul 25 16:45:04 2012 +0300
@@ -521,6 +521,7 @@
if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
(OpInfo->Class != AML_CLASS_CREATE) &&
+ (OpInfo->ObjectType != ACPI_TYPE_LOCAL_ALIAS) &&
(ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&
!Op->Common.Node)
{
@@ -743,13 +744,23 @@
if (OpInfo->Flags & AML_NAMED)
{
- if ((Op->Common.AmlOpcode == AML_ALIAS_OP) ||
- (Op->Common.AmlOpcode == AML_SCOPE_OP))
+ /*
+ * Only these two operators (Alias, Scope) refer to an existing
+ * name, it is the first argument
+ */
+ if (Op->Common.AmlOpcode == AML_ALIAS_OP)
{
- /*
- * Only these two operators refer to an existing name,
- * first argument
- */
+ ObjectType = ACPI_TYPE_ANY;
+
+ NextOp = Op->Common.Value.Arg;
+ NextOp = NextOp->Common.Value.Arg;
+ if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
+ {
+ Path = NextOp->Common.Value.String;
+ }
+ }
+ else if (Op->Common.AmlOpcode == AML_SCOPE_OP)
+ {
Path = (char *) Op->Named.Path;
}
}
@@ -757,6 +768,8 @@
{
/* Referenced Buffer Name is the first child */
+ ObjectType = ACPI_TYPE_BUFFER; /* Change from TYPE_BUFFER_FIELD */
+
NextOp = Op->Common.Value.Arg;
if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
{
@@ -783,6 +796,11 @@
Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
WalkState, &Node);
+ if (ACPI_SUCCESS (Status) && (Node->Flags & ANOBJ_IS_EXTERNAL))
+ {
+ Status = AE_NOT_FOUND;
+ }
+
if (ACPI_FAILURE (Status))
{
if (Status == AE_NOT_FOUND)
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/common/ahpredef.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/contrib/dev/acpica/common/ahpredef.c Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,323 @@
+/******************************************************************************
+ *
+ * Module Name: ahpredef - Table of all known ACPI predefined names
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+/*
+ * iASL only needs a partial table (short descriptions only).
+ * AcpiHelp needs the full table.
+ */
+#ifdef ACPI_ASL_COMPILER
+#define AH_PREDEF(Name, ShortDesc, LongDesc) {Name, ShortDesc}
+#else
+#define AH_PREDEF(Name, ShortDesc, LongDesc) {Name, ShortDesc, LongDesc}
+#endif
+
+/*
+ * Predefined ACPI names, with short description and return value.
+ * This table was extracted directly from the ACPI specification.
+ */
+const AH_PREDEFINED_NAME AslPredefinedInfo[] =
+{
+ AH_PREDEF ("_ACx", "Active Cooling", "Returns the active cooling policy threshold values"),
+ AH_PREDEF ("_ADR", "Address", "Returns the address of a device on its parent bus"),
+ AH_PREDEF ("_AEI", "ACPI Event Interrupts", "Returns a list of GPIO events to be used as ACPI events"),
+ AH_PREDEF ("_ALC", "Ambient Light Chromaticity", "Returns the ambient light color chromaticity"),
+ AH_PREDEF ("_ALI", "Ambient Light Illuminance", "Returns the ambient light brightness"),
+ AH_PREDEF ("_ALN", "Alignment", "Base alignment, Resource Descriptor field"),
+ AH_PREDEF ("_ALP", "Ambient Light Polling", "Returns the ambient light sensor polling frequency"),
+ AH_PREDEF ("_ALR", "Ambient Light Response", "Returns the ambient light brightness to display brightness mappings"),
+ AH_PREDEF ("_ALT", "Ambient Light Temperature", "Returns the ambient light color temperature"),
+ AH_PREDEF ("_ALx", "Active List", "Returns a list of active cooling device objects"),
+ AH_PREDEF ("_ART", "Active Cooling Relationship Table", "Returns thermal relationship information between platform devices and fan devices"),
+ AH_PREDEF ("_ASI", "Address Space Id", "Resource Descriptor field"),
+ AH_PREDEF ("_ASZ", "Access Size", "Resource Descriptor field"),
+ AH_PREDEF ("_ATT", "Type-Specific Attribute", "Resource Descriptor field"),
+ AH_PREDEF ("_BAS", "Base Address", "Range base address, Resource Descriptor field"),
+ AH_PREDEF ("_BBN", "BIOS Bus Number", "Returns the PCI bus number returned by the BIOS"),
+ AH_PREDEF ("_BCL", "Brightness Control Levels", "Returns a list of supported brightness control levels"),
+ AH_PREDEF ("_BCM", "Brightness Control Method", "Sets the brightness level of the display device"),
+ AH_PREDEF ("_BCT", "Battery Charge Time", "Returns time remaining to complete charging battery"),
+ AH_PREDEF ("_BDN", "BIOS Dock Name", "Returns the Dock ID returned by the BIOS"),
+ AH_PREDEF ("_BFS", "Back From Sleep", "Inform AML of a wake event"),
+ AH_PREDEF ("_BIF", "Battery Information", "Returns a Control Method Battery information block"),
+ AH_PREDEF ("_BIX", "Battery Information Extended", "Returns a Control Method Battery extended information block"),
+ AH_PREDEF ("_BLT", "Battery Level Threshold", "Set battery level threshold preferences"),
+ AH_PREDEF ("_BM_", "Bus Master", "Resource Descriptor field"),
+ AH_PREDEF ("_BMA", "Battery Measurement Averaging Interval", "Sets battery measurement averaging interval"),
+ AH_PREDEF ("_BMC", "Battery Maintenance Control", "Sets battery maintenance and control features"),
+ AH_PREDEF ("_BMD", "Battery Maintenance Data", "Returns battery maintenance, control, and state data"),
+ AH_PREDEF ("_BMS", "Battery Measurement Sampling Time", "Sets the battery measurement sampling time"),
+ AH_PREDEF ("_BQC", "Brightness Query Current", "Returns the current display brightness level"),
+ AH_PREDEF ("_BST", "Battery Status", "Returns a Control Method Battery status block"),
+ AH_PREDEF ("_BTM", "Battery Time", "Returns the battery runtime"),
+ AH_PREDEF ("_BTP", "Battery Trip Point", "Sets a Control Method Battery trip point"),
+ AH_PREDEF ("_CBA", "Configuration Base Address", "Sets the base address for a PCI Express host bridge"),
+ AH_PREDEF ("_CDM", "Clock Domain", "Returns a logical processor's clock domain identifier"),
+ AH_PREDEF ("_CID", "Compatible ID", "Returns a device's Plug and Play Compatible ID list"),
+ AH_PREDEF ("_CLS", "Class Code", "Returns PCI class code and subclass"),
+ AH_PREDEF ("_CPC", "Continuous Performance Control", "Returns a list of performance control interfaces"),
+ AH_PREDEF ("_CRS", "Current Resource Settings", "Returns the current resource settings for a device"),
+ AH_PREDEF ("_CRT", "Critical Temperature", "Returns the shutdown critical temperature"),
+ AH_PREDEF ("_CSD", "C-State Dependencies", "Returns a list of C-state dependencies"),
+ AH_PREDEF ("_CST", "C-States", "Returns a list of supported C-states"),
+ AH_PREDEF ("_CWS", "Clear Wake Alarm Status", "Clear the status of wake alarms"),
+ AH_PREDEF ("_DBT", "Debounce Timeout", "Timeout value, Resource Descriptor field"),
+ AH_PREDEF ("_DCK", "Dock Present", "Sets docking isolation. Presence indicates device is a docking station"),
+ AH_PREDEF ("_DCS", "Display Current Status", "Returns status of the display output device"),
+ AH_PREDEF ("_DDC", "Display Data Current", "Returns the EDID for the display output device"),
+ AH_PREDEF ("_DDN", "DOS Device Name", "Returns a device logical name"),
+ AH_PREDEF ("_DEC", "Decode", "Device decoding type, Resource Descriptor field"),
+ AH_PREDEF ("_DEP", "Dependencies", "Returns a list of operation region dependencies"),
+ AH_PREDEF ("_DGS", "Display Graphics State", "Return the current state of the output device"),
+ AH_PREDEF ("_DIS", "Disable Device", "Disables a device"),
+ AH_PREDEF ("_DLM", "Device Lock Mutex", "Defines mutex for OS/AML sharing"),
+ AH_PREDEF ("_DMA", "Direct Memory Access", "Returns a device's current resources for DMA transactions"),
+ AH_PREDEF ("_DOD", "Display Output Devices", "Enumerate all devices attached to the display adapter"),
+ AH_PREDEF ("_DOS", "Disable Output Switching", "Sets the display output switching mode"),
+ AH_PREDEF ("_DPL", "Device Selection Polarity", "Polarity of Device Selection signal, Resource Descriptor field"),
+ AH_PREDEF ("_DRS", "Drive Strength", "Drive Strength setting for GPIO connection, Resource Descriptor field"),
+ AH_PREDEF ("_DSM", "Device-Specific Method", "Executes device-specific functions"),
+ AH_PREDEF ("_DSS", "Device Set State", "Sets the display device state"),
+ AH_PREDEF ("_DSW", "Device Sleep Wake", "Sets the sleep and wake transition states for a device"),
+ AH_PREDEF ("_DTI", "Device Temperature Indication", "Conveys native device temperature to the platform"),
+ AH_PREDEF ("_Exx", "Edge-Triggered GPE", "Method executed as a result of a general-purpose event"),
+ AH_PREDEF ("_EC_", "Embedded Controller", "returns EC offset and query information"),
+ AH_PREDEF ("_EDL", "Eject Device List", "Returns a list of devices that are dependent on a device (docking)"),
+ AH_PREDEF ("_EJD", "Ejection Dependent Device", "Returns the name of dependent (parent) device (docking)"),
+ AH_PREDEF ("_EJx", "Eject Device", "Begin or cancel a device ejection request (docking)"),
+ AH_PREDEF ("_END", "Endianness", "Endian orientation, Resource Descriptor field"),
+ AH_PREDEF ("_EVT", "Event", "Event method for GPIO events"),
+ AH_PREDEF ("_FDE", "Floppy Disk Enumerate", "Returns floppy disk configuration information"),
+ AH_PREDEF ("_FDI", "Floppy Drive Information", "Returns a floppy drive information block"),
+ AH_PREDEF ("_FDM", "Floppy Drive Mode", "Sets a floppy drive speed"),
+ AH_PREDEF ("_FIF", "Fan Information", "Returns fan device information"),
+ AH_PREDEF ("_FIX", "Fixed Register Resource Provider", "Returns a list of devices that implement FADT register blocks"),
+ AH_PREDEF ("_FLC", "Flow Control", "Flow control, Resource Descriptor field"),
+ AH_PREDEF ("_FPS", "Fan Performance States", "Returns a list of supported fan performance states"),
+ AH_PREDEF ("_FSL", "Fan Set Level", "Control method that sets the fan device's speed level (performance state)"),
+ AH_PREDEF ("_FST", "Fan Status", "Returns current status information for a fan device"),
+ AH_PREDEF ("_GAI", "Get Averaging Interval", "Returns the power meter averaging interval"),
+ AH_PREDEF ("_GCP", "Get Capabilities", "Get device time capabilities"),
+ AH_PREDEF ("_GHL", "Get Hardware Limit", "Returns the hardware limit enforced by the power meter"),
+ AH_PREDEF ("_GL_", "Global Lock", "OS-defined Global Lock mutex object"),
+ AH_PREDEF ("_GLK", "Get Global Lock Requirement", "Returns a device's Global Lock requirement for device access"),
+ AH_PREDEF ("_GPD", "Get Post Data", "Returns the value of the VGA device that will be posted at boot"),
+ AH_PREDEF ("_GPE", "General Purpose Events", "Predefined scope (\\_GPE) or SCI number for EC"),
+ AH_PREDEF ("_GRA", "Granularity", "Address space granularity, Resource Descriptor field"),
+ AH_PREDEF ("_GRT", "Get Real Time", "Returns current time-of-day from a time/alarm device"),
+ AH_PREDEF ("_GSB", "Global System Interrupt Base", "Returns the GSB for a I/O APIC device"),
+ AH_PREDEF ("_GTF", "Get Task File", "Returns a list of ATA commands to restore a drive to default state"),
+ AH_PREDEF ("_GTM", "Get Timing Mode", "Returns a list of IDE controller timing information"),
+ AH_PREDEF ("_GTS", "Going To Sleep", "Inform AML of pending sleep"),
+ AH_PREDEF ("_GWS", "Get Wake Status", "Return status of wake alarms"),
+ AH_PREDEF ("_HE_", "High-Edge", "Interrupt triggering, Resource Descriptor field"),
+ AH_PREDEF ("_HID", "Hardware ID", "Returns a device's Plug and Play Hardware ID"),
+ AH_PREDEF ("_HOT", "Hot Temperature", "Returns the critical temperature for sleep (entry to S4)"),
+ AH_PREDEF ("_HPP", "Hot Plug Parameters", "Returns a list of hot-plug information for a PCI device"),
+ AH_PREDEF ("_HPX", "Hot Plug Parameter Extensions", "Returns a list of hot-plug information for a PCI device. Supersedes _HPP"),
+ AH_PREDEF ("_HRV", "Hardware Revision", "Returns a hardware revision value"),
+ AH_PREDEF ("_IFT", "IPMI Interface Type", "See the Intelligent Platform Management Interface Specification"),
+ AH_PREDEF ("_INI", "Initialize", "Performs device specific initialization"),
+ AH_PREDEF ("_INT", "Interrupts", "Interrupt mask bits, Resource Descriptor field"),
+ AH_PREDEF ("_IOR", "I/O Restriction", "Restriction type, Resource Descriptor field"),
+ AH_PREDEF ("_IRC", "Inrush Current", "Presence indicates that a device has a significant inrush current draw"),
+ AH_PREDEF ("_Lxx", "Level-Triggered GPE", "Control method executed as a result of a general-purpose event"),
+ AH_PREDEF ("_LCK", "Lock Device", "Locks or unlocks a device (docking)"),
+ AH_PREDEF ("_LEN", "Length", "Range length, Resource Descriptor field"),
+ AH_PREDEF ("_LID", "Lid Status", "Returns the open/closed status of the lid on a mobile system"),
+ AH_PREDEF ("_LIN", "Lines In Use", "Handshake lines, Resource Descriptor field"),
+ AH_PREDEF ("_LL_", "Low Level", "Interrupt polarity, Resource Descriptor field"),
+ AH_PREDEF ("_MAF", "Maximum Address Fixed", "Resource Descriptor field"),
+ AH_PREDEF ("_MAT", "Multiple APIC Table Entry", "Returns a list of MADT APIC structure entries"),
+ AH_PREDEF ("_MAX", "Maximum Base Address", "Resource Descriptor field"),
+ AH_PREDEF ("_MBM", "Memory Bandwidth Monitoring Data", "Returns bandwidth monitoring data for a memory device"),
+ AH_PREDEF ("_MEM", "Memory Attributes", "Resource Descriptor field"),
+ AH_PREDEF ("_MIF", "Minimum Address Fixed", "Resource Descriptor field"),
+ AH_PREDEF ("_MIN", "Minimum Base Address", "Resource Descriptor field"),
+ AH_PREDEF ("_MLS", "Multiple Language String", "Returns a device description in multiple languages"),
+ AH_PREDEF ("_MOD", "Mode", "Interrupt mode, Resource Descriptor field"),
+ AH_PREDEF ("_MSG", "Message", "Sets the system message waiting status indicator"),
+ AH_PREDEF ("_MSM", "Memory Set Monitoring", "Sets bandwidth monitoring parameters for a memory device"),
+ AH_PREDEF ("_MTP", "Memory Type", "Resource Descriptor field"),
+ AH_PREDEF ("_NTT", "Notification Temperature Threshold", "Returns a threshold for device temperature change that requires platform notification"),
+ AH_PREDEF ("_OFF", "Power Off", "Sets a power resource to the off state"),
+ AH_PREDEF ("_ON_", "Power On", "Sets a power resource to the on state"),
+ AH_PREDEF ("_OS_", "Operating System", "Returns a string that identifies the operating system"),
+ AH_PREDEF ("_OSC", "Operating System Capabilities", "Inform AML of host features and capabilities"),
+ AH_PREDEF ("_OSI", "Operating System Interfaces", "Returns supported interfaces, behaviors, and features"),
+ AH_PREDEF ("_OST", "OSPM Status Indication", "Inform AML of event processing status"),
+ AH_PREDEF ("_PAI", "Power Averaging Interval", "Sets the averaging interval for a power meter"),
+ AH_PREDEF ("_PAR", "Parity", "Parity bits, Resource Descriptor field"),
+ AH_PREDEF ("_PCL", "Power Consumer List", "Returns a list of devices powered by a power source"),
+ AH_PREDEF ("_PCT", "Performance Control", "Returns processor performance control and status registers"),
+ AH_PREDEF ("_PDC", "Processor Driver Capabilities", "Inform AML of processor driver capabilities"),
+ AH_PREDEF ("_PDL", "P-state Depth Limit", "Returns the lowest available performance P-state"),
+ AH_PREDEF ("_PHA", "Clock Phase", "Clock phase, Resource Descriptor field"),
+ AH_PREDEF ("_PIC", "Interrupt Model", "Inform AML of the interrupt model in use"),
+ AH_PREDEF ("_PIF", "Power Source Information", "Returns a Power Source information block"),
+ AH_PREDEF ("_PIN", "Pin List", "Pin list, Resource Descriptor field"),
+ AH_PREDEF ("_PLD", "Physical Device Location", "Returns a device's physical location information"),
+ AH_PREDEF ("_PMC", "Power Meter Capabilities", "Returns a list of Power Meter capabilities info"),
+ AH_PREDEF ("_PMD", "Power Metered Devices", "Returns a list of devices that are measured by the power meter device"),
+ AH_PREDEF ("_PMM", "Power Meter Measurement", "Returns the current value of the Power Meter"),
+ AH_PREDEF ("_POL", "Polarity", "Interrupt polarity, Resource Descriptor field"),
+ AH_PREDEF ("_PPC", "Performance Present Capabilites", "Returns a list of the performance states currently supported by the platform"),
+ AH_PREDEF ("_PPE", "Polling for Platform Error", "Returns the polling interval to retrieve Corrected Platform Error information"),
+ AH_PREDEF ("_PPI", "Pin Configuration", "Resource Descriptor field"),
+ AH_PREDEF ("_PR", "Processor", "Predefined scope for processor objects"),
+ AH_PREDEF ("_PR0", "Power Resources for D0", "Returns a list of dependent power resources to enter state D0 (fully on)"),
+ AH_PREDEF ("_PR1", "Power Resources for D1", "Returns a list of dependent power resources to enter state D1"),
+ AH_PREDEF ("_PR2", "Power Resources for D2", "Returns a list of dependent power resources to enter state D2"),
+ AH_PREDEF ("_PR3", "Power Resources for D3hot", "Returns a list of dependent power resources to enter state D3hot"),
+ AH_PREDEF ("_PRE", "Power Resources for Enumeration", "Returns a list of dependent power resources to enumerate devices on a bus"),
+ AH_PREDEF ("_PRL", "Power Source Redundancy List", "Returns a list of power source devices in the same redundancy grouping"),
+ AH_PREDEF ("_PRS", "Possible Resource Settings", "Returns a list of a device's possible resource settings"),
+ AH_PREDEF ("_PRT", "PCI Routing Table", "Returns a list of PCI interrupt mappings"),
+ AH_PREDEF ("_PRW", "Power Resources for Wake", "Returns a list of dependent power resources for waking"),
+ AH_PREDEF ("_PS0", "Power State 0", "Sets a device's power state to D0 (device fully on)"),
+ AH_PREDEF ("_PS1", "Power State 1", "Sets a device's power state to D1"),
+ AH_PREDEF ("_PS2", "Power State 2", "Sets a device's power state to D2"),
+ AH_PREDEF ("_PS3", "Power State 3", "Sets a device's power state to D3 (device off)"),
+ AH_PREDEF ("_PSC", "Power State Current", "Returns a device's current power state"),
+ AH_PREDEF ("_PSD", "Power State Dependencies", "Returns processor P-State dependencies"),
+ AH_PREDEF ("_PSE", "Power State for Enumeration", "Put a bus into enumeration power mode"),
+ AH_PREDEF ("_PSL", "Passive List", "Returns a list of passive cooling device objects"),
+ AH_PREDEF ("_PSR", "Power Source", "Returns the power source device currently in use"),
+ AH_PREDEF ("_PSS", "Performance Supported States", "Returns a list of supported processor performance states"),
+ AH_PREDEF ("_PSV", "Passive Temperature", "Returns the passive trip point temperature"),
+ AH_PREDEF ("_PSW", "Power State Wake", "Sets a device's wake function"),
+ AH_PREDEF ("_PTC", "Processor Throttling Control", "Returns throttling control and status registers"),
+ AH_PREDEF ("_PTP", "Power Trip Points", "Sets trip points for the Power Meter device"),
+ AH_PREDEF ("_PTS", "Prepare To Sleep", "Inform the platform of an impending sleep transition"),
+ AH_PREDEF ("_PUR", "Processor Utilization Request", "Returns the number of processors that the platform would like to idle"),
+ AH_PREDEF ("_PXM", "Device Proximity", "Returns a device's proximity domain identifier"),
+ AH_PREDEF ("_Qxx", "EC Query", "Embedded Controller query and SMBus Alarm control method"),
+ AH_PREDEF ("_RBO", "Register Bit Offset", "Resource Descriptor field"),
+ AH_PREDEF ("_RBW", "Register Bit Width", "Resource Descriptor field"),
+ AH_PREDEF ("_REG", "Region Availability", "Inform AML code of an operation region availability change"),
+ AH_PREDEF ("_REV", "Supported ACPI Revision", "Returns the revision of the ACPI specification that is implemented"),
+ AH_PREDEF ("_RMV", "Removal Status", "Returns a device's removal ability status (docking)"),
+ AH_PREDEF ("_RNG", "Range", "Memory range type, Resource Descriptor field"),
+ AH_PREDEF ("_ROM", "Read-Only Memory", "Returns a copy of the ROM data for a display device"),
+ AH_PREDEF ("_RT_", "Resource Type", "Resource Descriptor field"),
+ AH_PREDEF ("_RTV", "Relative Temperature Values", "Returns temperature value information"),
+ AH_PREDEF ("_RW_", "Read-Write Status", "Resource Descriptor field"),
+ AH_PREDEF ("_RXL", "Receive Buffer Size", "Serial channel buffer, Resource Descriptor field"),
+ AH_PREDEF ("_S0_", "S0 System State", "Returns values to enter the system into the S0 state"),
+ AH_PREDEF ("_S1_", "S1 System State", "Returns values to enter the system into the S1 state"),
+ AH_PREDEF ("_S2_", "S2 System State", "Returns values to enter the system into the S2 state"),
+ AH_PREDEF ("_S3_", "S3 System State", "Returns values to enter the system into the S3 state"),
+ AH_PREDEF ("_S4_", "S4 System State", "Returns values to enter the system into the S4 state"),
+ AH_PREDEF ("_S5_", "S5 System State", "Returns values to enter the system into the S5 state"),
+ AH_PREDEF ("_S1D", "S1 Device State", "Returns the highest D-state supported by a device when in the S1 state"),
+ AH_PREDEF ("_S2D", "S2 Device State", "Returns the highest D-state supported by a device when in the S2 state"),
+ AH_PREDEF ("_S3D", "S3 Device State", "Returns the highest D-state supported by a device when in the S3 state"),
+ AH_PREDEF ("_S4D", "S4 Device State", "Returns the highest D-state supported by a device when in the S4 state"),
+ AH_PREDEF ("_S0W", "S0 Device Wake State", "Returns the lowest D-state that the device can wake itself from S0"),
+ AH_PREDEF ("_S1W", "S1 Device Wake State", "Returns the lowest D-state for this device that can wake the system from S1"),
+ AH_PREDEF ("_S2W", "S2 Device Wake State", "Returns the lowest D-state for this device that can wake the system from S2"),
+ AH_PREDEF ("_S3W", "S3 Device Wake State", "Returns the lowest D-state for this device that can wake the system from S3"),
+ AH_PREDEF ("_S4W", "S4 Device Wake State", "Returns the lowest D-state for this device that can wake the system from S4"),
+ AH_PREDEF ("_SB_", "System Bus", "Predefined scope for device and bus objects"),
+ AH_PREDEF ("_SBS", "Smart Battery Subsystem", "Returns the subsystem configuration"),
+ AH_PREDEF ("_SCP", "Set Cooling Policy", "Sets the cooling policy (active or passive)"),
+ AH_PREDEF ("_SDD", "Set Device Data", "Sets data for a SATA device"),
+ AH_PREDEF ("_SEG", "PCI Segment", "Returns a device's PCI Segment Group number"),
+ AH_PREDEF ("_SHL", "Set Hardware Limit", "Sets the hardware limit enforced by the Power Meter"),
+ AH_PREDEF ("_SHR", "Sharable", "Interrupt share status, Resource Descriptor field"),
+ AH_PREDEF ("_SI_", "System Indicators", "Predefined scope"),
+ AH_PREDEF ("_SIZ", "Size", "DMA transfer size, Resource Descriptor field"),
+ AH_PREDEF ("_SLI", "System Locality Information", "Returns a list of NUMA system localities"),
+ AH_PREDEF ("_SLV", "Slave Mode", "Mode setting, Resource Descriptor field"),
+ AH_PREDEF ("_SPD", "Set Post Device", "Sets which video device will be posted at boot"),
+ AH_PREDEF ("_SPE", "Speed", "Connection speed, Resource Descriptor field"),
+ AH_PREDEF ("_SRS", "Set Resource Settings", "Sets a device's resource allocation"),
+ AH_PREDEF ("_SRT", "Set Real Time", "Sets the current time for a time/alarm device"),
+ AH_PREDEF ("_SRV", "IPMI Spec Revision", "See the Intelligent Platform Management Interface Specification"),
+ AH_PREDEF ("_SST", "System Status", "Sets the system status indicator"),
+ AH_PREDEF ("_STA", "Status", "Returns the current status of a Device or Power Resource"),
+ AH_PREDEF ("_STB", "Stop Bits", "Serial channel stop bits, Resource Descriptor field"),
+ AH_PREDEF ("_STM", "Set Timing Mode", "Sets an IDE controller transfer timings"),
+ AH_PREDEF ("_STP", "Set Expired Timer Wake Policy", "Sets expired timer policies of the wake alarm device"),
+ AH_PREDEF ("_STR", "Description String", "Returns a device's description string"),
+ AH_PREDEF ("_STV", "Set Timer Value", "Set timer values of the wake alarm device"),
+ AH_PREDEF ("_SUB", "Subsystem ID", "Returns the subsystem ID for a device"),
+ AH_PREDEF ("_SUN", "Slot User Number", "Returns the slot unique ID number"),
+ AH_PREDEF ("_SWS", "System Wake Source", "Returns the source event that caused the system to wake"),
+ AH_PREDEF ("_T_x", "Emitted by ASL Compiler", "Reserved for use by ASL compilers"),
+ AH_PREDEF ("_TC1", "Thermal Constant 1", "Returns TC1 for the passive cooling formula"),
+ AH_PREDEF ("_TC2", "Thermal Constant 2", "Returns TC2 for the passive cooling formula"),
+ AH_PREDEF ("_TDL", "T-State Depth Limit", "Returns the _TSS entry number of the lowest power throttling state"),
+ AH_PREDEF ("_TIP", "Expired Timer Wake Policy", "Returns timer policies of the wake alarm device"),
+ AH_PREDEF ("_TIV", "Timer Values", "Returns remaining time of the wake alarm device"),
+ AH_PREDEF ("_TMP", "Temperature", "Returns a thermal zone's current temperature"),
+ AH_PREDEF ("_TPC", "Throttling Present Capabilities", "Returns the current number of supported throttling states"),
+ AH_PREDEF ("_TPT", "Trip Point Temperature", "Inform AML that a device's embedded temperature sensor has crossed a temperature trip point"),
+ AH_PREDEF ("_TRA", "Translation", "Address translation offset, Resource Descriptor field"),
+ AH_PREDEF ("_TRS", "Translation Sparse", "Sparse/dense flag, Resource Descriptor field"),
+ AH_PREDEF ("_TRT", "Thermal Relationship Table", "Returns thermal relationships between platform devices"),
+ AH_PREDEF ("_TSD", "Throttling State Dependencies", "Returns a list of T-state dependencies"),
+ AH_PREDEF ("_TSF", "Type-Specific Flags", "Resource Descriptor field"),
+ AH_PREDEF ("_TSP", "Thermal Sampling Period", "Returns the thermal sampling period for passive cooling"),
+ AH_PREDEF ("_TSS", "Throttling Supported States", "Returns supported throttling state information"),
+ AH_PREDEF ("_TST", "Temperature Sensor Threshold", "Returns the minimum separation for a device's temperature trip points"),
+ AH_PREDEF ("_TTP", "Translation Type", "Translation/static flag, Resource Descriptor field"),
+ AH_PREDEF ("_TTS", "Transition To State", "Inform AML of an S-state transition"),
+ AH_PREDEF ("_TXL", "Transmit Buffer Size", "Serial Channel buffer, Resource Descriptor field"),
+ AH_PREDEF ("_TYP", "Type", "DMA channel type (speed), Resource Descriptor field"),
+ AH_PREDEF ("_TZ_", "Thermal Zone", "Predefined scope: ACPI 1.0"),
+ AH_PREDEF ("_TZD", "Thermal Zone Devices", "Returns a list of device names associated with a Thermal Zone"),
+ AH_PREDEF ("_TZM", "Thermal Zone Member", "Returns a reference to the thermal zone of which a device is a member"),
+ AH_PREDEF ("_TZP", "Thermal Zone Polling", "Returns a Thermal zone's polling frequency"),
+ AH_PREDEF ("_UID", "Unique ID", "Return a device's unique persistent ID"),
+ AH_PREDEF ("_UPC", "USB Port Capabilities", "Returns a list of USB port capabilities"),
+ AH_PREDEF ("_UPD", "User Presence Detect", "Returns user detection information"),
+ AH_PREDEF ("_UPP", "User Presence Polling", "Returns the recommended user presence polling interval"),
+ AH_PREDEF ("_VEN", "Vendor Data", "Resource Descriptor field"),
+ AH_PREDEF ("_VPO", "Video Post Options", "Returns the implemented video post options"),
+ AH_PREDEF ("_WAK", "Wake", "Inform AML that the system has just awakened"),
+ AH_PREDEF ("_Wxx", "Wake Event", "Method executed as a result of a wake event"),
+ AH_PREDEF (NULL, NULL, NULL)
+};
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/common/dmextern.c
--- a/head/sys/contrib/dev/acpica/common/dmextern.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/common/dmextern.c Wed Jul 25 16:45:04 2012 +0300
@@ -221,8 +221,10 @@
*/
ACPI_STRCAT (Fullpath, ParentPath);
- /* Add dot separator (don't need dot if parent fullpath is a single "\") */
-
+ /*
+ * Add dot separator
+ * (don't need dot if parent fullpath is a single backslash)
+ */
if (ParentPath[1])
{
ACPI_STRCAT (Fullpath, ".");
@@ -454,12 +456,12 @@
NewExternal->InternalPath = Path;
- /* Link the new descriptor into the global list, ordered by string length */
+ /* Link the new descriptor into the global list, alphabetically ordered */
NextExternal = AcpiGbl_ExternalList;
while (NextExternal)
{
- if (NewExternal->Length <= NextExternal->Length)
+ if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
{
if (PrevExternal)
{
@@ -508,7 +510,7 @@
{
ACPI_STATUS Status;
ACPI_NAMESPACE_NODE *Node;
- ACPI_OPERAND_OBJECT *MethodDesc;
+ ACPI_OPERAND_OBJECT *ObjDesc;
ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
@@ -527,13 +529,29 @@
"while adding external to namespace [%s]",
External->Path));
}
- else if (External->Type == ACPI_TYPE_METHOD)
+
+ else switch (External->Type)
{
+ case ACPI_TYPE_METHOD:
+
/* For methods, we need to save the argument count */
- MethodDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
- MethodDesc->Method.ParamCount = (UINT8) External->Value;
- Node->Object = MethodDesc;
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
+ ObjDesc->Method.ParamCount = (UINT8) External->Value;
+ Node->Object = ObjDesc;
+ break;
+
+ case ACPI_TYPE_REGION:
+
+ /* Regions require a region sub-object */
+
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
+ ObjDesc->Region.Node = Node;
+ Node->Object = ObjDesc;
+ break;
+
+ default:
+ break;
}
External = External->Next;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/common/dmrestag.c
--- a/head/sys/contrib/dev/acpica/common/dmrestag.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/common/dmrestag.c Wed Jul 25 16:45:04 2012 +0300
@@ -73,6 +73,7 @@
static char *
AcpiGetTagPathname (
+ ACPI_PARSE_OBJECT *Op,
ACPI_NAMESPACE_NODE *BufferNode,
ACPI_NAMESPACE_NODE *ResourceNode,
UINT32 BitIndex);
@@ -443,7 +444,6 @@
ACPI_NAMESPACE_NODE *BufferNode;
ACPI_NAMESPACE_NODE *ResourceNode;
const ACPI_OPCODE_INFO *OpInfo;
- char *Pathname;
UINT32 BitIndex;
@@ -519,14 +519,7 @@
/* Translate the Index to a resource tag pathname */
- Pathname = AcpiGetTagPathname (BufferNode, ResourceNode, BitIndex);
- if (Pathname)
- {
- /* Complete the conversion of the Index to a symbol */
-
- IndexOp->Common.AmlOpcode = AML_INT_NAMEPATH_OP;
- IndexOp->Common.Value.String = Pathname;
- }
+ AcpiGetTagPathname (IndexOp, BufferNode, ResourceNode, BitIndex);
}
@@ -597,6 +590,7 @@
static char *
AcpiGetTagPathname (
+ ACPI_PARSE_OBJECT *IndexOp,
ACPI_NAMESPACE_NODE *BufferNode,
ACPI_NAMESPACE_NODE *ResourceNode,
UINT32 BitIndex)
@@ -689,6 +683,15 @@
AcpiNsInternalizeName (Pathname, &InternalPath);
ACPI_FREE (Pathname);
+
+ /* Update the Op with the symbol */
+
+ AcpiPsInitOp (IndexOp, AML_INT_NAMEPATH_OP);
+ IndexOp->Common.Value.String = InternalPath;
+
+ /* We will need the tag later. Cheat by putting it in the Node field */
+
+ IndexOp->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Tag);
return (InternalPath);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/aslcompile.c
--- a/head/sys/contrib/dev/acpica/compiler/aslcompile.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/aslcompile.c Wed Jul 25 16:45:04 2012 +0300
@@ -59,14 +59,18 @@
static void
FlConsumeAnsiComment (
- ASL_FILE_INFO *FileInfo,
+ FILE *Handle,
ASL_FILE_STATUS *Status);
static void
FlConsumeNewComment (
- ASL_FILE_INFO *FileInfo,
+ FILE *Handle,
ASL_FILE_STATUS *Status);
+static void
+CmDumpAllEvents (
+ void);
+
/*******************************************************************************
*
@@ -242,10 +246,10 @@
while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR)
{
- InsertLineBuffer ((int) Buffer);
+ AslInsertLineBuffer ((int) Buffer);
}
- ResetCurrentLineBuffer ();
+ AslResetCurrentLineBuffer ();
}
@@ -253,7 +257,8 @@
*
* FUNCTION: FlConsume*
*
- * PARAMETERS: FileInfo - Points to an open input file
+ * PARAMETERS: Handle - Open input file
+ * Status - File current status struct
*
* RETURN: Number of lines consumed
*
@@ -263,14 +268,14 @@
static void
FlConsumeAnsiComment (
- ASL_FILE_INFO *FileInfo,
+ FILE *Handle,
ASL_FILE_STATUS *Status)
{
UINT8 Byte;
BOOLEAN ClosingComment = FALSE;
- while (fread (&Byte, 1, 1, FileInfo->Handle))
+ while (fread (&Byte, 1, 1, Handle))
{
/* Scan until comment close is found */
@@ -307,13 +312,13 @@
static void
FlConsumeNewComment (
- ASL_FILE_INFO *FileInfo,
+ FILE *Handle,
ASL_FILE_STATUS *Status)
{
UINT8 Byte;
- while (fread (&Byte, 1, 1, FileInfo->Handle))
+ while (fread (&Byte, 1, 1, Handle))
{
Status->Offset++;
@@ -332,7 +337,9 @@
*
* FUNCTION: FlCheckForAscii
*
- * PARAMETERS: FileInfo - Points to an open input file
+ * PARAMETERS: Handle - Open input file
+ * Filename - Input filename
+ * DisplayErrors - TRUE if error messages desired
*
* RETURN: Status
*
@@ -347,7 +354,9 @@
ACPI_STATUS
FlCheckForAscii (
- ASL_FILE_INFO *FileInfo)
+ FILE *Handle,
+ char *Filename,
+ BOOLEAN DisplayErrors)
{
UINT8 Byte;
ACPI_SIZE BadBytes = 0;
@@ -360,7 +369,7 @@
/* Read the entire file */
- while (fread (&Byte, 1, 1, FileInfo->Handle))
+ while (fread (&Byte, 1, 1, Handle))
{
/* Ignore comment fields (allow non-ascii within) */
@@ -370,12 +379,12 @@
if (Byte == '*')
{
- FlConsumeAnsiComment (FileInfo, &Status);
+ FlConsumeAnsiComment (Handle, &Status);
}
if (Byte == '/')
{
- FlConsumeNewComment (FileInfo, &Status);
+ FlConsumeNewComment (Handle, &Status);
}
/* Reset */
@@ -391,7 +400,7 @@
if (!ACPI_IS_ASCII (Byte))
{
- if (BadBytes < 10)
+ if ((BadBytes < 10) && (DisplayErrors))
{
AcpiOsPrintf (
"Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n",
@@ -413,20 +422,24 @@
/* Seek back to the beginning of the source file */
- fseek (FileInfo->Handle, 0, SEEK_SET);
+ fseek (Handle, 0, SEEK_SET);
/* Were there any non-ASCII characters in the file? */
if (BadBytes)
{
- AcpiOsPrintf (
- "%u non-ASCII characters found in input source text, could be a binary file\n",
- BadBytes);
- AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, FileInfo->Filename);
+ if (DisplayErrors)
+ {
+ AcpiOsPrintf (
+ "%u non-ASCII characters found in input source text, could be a binary file\n",
+ BadBytes);
+ AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename);
+ }
+
return (AE_BAD_CHARACTER);
}
- /* File is OK */
+ /* File is OK (100% ASCII) */
return (AE_OK);
}
@@ -457,16 +470,20 @@
Event = UtBeginEvent ("Open input and output files");
UtEndEvent (Event);
- /* Preprocessor */
+ Event = UtBeginEvent ("Preprocess input file");
+ if (Gbl_PreprocessFlag)
+ {
+ /* Preprocessor */
- Event = UtBeginEvent ("Preprocess input file");
- PrDoPreprocess ();
+ PrDoPreprocess ();
+ if (Gbl_PreprocessOnly)
+ {
+ UtEndEvent (Event);
+ CmCleanupAndExit ();
+ return 0;
+ }
+ }
UtEndEvent (Event);
- if (Gbl_PreprocessOnly)
- {
- CmCleanupAndExit ();
- return 0;
- }
/* Build the parse tree */
@@ -483,8 +500,17 @@
if (!RootNode)
{
- AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
- NULL, "- Could not resolve parse tree root node");
+ /*
+ * If there are no errors, then we have some sort of
+ * internal problem.
+ */
+ Status = AslCheckForErrorExit ();
+ if (Status == AE_OK)
+ {
+ AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
+ NULL, "- Could not resolve parse tree root node");
+ }
+
goto ErrorExit;
}
@@ -553,14 +579,14 @@
if (Gbl_ParseOnlyFlag)
{
- AePrintErrorLog (ASL_FILE_STDOUT);
- UtDisplaySummary (ASL_FILE_STDOUT);
+ AePrintErrorLog (ASL_FILE_STDERR);
+ UtDisplaySummary (ASL_FILE_STDERR);
if (Gbl_DebugFlag)
{
- /* Print error summary to the debug file */
+ /* Print error summary to the stdout also */
- AePrintErrorLog (ASL_FILE_STDERR);
- UtDisplaySummary (ASL_FILE_STDERR);
+ AePrintErrorLog (ASL_FILE_STDOUT);
+ UtDisplaySummary (ASL_FILE_STDOUT);
}
UtEndEvent (FullCompile);
return 0;
@@ -695,45 +721,65 @@
/*******************************************************************************
*
- * FUNCTION: CmDumpEvent
+ * FUNCTION: CmDumpAllEvents
*
- * PARAMETERS: Event - A compiler event struct
+ * PARAMETERS: None
*
* RETURN: None.
*
- * DESCRIPTION: Dump a compiler event struct
+ * DESCRIPTION: Dump all compiler events
*
******************************************************************************/
static void
-CmDumpEvent (
- ASL_EVENT_INFO *Event)
+CmDumpAllEvents (
+ void)
{
+ ASL_EVENT_INFO *Event;
UINT32 Delta;
UINT32 USec;
UINT32 MSec;
+ UINT32 i;
- if (!Event->Valid)
+
+ Event = AslGbl_Events;
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
+ if (Gbl_CompileTimesFlag)
{
- return;
+ printf ("\nElapsed time for major events\n\n");
}
- /* Delta will be in 100-nanosecond units */
+ for (i = 0; i < AslGbl_NextEvent; i++)
+ {
+ if (Event->Valid)
+ {
+ /* Delta will be in 100-nanosecond units */
- Delta = (UINT32) (Event->EndTime - Event->StartTime);
+ Delta = (UINT32) (Event->EndTime - Event->StartTime);
- USec = Delta / 10;
- MSec = Delta / 10000;
+ USec = Delta / 10;
+ MSec = Delta / 10000;
- /* Round milliseconds up */
+ /* Round milliseconds up */
- if ((USec - (MSec * 1000)) >= 500)
- {
- MSec++;
+ if ((USec - (MSec * 1000)) >= 500)
+ {
+ MSec++;
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
+ USec, MSec, Event->EventName);
+
+ if (Gbl_CompileTimesFlag)
+ {
+ printf ("%8u usec %8u msec - %s\n",
+ USec, MSec, Event->EventName);
+ }
+ }
+
+ Event++;
}
-
- DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
- USec, MSec, Event->EventName);
}
@@ -756,28 +802,20 @@
UINT32 i;
- AePrintErrorLog (ASL_FILE_STDOUT);
+ AePrintErrorLog (ASL_FILE_STDERR);
if (Gbl_DebugFlag)
{
- /* Print error summary to the debug file */
+ /* Print error summary to stdout also */
- AePrintErrorLog (ASL_FILE_STDERR);
+ AePrintErrorLog (ASL_FILE_STDOUT);
}
- DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
- for (i = 0; i < AslGbl_NextEvent; i++)
- {
- CmDumpEvent (&AslGbl_Events[i]);
- }
+ /* Emit compile times if enabled */
+
+ CmDumpAllEvents ();
if (Gbl_CompileTimesFlag)
{
- printf ("\nElapsed time for major events\n\n");
- for (i = 0; i < AslGbl_NextEvent; i++)
- {
- CmDumpEvent (&AslGbl_Events[i]);
- }
-
printf ("\nMiscellaneous compile statistics\n\n");
printf ("%11u : %s\n", TotalParseNodes, "Parse nodes");
printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches");
@@ -837,7 +875,9 @@
/* Delete the preprocessor output file (.i) unless -li flag is set */
- if (!Gbl_PreprocessorOutputFlag && Gbl_Files[ASL_FILE_PREPROCESSOR].Filename)
+ if (!Gbl_PreprocessorOutputFlag &&
+ Gbl_PreprocessFlag &&
+ Gbl_Files[ASL_FILE_PREPROCESSOR].Filename)
{
if (remove (Gbl_Files[ASL_FILE_PREPROCESSOR].Filename))
{
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/aslcompiler.h
--- a/head/sys/contrib/dev/acpica/compiler/aslcompiler.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/aslcompiler.h Wed Jul 25 16:45:04 2012 +0300
@@ -100,11 +100,11 @@
void);
void
-ResetCurrentLineBuffer (
+AslResetCurrentLineBuffer (
void);
void
-InsertLineBuffer (
+AslInsertLineBuffer (
int SourceChar);
int
@@ -136,6 +136,11 @@
AslDoOneFile (
char *Filename);
+ACPI_STATUS
+AslCheckForErrorExit (
+ void);
+
+
/*
* aslcompile - compile mainline
*/
@@ -161,7 +166,9 @@
ACPI_STATUS
FlCheckForAscii (
- ASL_FILE_INFO *FileInfo);
+ FILE *Handle,
+ char *Filename,
+ BOOLEAN DisplayErrors);
/*
@@ -603,6 +610,11 @@
FlAddIncludeDirectory (
char *Dir);
+char *
+FlMergePathnames (
+ char *PrefixDir,
+ char *FilePathname);
+
void
FlOpenIncludeFile (
ACPI_PARSE_OBJECT *Op);
@@ -645,7 +657,11 @@
void
FlSetLineNumber (
- ACPI_PARSE_OBJECT *Op);
+ UINT32 LineNumber);
+
+void
+FlSetFilename (
+ char *Filename);
ACPI_STATUS
FlOpenInputFile (
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/aslcompiler.l
--- a/head/sys/contrib/dev/acpica/compiler/aslcompiler.l Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/aslcompiler.l Wed Jul 25 16:45:04 2012 +0300
@@ -58,20 +58,26 @@
*/
#define _COMPONENT ACPI_COMPILER
- ACPI_MODULE_NAME ("aslscan")
+ ACPI_MODULE_NAME ("aslscanner")
+
/* Local prototypes */
-char
-comment (void);
-char
-comment2 (void);
-void
+static void
+AslDoLineDirective (void);
+
+static char
+AslDoComment (void);
+
+static char
+AslDoCommentType2 (void);
+
+static char
+AslDoStringLiteral (void);
+
+static void
count (int type);
-char
-literal (void);
-void
-copy (void);
+
/*! [Begin] no source code translation */
@@ -104,10 +110,10 @@
[ \t] { count (0); }
-"/*" { if (!comment ()) yyterminate (); }
-"//" { if (!comment2 ()) yyterminate (); }
+"/*" { if (!AslDoComment ()) yyterminate (); }
+"//" { if (!AslDoCommentType2 ()) yyterminate (); }
-"\"" { if (literal ()) return (PARSEOP_STRING_LITERAL); else yyterminate (); }
+"\"" { if (AslDoStringLiteral ()) return (PARSEOP_STRING_LITERAL); else yyterminate (); }
";" { count (0); return(';'); }
@@ -116,10 +122,16 @@
count (1); return (PARSEOP_INTEGER); }
"Include" { count (1); return (PARSEOP_INCLUDE); }
-"#include" { count (1); return (PARSEOP_INCLUDE_CSTYLE); }
-"#line" { count (1); return (PARSEOP_LINE_CSTYLE); }
"External" { count (1); return (PARSEOP_EXTERNAL); }
+ /*
+ * The #line directive is emitted by the preprocessor and handled
+ * here in the main iASL lexer - simply set the line number and
+ * optionally the current filename.
+ */
+"#line" { AslDoLineDirective ();}
+
+
/****************************************************************************
*
* Main ASL operators
@@ -511,6 +523,7 @@
"IPMI" { count (0); return (PARSEOP_REGIONSPACE_IPMI); }
"GeneralPurposeIo" { count (0); return (PARSEOP_REGIONSPACE_GPIO); } /* ACPI 5.0 */
"GenericSerialBus" { count (0); return (PARSEOP_REGIONSPACE_GSBUS); } /* ACPI 5.0 */
+"PCC" { count (0); return (PARSEOP_REGIONSPACE_PCC); } /* ACPI 5.0 */
"FFixedHW" { count (0); return (PARSEOP_REGIONSPACE_FFIXEDHW); }
/* ResourceTypeKeyword: Resource Usage - Resource Descriptors */
@@ -634,668 +647,7 @@
/*! [End] no source code translation !*/
-typedef struct asl_file_node
-{
- FILE *File;
- UINT32 CurrentLineNumber;
- YY_BUFFER_STATE State;
- char *Filename;
- struct asl_file_node *Next;
-
-} ASL_FILE_NODE;
-
-ASL_FILE_NODE *InputStack = NULL;
-
-
-/*******************************************************************************
- *
- * FUNCTION: AslPopInputFileStack
- *
- * PARAMETERS: None
- *
- * RETURN: 0 if a node was popped, -1 otherwise
- *
- * DESCRIPTION: Pop the top of the input file stack and point the parser to
- * the saved parse buffer contained in the fnode. Also, set the
- * global line counters to the saved values. This function is
- * called when an include file reaches EOF.
- *
- ******************************************************************************/
-
-int
-AslPopInputFileStack (
- void)
-{
- ASL_FILE_NODE *Fnode;
-
-
- Fnode = InputStack;
- DbgPrint (ASL_PARSE_OUTPUT, "\nPop InputFile Stack, Fnode %p\n\n", Fnode);
-
-
- if (!Fnode)
- {
- return -1;
- }
-
- /* Close the current include file */
-
- fclose (yyin);
-
- /* Update the top-of-stack */
-
- InputStack = Fnode->Next;
-
- /* Reset global line counter and filename */
-
- Gbl_Files[ASL_FILE_INPUT].Filename = Fnode->Filename;
- Gbl_CurrentLineNumber = Fnode->CurrentLineNumber;
-
- /* Point the parser to the popped file */
-
- yy_delete_buffer (YY_CURRENT_BUFFER);
- yy_switch_to_buffer (Fnode->State);
-
- /* All done with this node */
-
- ACPI_FREE (Fnode);
- return 0;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AslPushInputFileStack
- *
- * PARAMETERS: InputFile - Open file pointer
- * Filename - Name of the file
- *
- * RETURN: None
- *
- * DESCRIPTION: Push the InputFile onto the file stack, and point the parser
- * to this file. Called when an include file is successfully
- * opened.
- *
- ******************************************************************************/
-
-void
-AslPushInputFileStack (
- FILE *InputFile,
- char *Filename)
-{
- ASL_FILE_NODE *Fnode;
- YY_BUFFER_STATE State;
-
-
- /* Save the current state in an Fnode */
-
- Fnode = UtLocalCalloc (sizeof (ASL_FILE_NODE));
-
- Fnode->File = yyin;
- Fnode->Next = InputStack;
- Fnode->State = YY_CURRENT_BUFFER;
- Fnode->CurrentLineNumber = Gbl_CurrentLineNumber;
- Fnode->Filename = Gbl_Files[ASL_FILE_INPUT].Filename;
-
- /* Push it on the stack */
-
- InputStack = Fnode;
-
- /* Point the parser to this file */
-
- State = yy_create_buffer (InputFile, YY_BUF_SIZE);
- yy_switch_to_buffer (State);
-
- DbgPrint (ASL_PARSE_OUTPUT, "\nPush InputFile Stack, returning %p\n\n", InputFile);
-
- /* Reset the global line count and filename */
-
- Gbl_Files[ASL_FILE_INPUT].Filename = Filename;
- Gbl_CurrentLineNumber = 1;
- yyin = InputFile;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: ResetCurrentLineBuffer
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Reset the Line Buffer to zero, increment global line numbers.
- *
- ******************************************************************************/
-
-void
-ResetCurrentLineBuffer (
- void)
-{
-
- if (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle)
- {
- FlWriteFile (ASL_FILE_SOURCE_OUTPUT, Gbl_CurrentLineBuffer,
- Gbl_LineBufPtr - Gbl_CurrentLineBuffer);
- }
-
- Gbl_CurrentLineOffset += Gbl_CurrentColumn;
- Gbl_CurrentColumn = 0;
-
- Gbl_CurrentLineNumber++;
- Gbl_LogicalLineNumber++;
- Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: InsertLineBuffer
- *
- * PARAMETERS: SourceChar - One char from the input ASL source file
- *
- * RETURN: None
- *
- * DESCRIPTION: Put one character of the source file into the temp line buffer
- *
- ******************************************************************************/
-
-#define ASL_SPACES_PER_TAB 4
-
-void
-InsertLineBuffer (
- int SourceChar)
-{
- UINT32 i;
- UINT32 Count = 1;
-
-
- if (SourceChar == EOF)
- {
- return;
- }
-
- Gbl_InputByteCount++;
-
- /* Handle tabs. Convert to spaces */
-
- if (SourceChar == '\t')
- {
- SourceChar = ' ';
- Count = ASL_SPACES_PER_TAB -
- (Gbl_CurrentColumn & (ASL_SPACES_PER_TAB-1));
- }
-
-
- for (i = 0; i < Count; i++)
- {
- Gbl_CurrentColumn++;
-
- /* Insert the character into the line buffer */
-
- *Gbl_LineBufPtr = (UINT8) SourceChar;
- Gbl_LineBufPtr++;
-
- if (Gbl_LineBufPtr > (Gbl_CurrentLineBuffer + (ASL_LINE_BUFFER_SIZE - 1)))
- {
-#if 0
- /*
- * Warning if we have split a long source line.
- * <Probably overkill>
- */
- sprintf (MsgBuffer, "Max %u", ASL_LINE_BUFFER_SIZE);
- AslCommonError (ASL_WARNING, ASL_MSG_LONG_LINE,
- Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
- Gbl_CurrentLineOffset, Gbl_CurrentColumn,
- Gbl_Files[ASL_FILE_INPUT].Filename, MsgBuffer);
-#endif
-
- ResetCurrentLineBuffer ();
- }
- else if (SourceChar == '\n')
- {
- /* End of line */
-
- ResetCurrentLineBuffer ();
- }
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: count
- *
- * PARAMETERS: yytext - Contains the matched keyword.
- * Type - Keyword/Character type:
- * 0 = anything except a keyword
- * 1 = pseudo-keywords
- * 2 = non-executable ASL keywords
- * 3 = executable ASL keywords
- *
- * RETURN: None
- *
- * DESCRIPTION: Count keywords and put them into the line buffer
- *
- ******************************************************************************/
-
-void
-count (
- int Type)
-{
- int i;
-
-
- switch (Type)
- {
- case 2:
- TotalKeywords++;
- TotalNamedObjects++;
- break;
-
- case 3:
- TotalKeywords++;
- TotalExecutableOpcodes++;
- break;
- }
-
- for (i = 0; (yytext[i] != 0) && (yytext[i] != EOF); i++)
- {
- InsertLineBuffer (yytext[i]);
- *Gbl_LineBufPtr = 0;
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: comment
- *
- * PARAMETERS: none
- *
- * RETURN: none
- *
- * DESCRIPTION: Process a standard comment.
- *
- ******************************************************************************/
-
-char
-comment (void)
-{
- char c;
- char c1 = 0;
-
-
- InsertLineBuffer ('/');
- InsertLineBuffer ('*');
-
-loop:
-
- /* Eat chars until end-of-comment */
-
- while ((c = (char) input()) != '*' && c != EOF)
- {
- InsertLineBuffer (c);
- c1 = c;
- }
-
- if (c == EOF)
- {
- goto EarlyEOF;
- }
-
- /*
- * Check for nested comment -- can help catch cases where a previous
- * comment was accidently left unterminated
- */
- if ((c1 == '/') && (c == '*'))
- {
- AslCommonError (ASL_WARNING, ASL_MSG_NESTED_COMMENT,
- Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
- Gbl_InputByteCount, Gbl_CurrentColumn,
- Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
- }
-
- /* Comment is closed only if the NEXT character is a slash */
-
- InsertLineBuffer (c);
-
- if ((c1 = (char) input()) != '/' && c1 != EOF)
- {
- unput(c1);
- goto loop;
- }
-
- if (c1 == EOF)
- {
- goto EarlyEOF;
- }
-
- InsertLineBuffer (c1);
- return TRUE;
-
-
-EarlyEOF:
- /*
- * Premature End-Of-File
- */
- AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
- Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
- Gbl_CurrentLineOffset, Gbl_CurrentColumn,
- Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
- return (FALSE);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: comment
- *
- * PARAMETERS: none
- *
- * RETURN: none
- *
- * DESCRIPTION: Process a new "//" comment.
- *
- ******************************************************************************/
-
-char
-comment2 (void)
-{
- char c;
-
-
- InsertLineBuffer ('/');
- InsertLineBuffer ('/');
-
- while ((c = (char) input()) != '\n' && c != EOF)
- {
- InsertLineBuffer (c);
- }
-
- if (c == EOF)
- {
- /* End of file is OK, change to newline. Let parser detect EOF later */
-
- c = '\n';
- }
-
- InsertLineBuffer (c);
- return (TRUE);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: literal
- *
- * PARAMETERS: none
- *
- * RETURN: none
- *
- * DESCRIPTION: Process a string literal (surrounded by quotes)
- *
- ******************************************************************************/
-
-#define ASL_NORMAL_CHAR 0
-#define ASL_ESCAPE_SEQUENCE 1
-#define ASL_OCTAL_CONSTANT 2
-#define ASL_HEX_CONSTANT 3
-
-char
-literal (void)
-{
- char *StringBuffer = MsgBuffer;
- char *EndBuffer = MsgBuffer + ASL_MSG_BUFFER_SIZE;
- char *CleanString;
- char StringChar;
- UINT32 State = ASL_NORMAL_CHAR;
- UINT32 i = 0;
- UINT8 Digit;
- char ConvertBuffer[4];
-
-
- /*
- * Eat chars until end-of-literal.
- * NOTE: Put back the original surrounding quotes into the
- * source line buffer.
- */
- InsertLineBuffer ('\"');
- while ((StringChar = (char) input()) != EOF)
- {
- InsertLineBuffer (StringChar);
-
-DoCharacter:
-
- switch (State)
- {
- case ASL_NORMAL_CHAR:
-
- switch (StringChar)
- {
- case '\\':
- /*
- * Special handling for backslash-escape sequence. We will
- * toss the backslash and translate the escape char(s).
- */
- State = ASL_ESCAPE_SEQUENCE;
- continue;
-
- case '\"':
-
- /* String terminator */
-
- goto CompletedString;
- }
- break;
-
-
- case ASL_ESCAPE_SEQUENCE:
-
- State = ASL_NORMAL_CHAR;
- switch (StringChar)
- {
- case 'a':
- StringChar = 0x07; /* BELL */
- break;
-
- case 'b':
- StringChar = 0x08; /* BACKSPACE */
- break;
-
- case 'f':
- StringChar = 0x0C; /* FORMFEED */
- break;
-
- case 'n':
- StringChar = 0x0A; /* LINEFEED */
- break;
-
- case 'r':
- StringChar = 0x0D; /* CARRIAGE RETURN*/
- break;
-
- case 't':
- StringChar = 0x09; /* HORIZONTAL TAB */
- break;
-
- case 'v':
- StringChar = 0x0B; /* VERTICAL TAB */
- break;
-
- case 'x':
- State = ASL_HEX_CONSTANT;
- i = 0;
- continue;
-
- case '\'': /* Single Quote */
- case '\"': /* Double Quote */
- case '\\': /* Backslash */
- break;
-
- default:
-
- /* Check for an octal digit (0-7) */
-
- if (ACPI_IS_OCTAL_DIGIT (StringChar))
- {
- State = ASL_OCTAL_CONSTANT;
- ConvertBuffer[0] = StringChar;
- i = 1;
- continue;
- }
-
- /* Unknown escape sequence issue warning, but use the character */
-
- AslCommonError (ASL_WARNING, ASL_MSG_INVALID_ESCAPE,
- Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
- Gbl_CurrentLineOffset, Gbl_CurrentColumn,
- Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
- break;
- }
- break;
-
-
- case ASL_OCTAL_CONSTANT:
-
- /* Up to three octal digits allowed */
-
- if (!ACPI_IS_OCTAL_DIGIT (StringChar) ||
- (i > 2))
- {
- /*
- * Reached end of the constant. Convert the assembled ASCII
- * string and resume processing of the next character
- */
- ConvertBuffer[i] = 0;
- Digit = (UINT8) ACPI_STRTOUL (ConvertBuffer, NULL, 8);
-
- /* Check for NULL or non-ascii character (ignore if so) */
-
- if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
- {
- AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
- Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
- Gbl_CurrentLineOffset, Gbl_CurrentColumn,
- Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
- }
- else
- {
- *StringBuffer = (char) Digit;
- StringBuffer++;
- if (StringBuffer >= EndBuffer)
- {
- goto BufferOverflow;
- }
- }
-
- State = ASL_NORMAL_CHAR;
- goto DoCharacter;
- break;
- }
-
- /* Append another digit of the constant */
-
- ConvertBuffer[i] = StringChar;
- i++;
- continue;
-
-
- case ASL_HEX_CONSTANT:
-
- /* Up to two hex digits allowed */
-
- if (!ACPI_IS_XDIGIT (StringChar) ||
- (i > 1))
- {
- /*
- * Reached end of the constant. Convert the assembled ASCII
- * string and resume processing of the next character
- */
- ConvertBuffer[i] = 0;
- Digit = (UINT8) ACPI_STRTOUL (ConvertBuffer, NULL, 16);
-
- /* Check for NULL or non-ascii character (ignore if so) */
-
- if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
- {
- AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
- Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
- Gbl_CurrentLineOffset, Gbl_CurrentColumn,
- Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
- }
- else
- {
- *StringBuffer = (char) Digit;
- StringBuffer++;
- if (StringBuffer >= EndBuffer)
- {
- goto BufferOverflow;
- }
- }
-
- State = ASL_NORMAL_CHAR;
- goto DoCharacter;
- break;
- }
-
- /* Append another digit of the constant */
-
- ConvertBuffer[i] = StringChar;
- i++;
- continue;
- }
-
- /* Save the finished character */
-
- *StringBuffer = StringChar;
- StringBuffer++;
- if (StringBuffer >= EndBuffer)
- {
- goto BufferOverflow;
- }
- }
-
- /*
- * Premature End-Of-File
- */
- AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
- Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
- Gbl_CurrentLineOffset, Gbl_CurrentColumn,
- Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
- return (FALSE);
-
-
-CompletedString:
- /*
- * Null terminate the input string and copy string to a new buffer
- */
- *StringBuffer = 0;
-
- CleanString = UtGetStringBuffer (strlen (MsgBuffer) + 1);
- if (!CleanString)
- {
- AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION,
- Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
- Gbl_CurrentLineOffset, Gbl_CurrentColumn,
- Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
- return (FALSE);
- }
-
- ACPI_STRCPY (CleanString, MsgBuffer);
- AslCompilerlval.s = CleanString;
- return (TRUE);
-
-
-BufferOverflow:
-
- /* Literal was too long */
-
- AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH,
- Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
- Gbl_CurrentLineOffset, Gbl_CurrentColumn,
- Gbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096");
- return (FALSE);
-}
-
-
+/*
+ * Bring in the scanner support routines
+ */
+#include <contrib/dev/acpica/compiler/aslsupport.l>
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/aslcompiler.y
--- a/head/sys/contrib/dev/acpica/compiler/aslcompiler.y Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/aslcompiler.y Wed Jul 25 16:45:04 2012 +0300
@@ -236,7 +236,6 @@
%token <i> PARSEOP_I2C_SERIALBUS
%token <i> PARSEOP_IF
%token <i> PARSEOP_INCLUDE
-%token <i> PARSEOP_INCLUDE_CSTYLE
%token <i> PARSEOP_INCLUDE_END
%token <i> PARSEOP_INCREMENT
%token <i> PARSEOP_INDEX
@@ -261,7 +260,6 @@
%token <i> PARSEOP_LEQUAL
%token <i> PARSEOP_LGREATER
%token <i> PARSEOP_LGREATEREQUAL
-%token <i> PARSEOP_LINE_CSTYLE
%token <i> PARSEOP_LLESS
%token <i> PARSEOP_LLESSEQUAL
%token <i> PARSEOP_LNOT
@@ -365,6 +363,7 @@
%token <i> PARSEOP_REGIONSPACE_IO
%token <i> PARSEOP_REGIONSPACE_IPMI
%token <i> PARSEOP_REGIONSPACE_MEM
+%token <i> PARSEOP_REGIONSPACE_PCC
%token <i> PARSEOP_REGIONSPACE_PCI
%token <i> PARSEOP_REGIONSPACE_PCIBAR
%token <i> PARSEOP_REGIONSPACE_SMBUS
@@ -504,9 +503,7 @@
%type <n> FieldUnit
%type <n> FieldUnitEntry
%type <n> FieldUnitList
-%type <n> IncludeCStyleTerm
%type <n> IncludeTerm
-%type <n> LineTerm
%type <n> OffsetTerm
%type <n> OptionalAccessAttribTerm
@@ -805,15 +802,19 @@
/*
- * Blocks, Data, and Opcodes
+ * Root rule. Allow multiple #line directives before the definition block
+ * to handle output from preprocessors
*/
-
ASLCode
: DefinitionBlockTerm
| error {YYABORT; $$ = NULL;}
;
/*
+ * Blocks, Data, and Opcodes
+ */
+
+/*
* Note concerning support for "module-level code".
*
* ACPI 1.0 allowed Type1 and Type2 executable opcodes outside of control
@@ -829,7 +830,7 @@
* of Type1 and Type2 opcodes at module level.
*/
DefinitionBlockTerm
- : PARSEOP_DEFINITIONBLOCK '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DEFINITIONBLOCK);}
+ : PARSEOP_DEFINITIONBLOCK '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DEFINITIONBLOCK);}
String ','
String ','
ByteConst ','
@@ -863,8 +864,6 @@
CompilerDirective
: IncludeTerm {}
- | IncludeCStyleTerm {$$ = NULL;}
- | LineTerm {$$ = NULL;}
| ExternalTerm {}
;
@@ -1148,25 +1147,15 @@
;
IncludeTerm
- : PARSEOP_INCLUDE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_INCLUDE);}
+ : PARSEOP_INCLUDE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_INCLUDE);}
String ')' {TrLinkChildren ($<n>3,1,$4);FlOpenIncludeFile ($4);}
TermList
IncludeEndTerm {$$ = TrLinkPeerNodes (3,$<n>3,$7,$8);}
;
IncludeEndTerm
- : PARSEOP_INCLUDE_END {$$ = TrCreateLeafNode (PARSEOP_INCLUDE_END);}
- ;
-
-IncludeCStyleTerm
- : PARSEOP_INCLUDE_CSTYLE
- String {FlOpenIncludeFile ($2);}
- ;
-
-LineTerm
- : PARSEOP_LINE_CSTYLE
- Integer {FlSetLineNumber ($2);}
- ;
+ : PARSEOP_INCLUDE_END {$$ = TrCreateLeafNode (PARSEOP_INCLUDE_END);}
+ ;
ExternalTerm
: PARSEOP_EXTERNAL '('
@@ -1184,7 +1173,7 @@
BankFieldTerm
- : PARSEOP_BANKFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_BANKFIELD);}
+ : PARSEOP_BANKFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_BANKFIELD);}
NameString
NameStringItem
TermArgItem
@@ -1251,7 +1240,7 @@
;
CreateBitFieldTerm
- : PARSEOP_CREATEBITFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CREATEBITFIELD);}
+ : PARSEOP_CREATEBITFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CREATEBITFIELD);}
TermArg
TermArgItem
NameStringItem
@@ -1261,7 +1250,7 @@
;
CreateByteFieldTerm
- : PARSEOP_CREATEBYTEFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CREATEBYTEFIELD);}
+ : PARSEOP_CREATEBYTEFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CREATEBYTEFIELD);}
TermArg
TermArgItem
NameStringItem
@@ -1271,7 +1260,7 @@
;
CreateDWordFieldTerm
- : PARSEOP_CREATEDWORDFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CREATEDWORDFIELD);}
+ : PARSEOP_CREATEDWORDFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CREATEDWORDFIELD);}
TermArg
TermArgItem
NameStringItem
@@ -1281,7 +1270,7 @@
;
CreateFieldTerm
- : PARSEOP_CREATEFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CREATEFIELD);}
+ : PARSEOP_CREATEFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CREATEFIELD);}
TermArg
TermArgItem
TermArgItem
@@ -1292,7 +1281,7 @@
;
CreateQWordFieldTerm
- : PARSEOP_CREATEQWORDFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CREATEQWORDFIELD);}
+ : PARSEOP_CREATEQWORDFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CREATEQWORDFIELD);}
TermArg
TermArgItem
NameStringItem
@@ -1302,7 +1291,7 @@
;
CreateWordFieldTerm
- : PARSEOP_CREATEWORDFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CREATEWORDFIELD);}
+ : PARSEOP_CREATEWORDFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CREATEWORDFIELD);}
TermArg
TermArgItem
NameStringItem
@@ -1312,7 +1301,7 @@
;
DataRegionTerm
- : PARSEOP_DATATABLEREGION '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DATATABLEREGION);}
+ : PARSEOP_DATATABLEREGION '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DATATABLEREGION);}
NameString
TermArgItem
TermArgItem
@@ -1323,7 +1312,7 @@
;
DeviceTerm
- : PARSEOP_DEVICE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DEVICE);}
+ : PARSEOP_DEVICE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DEVICE);}
NameString
')' '{'
ObjectList '}' {$$ = TrLinkChildren ($<n>3,2,TrSetNodeFlags ($4, NODE_IS_NAME_DECLARATION),$7);}
@@ -1332,7 +1321,7 @@
;
EventTerm
- : PARSEOP_EVENT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_EVENT);}
+ : PARSEOP_EVENT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_EVENT);}
NameString
')' {$$ = TrLinkChildren ($<n>3,1,TrSetNodeFlags ($4, NODE_IS_NAME_DECLARATION));}
| PARSEOP_EVENT '('
@@ -1340,7 +1329,7 @@
;
FieldTerm
- : PARSEOP_FIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_FIELD);}
+ : PARSEOP_FIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_FIELD);}
NameString
',' AccessTypeKeyword
',' LockRuleKeyword
@@ -1352,7 +1341,7 @@
;
FunctionTerm
- : PARSEOP_FUNCTION '(' {$<n>$ = TrCreateLeafNode (PARSEOP_METHOD);}
+ : PARSEOP_FUNCTION '(' {$<n>$ = TrCreateLeafNode (PARSEOP_METHOD);}
NameString
OptionalParameterTypePackage
OptionalParameterTypesPackage
@@ -1366,7 +1355,7 @@
;
IndexFieldTerm
- : PARSEOP_INDEXFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_INDEXFIELD);}
+ : PARSEOP_INDEXFIELD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_INDEXFIELD);}
NameString
NameStringItem
',' AccessTypeKeyword
@@ -1379,7 +1368,7 @@
;
MethodTerm
- : PARSEOP_METHOD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_METHOD);}
+ : PARSEOP_METHOD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_METHOD);}
NameString
OptionalByteConstExpr {UtCheckIntegerRange ($5, 0, 7);}
OptionalSerializeRuleKeyword
@@ -1393,7 +1382,7 @@
;
MutexTerm
- : PARSEOP_MUTEX '(' {$<n>$ = TrCreateLeafNode (PARSEOP_MUTEX);}
+ : PARSEOP_MUTEX '(' {$<n>$ = TrCreateLeafNode (PARSEOP_MUTEX);}
NameString
',' ByteConstExpr
')' {$$ = TrLinkChildren ($<n>3,2,TrSetNodeFlags ($4, NODE_IS_NAME_DECLARATION),$6);}
@@ -1402,7 +1391,7 @@
;
OpRegionTerm
- : PARSEOP_OPERATIONREGION '(' {$<n>$ = TrCreateLeafNode (PARSEOP_OPERATIONREGION);}
+ : PARSEOP_OPERATIONREGION '(' {$<n>$ = TrCreateLeafNode (PARSEOP_OPERATIONREGION);}
NameString
',' OpRegionSpaceIdTerm
TermArgItem
@@ -1418,7 +1407,7 @@
;
PowerResTerm
- : PARSEOP_POWERRESOURCE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_POWERRESOURCE);}
+ : PARSEOP_POWERRESOURCE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_POWERRESOURCE);}
NameString
',' ByteConstExpr
',' WordConstExpr
@@ -1429,7 +1418,7 @@
;
ProcessorTerm
- : PARSEOP_PROCESSOR '(' {$<n>$ = TrCreateLeafNode (PARSEOP_PROCESSOR);}
+ : PARSEOP_PROCESSOR '(' {$<n>$ = TrCreateLeafNode (PARSEOP_PROCESSOR);}
NameString
',' ByteConstExpr
OptionalDWordConstExpr
@@ -1441,7 +1430,7 @@
;
ThermalZoneTerm
- : PARSEOP_THERMALZONE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_THERMALZONE);}
+ : PARSEOP_THERMALZONE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_THERMALZONE);}
NameString
')' '{'
ObjectList '}' {$$ = TrLinkChildren ($<n>3,2,TrSetNodeFlags ($4, NODE_IS_NAME_DECLARATION),$7);}
@@ -1454,7 +1443,7 @@
AliasTerm
- : PARSEOP_ALIAS '(' {$<n>$ = TrCreateLeafNode (PARSEOP_ALIAS);}
+ : PARSEOP_ALIAS '(' {$<n>$ = TrCreateLeafNode (PARSEOP_ALIAS);}
NameString
NameStringItem
')' {$$ = TrLinkChildren ($<n>3,2,$4,TrSetNodeFlags ($5, NODE_IS_NAME_DECLARATION));}
@@ -1463,7 +1452,7 @@
;
NameTerm
- : PARSEOP_NAME '(' {$<n>$ = TrCreateLeafNode (PARSEOP_NAME);}
+ : PARSEOP_NAME '(' {$<n>$ = TrCreateLeafNode (PARSEOP_NAME);}
NameString
',' DataObject
')' {$$ = TrLinkChildren ($<n>3,2,TrSetNodeFlags ($4, NODE_IS_NAME_DECLARATION),$6);}
@@ -1472,7 +1461,7 @@
;
ScopeTerm
- : PARSEOP_SCOPE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SCOPE);}
+ : PARSEOP_SCOPE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SCOPE);}
NameString
')' '{'
ObjectList '}' {$$ = TrLinkChildren ($<n>3,2,TrSetNodeFlags ($4, NODE_IS_NAME_DECLARATION),$7);}
@@ -1485,19 +1474,19 @@
BreakTerm
- : PARSEOP_BREAK {$$ = TrCreateNode (PARSEOP_BREAK, 0);}
+ : PARSEOP_BREAK {$$ = TrCreateNode (PARSEOP_BREAK, 0);}
;
BreakPointTerm
- : PARSEOP_BREAKPOINT {$$ = TrCreateNode (PARSEOP_BREAKPOINT, 0);}
+ : PARSEOP_BREAKPOINT {$$ = TrCreateNode (PARSEOP_BREAKPOINT, 0);}
;
ContinueTerm
- : PARSEOP_CONTINUE {$$ = TrCreateNode (PARSEOP_CONTINUE, 0);}
+ : PARSEOP_CONTINUE {$$ = TrCreateNode (PARSEOP_CONTINUE, 0);}
;
FatalTerm
- : PARSEOP_FATAL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_FATAL);}
+ : PARSEOP_FATAL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_FATAL);}
ByteConstExpr
',' DWordConstExpr
TermArgItem
@@ -1511,7 +1500,7 @@
;
IfTerm
- : PARSEOP_IF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_IF);}
+ : PARSEOP_IF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_IF);}
TermArg
')' '{'
TermList '}' {$$ = TrLinkChildren ($<n>3,2,$4,$7);}
@@ -1522,7 +1511,7 @@
ElseTerm
: {$$ = NULL;}
- | PARSEOP_ELSE '{' {$<n>$ = TrCreateLeafNode (PARSEOP_ELSE);}
+ | PARSEOP_ELSE '{' {$<n>$ = TrCreateLeafNode (PARSEOP_ELSE);}
TermList '}' {$$ = TrLinkChildren ($<n>3,1,$4);}
| PARSEOP_ELSE '{'
@@ -1531,10 +1520,10 @@
| PARSEOP_ELSE
error {$$ = AslDoError(); yyclearin;}
- | PARSEOP_ELSEIF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_ELSE);}
- TermArg {$<n>$ = TrCreateLeafNode (PARSEOP_IF);}
+ | PARSEOP_ELSEIF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_ELSE);}
+ TermArg {$<n>$ = TrCreateLeafNode (PARSEOP_IF);}
')' '{'
- TermList '}' {TrLinkChildren ($<n>5,2,$4,$8);}
+ TermList '}' {TrLinkChildren ($<n>5,2,$4,$8);}
ElseTerm {TrLinkPeerNode ($<n>5,$11);}
{$$ = TrLinkChildren ($<n>3,1,$<n>5);}
@@ -1546,7 +1535,7 @@
;
LoadTerm
- : PARSEOP_LOAD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LOAD);}
+ : PARSEOP_LOAD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LOAD);}
NameString
RequiredTarget
')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
@@ -1555,11 +1544,11 @@
;
NoOpTerm
- : PARSEOP_NOOP {$$ = TrCreateNode (PARSEOP_NOOP, 0);}
+ : PARSEOP_NOOP {$$ = TrCreateNode (PARSEOP_NOOP, 0);}
;
NotifyTerm
- : PARSEOP_NOTIFY '(' {$<n>$ = TrCreateLeafNode (PARSEOP_NOTIFY);}
+ : PARSEOP_NOTIFY '(' {$<n>$ = TrCreateLeafNode (PARSEOP_NOTIFY);}
SuperName
TermArgItem
')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
@@ -1568,7 +1557,7 @@
;
ReleaseTerm
- : PARSEOP_RELEASE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_RELEASE);}
+ : PARSEOP_RELEASE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_RELEASE);}
SuperName
')' {$$ = TrLinkChildren ($<n>3,1,$4);}
| PARSEOP_RELEASE '('
@@ -1576,7 +1565,7 @@
;
ResetTerm
- : PARSEOP_RESET '(' {$<n>$ = TrCreateLeafNode (PARSEOP_RESET);}
+ : PARSEOP_RESET '(' {$<n>$ = TrCreateLeafNode (PARSEOP_RESET);}
SuperName
')' {$$ = TrLinkChildren ($<n>3,1,$4);}
| PARSEOP_RESET '('
@@ -1584,16 +1573,16 @@
;
ReturnTerm
- : PARSEOP_RETURN '(' {$<n>$ = TrCreateLeafNode (PARSEOP_RETURN);}
+ : PARSEOP_RETURN '(' {$<n>$ = TrCreateLeafNode (PARSEOP_RETURN);}
OptionalReturnArg
')' {$$ = TrLinkChildren ($<n>3,1,$4);}
- | PARSEOP_RETURN {$$ = TrLinkChildren (TrCreateLeafNode (PARSEOP_RETURN),1,TrSetNodeFlags (TrCreateLeafNode (PARSEOP_ZERO), NODE_IS_NULL_RETURN));}
+ | PARSEOP_RETURN {$$ = TrLinkChildren (TrCreateLeafNode (PARSEOP_RETURN),1,TrSetNodeFlags (TrCreateLeafNode (PARSEOP_ZERO), NODE_IS_NULL_RETURN));}
| PARSEOP_RETURN '('
error ')' {$$ = AslDoError(); yyclearin;}
;
SignalTerm
- : PARSEOP_SIGNAL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SIGNAL);}
+ : PARSEOP_SIGNAL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SIGNAL);}
SuperName
')' {$$ = TrLinkChildren ($<n>3,1,$4);}
| PARSEOP_SIGNAL '('
@@ -1601,7 +1590,7 @@
;
SleepTerm
- : PARSEOP_SLEEP '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SLEEP);}
+ : PARSEOP_SLEEP '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SLEEP);}
TermArg
')' {$$ = TrLinkChildren ($<n>3,1,$4);}
| PARSEOP_SLEEP '('
@@ -1609,7 +1598,7 @@
;
StallTerm
- : PARSEOP_STALL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_STALL);}
+ : PARSEOP_STALL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_STALL);}
TermArg
')' {$$ = TrLinkChildren ($<n>3,1,$4);}
| PARSEOP_STALL '('
@@ -1617,7 +1606,7 @@
;
SwitchTerm
- : PARSEOP_SWITCH '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SWITCH);}
+ : PARSEOP_SWITCH '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SWITCH);}
TermArg
')' '{'
CaseDefaultTermList '}'
@@ -1660,7 +1649,7 @@
*/
CaseTerm
- : PARSEOP_CASE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CASE);}
+ : PARSEOP_CASE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CASE);}
DataObject
')' '{'
TermList '}' {$$ = TrLinkChildren ($<n>3,2,$4,$7);}
@@ -1669,14 +1658,14 @@
;
DefaultTerm
- : PARSEOP_DEFAULT '{' {$<n>$ = TrCreateLeafNode (PARSEOP_DEFAULT);}
+ : PARSEOP_DEFAULT '{' {$<n>$ = TrCreateLeafNode (PARSEOP_DEFAULT);}
TermList '}' {$$ = TrLinkChildren ($<n>3,1,$4);}
| PARSEOP_DEFAULT '{'
error '}' {$$ = AslDoError(); yyclearin;}
;
UnloadTerm
- : PARSEOP_UNLOAD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_UNLOAD);}
+ : PARSEOP_UNLOAD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_UNLOAD);}
SuperName
')' {$$ = TrLinkChildren ($<n>3,1,$4);}
| PARSEOP_UNLOAD '('
@@ -1684,7 +1673,7 @@
;
WhileTerm
- : PARSEOP_WHILE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_WHILE);}
+ : PARSEOP_WHILE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_WHILE);}
TermArg
')' '{' TermList '}'
{$$ = TrLinkChildren ($<n>3,2,$4,$7);}
@@ -1696,7 +1685,7 @@
/******* Type 2 opcodes *******************************************************/
AcquireTerm
- : PARSEOP_ACQUIRE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_ACQUIRE);}
+ : PARSEOP_ACQUIRE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_ACQUIRE);}
SuperName
',' WordConstExpr
')' {$$ = TrLinkChildren ($<n>3,2,$4,$6);}
@@ -1705,7 +1694,7 @@
;
AddTerm
- : PARSEOP_ADD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_ADD);}
+ : PARSEOP_ADD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_ADD);}
TermArg
TermArgItem
Target
@@ -1715,7 +1704,7 @@
;
AndTerm
- : PARSEOP_AND '(' {$<n>$ = TrCreateLeafNode (PARSEOP_AND);}
+ : PARSEOP_AND '(' {$<n>$ = TrCreateLeafNode (PARSEOP_AND);}
TermArg
TermArgItem
Target
@@ -1725,7 +1714,7 @@
;
ConcatTerm
- : PARSEOP_CONCATENATE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CONCATENATE);}
+ : PARSEOP_CONCATENATE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CONCATENATE);}
TermArg
TermArgItem
Target
@@ -1745,7 +1734,7 @@
;
CondRefOfTerm
- : PARSEOP_CONDREFOF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CONDREFOF);}
+ : PARSEOP_CONDREFOF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_CONDREFOF);}
SuperName
Target
')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
@@ -1754,7 +1743,7 @@
;
CopyObjectTerm
- : PARSEOP_COPYOBJECT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_COPYOBJECT);}
+ : PARSEOP_COPYOBJECT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_COPYOBJECT);}
TermArg
',' SimpleTarget
')' {$$ = TrLinkChildren ($<n>3,2,$4,TrSetNodeFlags ($6, NODE_IS_TARGET));}
@@ -1763,7 +1752,7 @@
;
DecTerm
- : PARSEOP_DECREMENT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DECREMENT);}
+ : PARSEOP_DECREMENT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DECREMENT);}
SuperName
')' {$$ = TrLinkChildren ($<n>3,1,$4);}
| PARSEOP_DECREMENT '('
@@ -1771,7 +1760,7 @@
;
DerefOfTerm
- : PARSEOP_DEREFOF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DEREFOF);}
+ : PARSEOP_DEREFOF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DEREFOF);}
TermArg
')' {$$ = TrLinkChildren ($<n>3,1,$4);}
| PARSEOP_DEREFOF '('
@@ -1779,7 +1768,7 @@
;
DivideTerm
- : PARSEOP_DIVIDE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DIVIDE);}
+ : PARSEOP_DIVIDE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_DIVIDE);}
TermArg
TermArgItem
Target
@@ -1790,7 +1779,7 @@
;
FindSetLeftBitTerm
- : PARSEOP_FINDSETLEFTBIT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_FINDSETLEFTBIT);}
+ : PARSEOP_FINDSETLEFTBIT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_FINDSETLEFTBIT);}
TermArg
Target
')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
@@ -1799,7 +1788,7 @@
;
FindSetRightBitTerm
- : PARSEOP_FINDSETRIGHTBIT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_FINDSETRIGHTBIT);}
+ : PARSEOP_FINDSETRIGHTBIT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_FINDSETRIGHTBIT);}
TermArg
Target
')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
@@ -1808,7 +1797,7 @@
;
FromBCDTerm
- : PARSEOP_FROMBCD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_FROMBCD);}
+ : PARSEOP_FROMBCD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_FROMBCD);}
TermArg
Target
')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
@@ -1817,7 +1806,7 @@
;
IncTerm
- : PARSEOP_INCREMENT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_INCREMENT);}
+ : PARSEOP_INCREMENT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_INCREMENT);}
SuperName
')' {$$ = TrLinkChildren ($<n>3,1,$4);}
| PARSEOP_INCREMENT '('
@@ -1825,7 +1814,7 @@
;
IndexTerm
- : PARSEOP_INDEX '(' {$<n>$ = TrCreateLeafNode (PARSEOP_INDEX);}
+ : PARSEOP_INDEX '(' {$<n>$ = TrCreateLeafNode (PARSEOP_INDEX);}
TermArg
TermArgItem
Target
@@ -1835,7 +1824,7 @@
;
LAndTerm
- : PARSEOP_LAND '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LAND);}
+ : PARSEOP_LAND '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LAND);}
TermArg
TermArgItem
')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
@@ -1844,7 +1833,7 @@
;
LEqualTerm
- : PARSEOP_LEQUAL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LEQUAL);}
+ : PARSEOP_LEQUAL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LEQUAL);}
TermArg
TermArgItem
')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
@@ -1853,7 +1842,7 @@
;
LGreaterTerm
- : PARSEOP_LGREATER '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LGREATER);}
+ : PARSEOP_LGREATER '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LGREATER);}
TermArg
TermArgItem
')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
@@ -1862,7 +1851,7 @@
;
LGreaterEqualTerm
- : PARSEOP_LGREATEREQUAL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LLESS);}
+ : PARSEOP_LGREATEREQUAL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LLESS);}
TermArg
TermArgItem
')' {$$ = TrCreateNode (PARSEOP_LNOT, 1, TrLinkChildren ($<n>3,2,$4,$5));}
@@ -1871,7 +1860,7 @@
;
LLessTerm
- : PARSEOP_LLESS '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LLESS);}
+ : PARSEOP_LLESS '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LLESS);}
TermArg
TermArgItem
')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
@@ -1880,7 +1869,7 @@
;
LLessEqualTerm
- : PARSEOP_LLESSEQUAL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LGREATER);}
+ : PARSEOP_LLESSEQUAL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LGREATER);}
TermArg
TermArgItem
')' {$$ = TrCreateNode (PARSEOP_LNOT, 1, TrLinkChildren ($<n>3,2,$4,$5));}
@@ -1889,7 +1878,7 @@
;
LNotTerm
- : PARSEOP_LNOT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LNOT);}
+ : PARSEOP_LNOT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LNOT);}
TermArg
')' {$$ = TrLinkChildren ($<n>3,1,$4);}
| PARSEOP_LNOT '('
@@ -1897,7 +1886,7 @@
;
LNotEqualTerm
- : PARSEOP_LNOTEQUAL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LEQUAL);}
+ : PARSEOP_LNOTEQUAL '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LEQUAL);}
TermArg
TermArgItem
')' {$$ = TrCreateNode (PARSEOP_LNOT, 1, TrLinkChildren ($<n>3,2,$4,$5));}
@@ -1906,7 +1895,7 @@
;
LoadTableTerm
- : PARSEOP_LOADTABLE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LOADTABLE);}
+ : PARSEOP_LOADTABLE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LOADTABLE);}
TermArg
TermArgItem
TermArgItem
@@ -1919,7 +1908,7 @@
;
LOrTerm
- : PARSEOP_LOR '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LOR);}
+ : PARSEOP_LOR '(' {$<n>$ = TrCreateLeafNode (PARSEOP_LOR);}
TermArg
TermArgItem
')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
@@ -1928,7 +1917,7 @@
;
MatchTerm
- : PARSEOP_MATCH '(' {$<n>$ = TrCreateLeafNode (PARSEOP_MATCH);}
+ : PARSEOP_MATCH '(' {$<n>$ = TrCreateLeafNode (PARSEOP_MATCH);}
TermArg
',' MatchOpKeyword
TermArgItem
@@ -1941,7 +1930,7 @@
;
MidTerm
- : PARSEOP_MID '(' {$<n>$ = TrCreateLeafNode (PARSEOP_MID);}
+ : PARSEOP_MID '(' {$<n>$ = TrCreateLeafNode (PARSEOP_MID);}
TermArg
TermArgItem
TermArgItem
@@ -1952,7 +1941,7 @@
;
ModTerm
- : PARSEOP_MOD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_MOD);}
+ : PARSEOP_MOD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_MOD);}
TermArg
TermArgItem
Target
@@ -1962,7 +1951,7 @@
;
MultiplyTerm
- : PARSEOP_MULTIPLY '(' {$<n>$ = TrCreateLeafNode (PARSEOP_MULTIPLY);}
+ : PARSEOP_MULTIPLY '(' {$<n>$ = TrCreateLeafNode (PARSEOP_MULTIPLY);}
TermArg
TermArgItem
Target
@@ -1972,7 +1961,7 @@
;
NAndTerm
- : PARSEOP_NAND '(' {$<n>$ = TrCreateLeafNode (PARSEOP_NAND);}
+ : PARSEOP_NAND '(' {$<n>$ = TrCreateLeafNode (PARSEOP_NAND);}
TermArg
TermArgItem
Target
@@ -1982,7 +1971,7 @@
;
NOrTerm
- : PARSEOP_NOR '(' {$<n>$ = TrCreateLeafNode (PARSEOP_NOR);}
+ : PARSEOP_NOR '(' {$<n>$ = TrCreateLeafNode (PARSEOP_NOR);}
TermArg
TermArgItem
Target
@@ -1992,7 +1981,7 @@
;
NotTerm
- : PARSEOP_NOT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_NOT);}
+ : PARSEOP_NOT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_NOT);}
TermArg
Target
')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
@@ -2001,7 +1990,7 @@
;
ObjectTypeTerm
- : PARSEOP_OBJECTTYPE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE);}
+ : PARSEOP_OBJECTTYPE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_OBJECTTYPE);}
SuperName
')' {$$ = TrLinkChildren ($<n>3,1,$4);}
| PARSEOP_OBJECTTYPE '('
@@ -2009,7 +1998,7 @@
;
OrTerm
- : PARSEOP_OR '(' {$<n>$ = TrCreateLeafNode (PARSEOP_OR);}
+ : PARSEOP_OR '(' {$<n>$ = TrCreateLeafNode (PARSEOP_OR);}
TermArg
TermArgItem
Target
@@ -2023,7 +2012,7 @@
* we've taken a pointer to it. (hard to tell if a local becomes initialized this way.)
*/
RefOfTerm
- : PARSEOP_REFOF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_REFOF);}
+ : PARSEOP_REFOF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_REFOF);}
SuperName
')' {$$ = TrLinkChildren ($<n>3,1,TrSetNodeFlags ($4, NODE_IS_TARGET));}
| PARSEOP_REFOF '('
@@ -2031,7 +2020,7 @@
;
ShiftLeftTerm
- : PARSEOP_SHIFTLEFT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SHIFTLEFT);}
+ : PARSEOP_SHIFTLEFT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SHIFTLEFT);}
TermArg
TermArgItem
Target
@@ -2041,7 +2030,7 @@
;
ShiftRightTerm
- : PARSEOP_SHIFTRIGHT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SHIFTRIGHT);}
+ : PARSEOP_SHIFTRIGHT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SHIFTRIGHT);}
TermArg
TermArgItem
Target
@@ -2051,7 +2040,7 @@
;
SizeOfTerm
- : PARSEOP_SIZEOF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SIZEOF);}
+ : PARSEOP_SIZEOF '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SIZEOF);}
SuperName
')' {$$ = TrLinkChildren ($<n>3,1,$4);}
| PARSEOP_SIZEOF '('
@@ -2059,7 +2048,7 @@
;
StoreTerm
- : PARSEOP_STORE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_STORE);}
+ : PARSEOP_STORE '(' {$<n>$ = TrCreateLeafNode (PARSEOP_STORE);}
TermArg
',' SuperName
')' {$$ = TrLinkChildren ($<n>3,2,$4,TrSetNodeFlags ($6, NODE_IS_TARGET));}
@@ -2068,7 +2057,7 @@
;
SubtractTerm
- : PARSEOP_SUBTRACT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SUBTRACT);}
+ : PARSEOP_SUBTRACT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_SUBTRACT);}
TermArg
TermArgItem
Target
@@ -2078,15 +2067,15 @@
;
TimerTerm
- : PARSEOP_TIMER '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TIMER);}
+ : PARSEOP_TIMER '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TIMER);}
')' {$$ = TrLinkChildren ($<n>3,0);}
- | PARSEOP_TIMER {$$ = TrLinkChildren (TrCreateLeafNode (PARSEOP_TIMER),0);}
+ | PARSEOP_TIMER {$$ = TrLinkChildren (TrCreateLeafNode (PARSEOP_TIMER),0);}
| PARSEOP_TIMER '('
error ')' {$$ = AslDoError(); yyclearin;}
;
ToBCDTerm
- : PARSEOP_TOBCD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TOBCD);}
+ : PARSEOP_TOBCD '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TOBCD);}
TermArg
Target
')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
@@ -2095,7 +2084,7 @@
;
ToBufferTerm
- : PARSEOP_TOBUFFER '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TOBUFFER);}
+ : PARSEOP_TOBUFFER '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TOBUFFER);}
TermArg
Target
')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
@@ -2104,7 +2093,7 @@
;
ToDecimalStringTerm
- : PARSEOP_TODECIMALSTRING '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TODECIMALSTRING);}
+ : PARSEOP_TODECIMALSTRING '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TODECIMALSTRING);}
TermArg
Target
')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
@@ -2113,7 +2102,7 @@
;
ToHexStringTerm
- : PARSEOP_TOHEXSTRING '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TOHEXSTRING);}
+ : PARSEOP_TOHEXSTRING '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TOHEXSTRING);}
TermArg
Target
')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
@@ -2122,7 +2111,7 @@
;
ToIntegerTerm
- : PARSEOP_TOINTEGER '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TOINTEGER);}
+ : PARSEOP_TOINTEGER '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TOINTEGER);}
TermArg
Target
')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
@@ -2131,7 +2120,7 @@
;
ToStringTerm
- : PARSEOP_TOSTRING '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TOSTRING);}
+ : PARSEOP_TOSTRING '(' {$<n>$ = TrCreateLeafNode (PARSEOP_TOSTRING);}
TermArg
OptionalCount
Target
@@ -2148,7 +2137,7 @@
;
WaitTerm
- : PARSEOP_WAIT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_WAIT);}
+ : PARSEOP_WAIT '(' {$<n>$ = TrCreateLeafNode (PARSEOP_WAIT);}
SuperName
TermArgItem
')' {$$ = TrLinkChildren ($<n>3,2,$4,$5);}
@@ -2157,7 +2146,7 @@
;
XOrTerm
- : PARSEOP_XOR '(' {$<n>$ = TrCreateLeafNode (PARSEOP_XOR);}
+ : PARSEOP_XOR '(' {$<n>$ = TrCreateLeafNode (PARSEOP_XOR);}
TermArg
TermArgItem
Target
@@ -2211,8 +2200,8 @@
;
AddressSpaceKeyword
- : ByteConst {$$ = UtCheckIntegerRange ($1, 0x80, 0xFF);}
- | RegionSpaceKeyword {}
+ : ByteConst {$$ = UtCheckIntegerRange ($1, 0x0A, 0xFF);}
+ | RegionSpaceKeyword {}
;
BitsPerByteKeyword
@@ -2371,6 +2360,7 @@
| PARSEOP_REGIONSPACE_IPMI {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_IPMI);}
| PARSEOP_REGIONSPACE_GPIO {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_GPIO);}
| PARSEOP_REGIONSPACE_GSBUS {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_GSBUS);}
+ | PARSEOP_REGIONSPACE_PCC {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_PCC);}
| PARSEOP_REGIONSPACE_FFIXEDHW {$$ = TrCreateLeafNode (PARSEOP_REGIONSPACE_FFIXEDHW);}
;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/aslerror.c
--- a/head/sys/contrib/dev/acpica/compiler/aslerror.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/aslerror.c Wed Jul 25 16:45:04 2012 +0300
@@ -259,7 +259,7 @@
{
if (Gbl_VerboseErrors)
{
- fprintf (OutputFile, "%6s", Enode->Filename);
+ fprintf (OutputFile, "%-8s", Enode->Filename);
if (Enode->LineNumber)
{
@@ -270,12 +270,7 @@
}
else
{
- if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_ASL)
- fprintf (OutputFile, " %6u: ",
- PrGetLineNumber (Enode->LineNumber));
- else
- fprintf (OutputFile, " %6u: ",
- Enode->LineNumber);
+ fprintf (OutputFile, " %6u: ", Enode->LineNumber);
/*
* If not at EOF, get the corresponding source code line and
@@ -320,20 +315,16 @@
}
else
{
+ /*
+ * Less verbose version of the error message, enabled via the
+ * -vi switch. The format is compatible with MS Visual Studio.
+ */
fprintf (OutputFile, "%s", Enode->Filename);
if (Enode->LineNumber)
{
- if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_ASL)
- {
- fprintf (OutputFile, "(%u) i:%6u : ",
- PrGetLineNumber (Enode->LineNumber), Enode->LineNumber);
- }
- else
- {
- fprintf (OutputFile, "(%u) i:%6u : ",
- Enode->LineNumber, Enode->LineNumber);
- }
+ fprintf (OutputFile, "(%u) : ",
+ Enode->LineNumber);
}
}
}
@@ -348,9 +339,18 @@
{
/* Decode the message ID */
- fprintf (OutputFile, "%s %4.4d - ",
- AslErrorLevel[Enode->Level],
- Enode->MessageId + ((Enode->Level+1) * 1000));
+ if (Gbl_VerboseErrors)
+ {
+ fprintf (OutputFile, "%s %4.4d -",
+ AslErrorLevel[Enode->Level],
+ Enode->MessageId + ((Enode->Level+1) * 1000));
+ }
+ else /* IDE case */
+ {
+ fprintf (OutputFile, "%s %4.4d:",
+ AslErrorLevelIde[Enode->Level],
+ Enode->MessageId + ((Enode->Level+1) * 1000));
+ }
MainMessage = AslMessages[Enode->MessageId];
ExtraMessage = Enode->Message;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/aslfiles.c
--- a/head/sys/contrib/dev/acpica/compiler/aslfiles.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/aslfiles.c Wed Jul 25 16:45:04 2012 +0300
@@ -81,12 +81,12 @@
void)
{
- AePrintErrorLog (ASL_FILE_STDOUT);
+ AePrintErrorLog (ASL_FILE_STDERR);
if (Gbl_DebugFlag)
{
- /* Print error summary to the debug file */
+ /* Print error summary to stdout also */
- AePrintErrorLog (ASL_FILE_STDERR);
+ AePrintErrorLog (ASL_FILE_STDOUT);
}
exit (1);
@@ -388,11 +388,38 @@
void
FlSetLineNumber (
- ACPI_PARSE_OBJECT *Op)
+ UINT32 LineNumber)
{
- Gbl_CurrentLineNumber = (UINT32) Op->Asl.Value.Integer;
- Gbl_LogicalLineNumber = (UINT32) Op->Asl.Value.Integer;
+ DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New line number %u (old %u)\n",
+ LineNumber, Gbl_LogicalLineNumber);
+
+ Gbl_CurrentLineNumber = LineNumber;
+ Gbl_LogicalLineNumber = LineNumber;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: FlSetFilename
+ *
+ * PARAMETERS: Op - Parse node for the LINE asl statement
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Set the current filename
+ *
+ ******************************************************************************/
+
+void
+FlSetFilename (
+ char *Filename)
+{
+
+ DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New filename %s (old %s)\n",
+ Filename, Gbl_Files[ASL_FILE_INPUT].Filename);
+
+ Gbl_Files[ASL_FILE_INPUT].Filename = Filename;
}
@@ -465,6 +492,107 @@
/*******************************************************************************
*
+ * FUNCTION: FlMergePathnames
+ *
+ * PARAMETERS: PrefixDir - Prefix directory pathname. Can be NULL or
+ * a zero length string.
+ * FilePathname - The include filename from the source ASL.
+ *
+ * RETURN: Merged pathname string
+ *
+ * DESCRIPTION: Merge two pathnames that (probably) have common elements, to
+ * arrive at a minimal length string. Merge can occur if the
+ * FilePathname is relative to the PrefixDir.
+ *
+ ******************************************************************************/
+
+char *
+FlMergePathnames (
+ char *PrefixDir,
+ char *FilePathname)
+{
+ char *CommonPath;
+ char *Pathname;
+ char *LastElement;
+
+
+ DbgPrint (ASL_PARSE_OUTPUT, "Include: Prefix path - \"%s\"\n"
+ "Include: FilePathname - \"%s\"\n",
+ PrefixDir, FilePathname);
+
+ /*
+ * If there is no prefix directory or if the file pathname is absolute,
+ * just return the original file pathname
+ */
+ if (!PrefixDir || (!*PrefixDir) ||
+ (*FilePathname == '/') ||
+ (FilePathname[1] == ':'))
+ {
+ Pathname = ACPI_ALLOCATE (strlen (FilePathname) + 1);
+ strcpy (Pathname, FilePathname);
+ goto ConvertBackslashes;
+ }
+
+ /* Need a local copy of the prefix directory path */
+
+ CommonPath = ACPI_ALLOCATE (strlen (PrefixDir) + 1);
+ strcpy (CommonPath, PrefixDir);
+
+ /*
+ * Walk forward through the file path, and simultaneously backward
+ * through the prefix directory path until there are no more
+ * relative references at the start of the file path.
+ */
+ while (*FilePathname && (!strncmp (FilePathname, "../", 3)))
+ {
+ /* Remove last element of the prefix directory path */
+
+ LastElement = strrchr (CommonPath, '/');
+ if (!LastElement)
+ {
+ goto ConcatenatePaths;
+ }
+
+ *LastElement = 0; /* Terminate CommonPath string */
+ FilePathname += 3; /* Point to next path element */
+ }
+
+ /*
+ * Remove the last element of the prefix directory path (it is the same as
+ * the first element of the file pathname), and build the final merged
+ * pathname.
+ */
+ LastElement = strrchr (CommonPath, '/');
+ if (LastElement)
+ {
+ *LastElement = 0;
+ }
+
+ /* Build the final merged pathname */
+
+ConcatenatePaths:
+ Pathname = ACPI_ALLOCATE_ZEROED (strlen (CommonPath) + strlen (FilePathname) + 2);
+ if (LastElement && *CommonPath)
+ {
+ strcpy (Pathname, CommonPath);
+ strcat (Pathname, "/");
+ }
+ strcat (Pathname, FilePathname);
+ ACPI_FREE (CommonPath);
+
+ /* Convert all backslashes to normal slashes */
+
+ConvertBackslashes:
+ UtConvertBackslashes (Pathname);
+
+ DbgPrint (ASL_PARSE_OUTPUT, "Include: Merged Pathname - \"%s\"\n",
+ Pathname);
+ return (Pathname);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: FlOpenIncludeWithPrefix
*
* PARAMETERS: PrefixDir - Prefix directory pathname. Can be a zero
@@ -488,12 +616,9 @@
/* Build the full pathname to the file */
- Pathname = ACPI_ALLOCATE (strlen (PrefixDir) + strlen (Filename) + 1);
+ Pathname = FlMergePathnames (PrefixDir, Filename);
- strcpy (Pathname, PrefixDir);
- strcat (Pathname, Filename);
-
- DbgPrint (ASL_PARSE_OUTPUT, "\nAttempt to open include file: path %s\n\n",
+ DbgPrint (ASL_PARSE_OUTPUT, "Include: Opening file - \"%s\"\n\n",
Pathname);
/* Attempt to open the file, push if successful */
@@ -548,7 +673,7 @@
* Flush out the "include ()" statement on this line, start
* the actual include file on the next line
*/
- ResetCurrentLineBuffer ();
+ AslResetCurrentLineBuffer ();
FlPrintFile (ASL_FILE_SOURCE_OUTPUT, "\n");
Gbl_CurrentLineOffset++;
@@ -629,7 +754,7 @@
/* Open the input ASL file, text mode */
- FlOpenFile (ASL_FILE_INPUT, InputFilename, "r");
+ FlOpenFile (ASL_FILE_INPUT, InputFilename, "rt");
AslCompilerin = Gbl_Files[ASL_FILE_INPUT].Handle;
return (AE_OK);
@@ -713,7 +838,7 @@
/* Open the hex file, text mode */
- FlOpenFile (ASL_FILE_HEX_OUTPUT, Filename, "w+");
+ FlOpenFile (ASL_FILE_HEX_OUTPUT, Filename, "w+t");
AslCompilerSignon (ASL_FILE_HEX_OUTPUT);
AslCompilerFileHeader (ASL_FILE_HEX_OUTPUT);
@@ -764,24 +889,27 @@
/* Open the listing file, text mode */
- FlOpenFile (ASL_FILE_LISTING_OUTPUT, Filename, "w+");
+ FlOpenFile (ASL_FILE_LISTING_OUTPUT, Filename, "w+t");
AslCompilerSignon (ASL_FILE_LISTING_OUTPUT);
AslCompilerFileHeader (ASL_FILE_LISTING_OUTPUT);
}
- /* Create the preprocessor output file */
+ /* Create the preprocessor output file if preprocessor enabled */
- Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_PREPROCESSOR);
- if (!Filename)
+ if (Gbl_PreprocessFlag)
{
- AslCommonError (ASL_ERROR, ASL_MSG_PREPROCESSOR_FILENAME,
- 0, 0, 0, 0, NULL, NULL);
- return (AE_ERROR);
+ Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_PREPROCESSOR);
+ if (!Filename)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_PREPROCESSOR_FILENAME,
+ 0, 0, 0, 0, NULL, NULL);
+ return (AE_ERROR);
+ }
+
+ FlOpenFile (ASL_FILE_PREPROCESSOR, Filename, "w+t");
}
- FlOpenFile (ASL_FILE_PREPROCESSOR, Filename, "w+b");
-
/* All done for data table compiler */
if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA)
@@ -824,7 +952,7 @@
/* Open the assembly code source file, text mode */
- FlOpenFile (ASL_FILE_ASM_SOURCE_OUTPUT, Filename, "w+");
+ FlOpenFile (ASL_FILE_ASM_SOURCE_OUTPUT, Filename, "w+t");
AslCompilerSignon (ASL_FILE_ASM_SOURCE_OUTPUT);
AslCompilerFileHeader (ASL_FILE_ASM_SOURCE_OUTPUT);
@@ -844,7 +972,7 @@
/* Open the C code source file, text mode */
- FlOpenFile (ASL_FILE_C_SOURCE_OUTPUT, Filename, "w+");
+ FlOpenFile (ASL_FILE_C_SOURCE_OUTPUT, Filename, "w+t");
FlPrintFile (ASL_FILE_C_SOURCE_OUTPUT, "/*\n");
AslCompilerSignon (ASL_FILE_C_SOURCE_OUTPUT);
@@ -865,7 +993,7 @@
/* Open the assembly include file, text mode */
- FlOpenFile (ASL_FILE_ASM_INCLUDE_OUTPUT, Filename, "w+");
+ FlOpenFile (ASL_FILE_ASM_INCLUDE_OUTPUT, Filename, "w+t");
AslCompilerSignon (ASL_FILE_ASM_INCLUDE_OUTPUT);
AslCompilerFileHeader (ASL_FILE_ASM_INCLUDE_OUTPUT);
@@ -885,7 +1013,7 @@
/* Open the C include file, text mode */
- FlOpenFile (ASL_FILE_C_INCLUDE_OUTPUT, Filename, "w+");
+ FlOpenFile (ASL_FILE_C_INCLUDE_OUTPUT, Filename, "w+t");
FlPrintFile (ASL_FILE_C_INCLUDE_OUTPUT, "/*\n");
AslCompilerSignon (ASL_FILE_C_INCLUDE_OUTPUT);
@@ -906,7 +1034,7 @@
/* Open the namespace file, text mode */
- FlOpenFile (ASL_FILE_NAMESPACE_OUTPUT, Filename, "w+");
+ FlOpenFile (ASL_FILE_NAMESPACE_OUTPUT, Filename, "w+t");
AslCompilerSignon (ASL_FILE_NAMESPACE_OUTPUT);
AslCompilerFileHeader (ASL_FILE_NAMESPACE_OUTPUT);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/aslglobal.h
--- a/head/sys/contrib/dev/acpica/compiler/aslglobal.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/aslglobal.h Wed Jul 25 16:45:04 2012 +0300
@@ -74,7 +74,7 @@
extern const ASL_MAPPING_ENTRY AslKeywordMapping[];
extern char *AslCompilertext;
-#define ASL_LINE_BUFFER_SIZE 4096
+#define ASL_LINE_BUFFER_SIZE (4096 * 4) /* 16K */
#define ASL_MSG_BUFFER_SIZE 4096
#define HEX_TABLE_LINE_SIZE 8
#define HEX_LISTING_LINE_SIZE 8
@@ -84,6 +84,7 @@
ASL_EXTERN char Gbl_CurrentLineBuffer[ASL_LINE_BUFFER_SIZE];
ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_CurrentColumn, 0);
+ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_PreviousLineNumber, 0);
ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_CurrentLineNumber, 1);
ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_LogicalLineNumber, 1);
ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_CurrentLineOffset, 0);
@@ -99,6 +100,7 @@
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DoCompile, TRUE);
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DoSignon, TRUE);
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_PreprocessOnly, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_PreprocessFlag, TRUE);
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DisassembleAll, FALSE);
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_Acpi2, FALSE);
@@ -118,6 +120,7 @@
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_FoldConstants, TRUE);
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_VerboseErrors, TRUE);
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_NoErrors, FALSE);
+ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_WarningsAsErrors, FALSE);
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_NoResourceChecking, FALSE);
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DisasmFlag, FALSE);
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_GetAllTables, FALSE);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/asllookup.c
--- a/head/sys/contrib/dev/acpica/compiler/asllookup.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/asllookup.c Wed Jul 25 16:45:04 2012 +0300
@@ -1098,7 +1098,7 @@
if (Message)
{
- sprintf (MsgBuffer, "Tag: %u bit%s, Field: %u bit%s",
+ sprintf (MsgBuffer, "Size mismatch, Tag: %u bit%s, Field: %u bit%s",
TagBitLength, (TagBitLength > 1) ? "s" : "",
FieldBitLength, (FieldBitLength > 1) ? "s" : "");
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/aslmain.c
--- a/head/sys/contrib/dev/acpica/compiler/aslmain.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/aslmain.c Wed Jul 25 16:45:04 2012 +0300
@@ -63,7 +63,7 @@
void);
static void
-HelpMessage (
+FilenameHelp (
void);
static void
@@ -96,7 +96,7 @@
#define ASL_TOKEN_SEPARATORS " \t\n"
-#define ASL_SUPPORTED_OPTIONS "@:2b|c|d^D:e:fgh^i|I:l^mno|p:Pr:s|t|T:G^v|w|x:z"
+#define ASL_SUPPORTED_OPTIONS "@:2b|c|d^D:e:fgh^i|I:l^mno|p:P^r:s|t|T:G^v^w|x:z"
/*******************************************************************************
@@ -119,11 +119,13 @@
printf ("\nGlobal:\n");
ACPI_OPTION ("-@ <file>", "Specify command file");
ACPI_OPTION ("-I <dir>", "Specify additional include directory");
+ ACPI_OPTION ("-v", "Display compiler version");
printf ("\nPreprocessor:\n");
ACPI_OPTION ("-D <symbol>", "Define symbol for preprocessor use");
ACPI_OPTION ("-li", "Create preprocessed output file (*.i)");
ACPI_OPTION ("-P", "Preprocess only and create preprocessor output file (*.i)");
+ ACPI_OPTION ("-Pn", "Disable preprocessor");
printf ("\nGeneral Output:\n");
ACPI_OPTION ("-p <prefix>", "Specify path/filename prefix for all output files");
@@ -133,6 +135,7 @@
ACPI_OPTION ("-vr", "Disable remarks");
ACPI_OPTION ("-vs", "Disable signon");
ACPI_OPTION ("-w1 -w2 -w3", "Set warning reporting level");
+ ACPI_OPTION ("-we", "Report warnings as errors");
printf ("\nAML Output Files:\n");
ACPI_OPTION ("-sa -sc", "Create AML in assembler or C source file (*.asm or *.c)");
@@ -168,27 +171,36 @@
ACPI_OPTION ("-g", "Get ACPI tables and write to files (*.dat)");
printf ("\nHelp:\n");
- ACPI_OPTION ("-h", "Additional help and compiler debug options");
+ ACPI_OPTION ("-h", "This message");
ACPI_OPTION ("-hc", "Display operators allowed in constant expressions");
+ ACPI_OPTION ("-hf", "Display help for output filename generation");
ACPI_OPTION ("-hr", "Display ACPI reserved method names");
ACPI_OPTION ("-ht", "Display currently supported ACPI table names");
+
+ printf ("\nDebug Options:\n");
+ ACPI_OPTION ("-bf -bt", "Create debug file (full or parse tree only) (*.txt)");
+ ACPI_OPTION ("-f", "Ignore errors, force creation of AML output file(s)");
+ ACPI_OPTION ("-n", "Parse only, no output generation");
+ ACPI_OPTION ("-ot", "Display compile times and statistics");
+ ACPI_OPTION ("-x <level>", "Set debug level for trace output");
+ ACPI_OPTION ("-z", "Do not insert new compiler ID for DataTables");
}
/*******************************************************************************
*
- * FUNCTION: HelpMessage
+ * FUNCTION: FilenameHelp
*
* PARAMETERS: None
*
* RETURN: None
*
- * DESCRIPTION: Display help message
+ * DESCRIPTION: Display help message for output filename generation
*
******************************************************************************/
static void
-HelpMessage (
+FilenameHelp (
void)
{
@@ -200,17 +212,6 @@
printf (" 2) The prefix of the AMLFileName in the ASL Definition Block\n");
printf (" 3) The prefix of the input filename\n");
printf ("\n");
-
- Options ();
-
- printf ("\nCompiler/Disassembler Debug Options:\n");
- ACPI_OPTION ("-bb -bp -bt", "Create compiler debug/trace file (*.txt)");
- ACPI_OPTION ("", "Types: Parse/Tree/Both");
- ACPI_OPTION ("-f", "Ignore errors, force creation of AML output file(s)");
- ACPI_OPTION ("-n", "Parse only, no output generation");
- ACPI_OPTION ("-ot", "Display compile times");
- ACPI_OPTION ("-x <level>", "Set debug level for trace output");
- ACPI_OPTION ("-z", "Do not insert new compiler ID for DataTables");
}
@@ -428,13 +429,7 @@
case 'b': /* Debug output options */
switch (AcpiGbl_Optarg[0])
{
- case 'b':
- AslCompilerdebug = 1; /* same as yydebug */
- DtParserdebug = 1;
- PrParserdebug = 1;
- break;
-
- case 'p':
+ case 'f':
AslCompilerdebug = 1; /* same as yydebug */
DtParserdebug = 1;
PrParserdebug = 1;
@@ -528,13 +523,17 @@
switch (AcpiGbl_Optarg[0])
{
case '^':
- HelpMessage ();
+ Usage ();
exit (0);
case 'c':
UtDisplayConstantOpcodes ();
exit (0);
+ case 'f':
+ FilenameHelp ();
+ exit (0);
+
case 'r':
/* reserved names */
@@ -671,9 +670,22 @@
break;
- case 'P': /* Preprocess (plus .i file) only */
- Gbl_PreprocessOnly = TRUE;
- Gbl_PreprocessorOutputFlag = TRUE;
+ case 'P': /* Preprocessor options */
+ switch (AcpiGbl_Optarg[0])
+ {
+ case '^': /* Proprocess only, emit (.i) file */
+ Gbl_PreprocessOnly = TRUE;
+ Gbl_PreprocessorOutputFlag = TRUE;
+ break;
+
+ case 'n': /* Disable preprocessor */
+ Gbl_PreprocessFlag = FALSE;
+ break;
+
+ default:
+ printf ("Unknown option: -P%s\n", AcpiGbl_Optarg);
+ return (-1);
+ }
break;
@@ -740,9 +752,13 @@
break;
- case 'v': /* Verbosity settings */
+ case 'v': /* Version and verbosity settings */
switch (AcpiGbl_Optarg[0])
{
+ case '^':
+ printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME));
+ exit (0);
+
case 'a':
/* Disable All error/warning messages */
@@ -750,9 +766,18 @@
break;
case 'i':
- /* Less verbose error messages */
-
+ /*
+ * Support for integrated development environment(s).
+ *
+ * 1) No compiler signon
+ * 2) Send stderr messages to stdout
+ * 3) Less verbose error messages (single line only for each)
+ * 4) Error/warning messages are formatted appropriately to
+ * be recognized by MS Visual Studio
+ */
Gbl_VerboseErrors = FALSE;
+ Gbl_DoSignon = FALSE;
+ Gbl_Files[ASL_FILE_STDERR].Handle = stdout;
break;
case 'o':
@@ -793,6 +818,10 @@
Gbl_WarningLevel = ASL_WARNING3;
break;
+ case 'e':
+ Gbl_WarningsAsErrors = TRUE;
+ break;
+
default:
printf ("Unknown option: -w%s\n", AcpiGbl_Optarg);
return (-1);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/aslmap.c
--- a/head/sys/contrib/dev/acpica/compiler/aslmap.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/aslmap.c Wed Jul 25 16:45:04 2012 +0300
@@ -240,7 +240,6 @@
/* I2CSERIALBUS */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
/* IF */ OP_TABLE_ENTRY (AML_IF_OP, 0, NODE_AML_PACKAGE, 0),
/* INCLUDE */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
-/* INCLUDE_CSTYLE */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
/* INCLUDE_END */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
/* INCREMENT */ OP_TABLE_ENTRY (AML_INCREMENT_OP, 0, 0, ACPI_BTYPE_INTEGER),
/* INDEX */ OP_TABLE_ENTRY (AML_INDEX_OP, 0, 0, ACPI_BTYPE_REFERENCE),
@@ -265,7 +264,6 @@
/* LEQUAL */ OP_TABLE_ENTRY (AML_LEQUAL_OP, 0, 0, ACPI_BTYPE_INTEGER),
/* LGREATER */ OP_TABLE_ENTRY (AML_LGREATER_OP, 0, 0, ACPI_BTYPE_INTEGER),
/* LGREATEREQUAL */ OP_TABLE_ENTRY (AML_LGREATEREQUAL_OP, 0, 0, ACPI_BTYPE_INTEGER),
-/* LINE */ OP_TABLE_ENTRY (AML_DEFAULT_ARG_OP, 0, 0, 0),
/* LLESS */ OP_TABLE_ENTRY (AML_LLESS_OP, 0, 0, ACPI_BTYPE_INTEGER),
/* LLESSEQUAL */ OP_TABLE_ENTRY (AML_LLESSEQUAL_OP, 0, 0, ACPI_BTYPE_INTEGER),
/* LNOT */ OP_TABLE_ENTRY (AML_LNOT_OP, 0, 0, ACPI_BTYPE_INTEGER),
@@ -369,6 +367,7 @@
/* REGIONSPACE_IO */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_SYSTEM_IO, 0, 0),
/* REGIONSPACE_IPMI */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_IPMI, 0, 0),
/* REGIONSPACE_MEM */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_SYSTEM_MEMORY, 0, 0),
+/* REGIONSPACE_PCC */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_PLATFORM_COMM, 0, 0),
/* REGIONSPACE_PCI */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_PCI_CONFIG, 0, 0),
/* REGIONSPACE_PCIBAR */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_PCI_BAR_TARGET, 0, 0),
/* REGIONSPACE_SMBUS */ OP_TABLE_ENTRY (AML_RAW_DATA_BYTE, ACPI_ADR_SPACE_SMBUS, 0, 0),
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/aslmessages.h
--- a/head/sys/contrib/dev/acpica/compiler/aslmessages.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/aslmessages.h Wed Jul 25 16:45:04 2012 +0300
@@ -402,7 +402,7 @@
};
-char *AslErrorLevel [ASL_NUM_REPORT_LEVELS] = {
+const char *AslErrorLevel [ASL_NUM_REPORT_LEVELS] = {
"Warning ",
"Warning ",
"Warning ",
@@ -411,6 +411,15 @@
"Optimize"
};
+const char *AslErrorLevelIde [ASL_NUM_REPORT_LEVELS] = {
+ "warning ",
+ "warning ",
+ "warning ",
+ "error ",
+ "remark ",
+ "optimize"
+};
+
#define ASL_ERROR_LEVEL_LENGTH 8 /* Length of strings above */
#endif /* ASL_EXCEPTIONS */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/aslrestype1.c
--- a/head/sys/contrib/dev/acpica/compiler/aslrestype1.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/aslrestype1.c Wed Jul 25 16:45:04 2012 +0300
@@ -453,6 +453,10 @@
PreviousRnode = Rnode;
Descriptor = Rnode->Buffer;
+ /* Increment offset past StartDependent descriptor */
+
+ CurrentByteOffset += sizeof (AML_RESOURCE_START_DEPENDENT);
+
/* Descriptor has priority byte */
Descriptor->StartDpf.DescriptorType = ACPI_RESOURCE_NAME_START_DEPENDENT |
@@ -545,6 +549,10 @@
ASL_RDESC_ST_DEPEND_SIZE;
PreviousRnode = Rnode;
+ /* Increment offset past StartDependentNoPri descriptor */
+
+ CurrentByteOffset += sizeof (AML_RESOURCE_START_DEPENDENT_NOPRIO);
+
/* Process all child initialization nodes */
State = ACPI_RSTATE_START_DEPENDENT;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/aslstartup.c
--- a/head/sys/contrib/dev/acpica/compiler/aslstartup.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/aslstartup.c Wed Jul 25 16:45:04 2012 +0300
@@ -227,7 +227,7 @@
/* Check for 100% ASCII source file (comments are ignored) */
- Status = FlCheckForAscii (Info);
+ Status = FlCheckForAscii (Info->Handle, Info->Filename, TRUE);
if (ACPI_FAILURE (Status))
{
printf ("Non-ascii input file - %s\n", Info->Filename);
@@ -404,18 +404,33 @@
case ASL_INPUT_TYPE_ASCII_DATA:
Status = DtDoCompile ();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
if (Gbl_Signature)
{
ACPI_FREE (Gbl_Signature);
Gbl_Signature = NULL;
}
+
+ /* Check if any errors occurred during compile */
+
+ Status = AslCheckForErrorExit ();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Cleanup (for next source file) and exit */
+
AeClearErrorLog ();
PrTerminatePreprocessor ();
return (Status);
/*
- * ASL Compilation (Optional)
+ * ASL Compilation
*/
case ASL_INPUT_TYPE_ASCII_ASL:
@@ -427,18 +442,19 @@
return (Status);
}
- Status = CmDoCompile ();
+ (void) CmDoCompile ();
(void) AcpiTerminate ();
- /*
- * Return non-zero exit code if there have been errors, unless the
- * global ignore error flag has been set
- */
- if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors))
+ /* Check if any errors occurred during compile */
+
+ Status = AslCheckForErrorExit ();
+ if (ACPI_FAILURE (Status))
{
- return (AE_ERROR);
+ return (Status);
}
+ /* Cleanup (for next source file) and exit */
+
AeClearErrorLog ();
PrTerminatePreprocessor ();
return (AE_OK);
@@ -525,3 +541,47 @@
return (Status);
}
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslCheckForErrorExit
+ *
+ * PARAMETERS: None. Examines global exception count array
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Determine if compiler should abort with error status
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AslCheckForErrorExit (
+ void)
+{
+
+ /*
+ * Return non-zero exit code if there have been errors, unless the
+ * global ignore error flag has been set
+ */
+ if (!Gbl_IgnoreErrors)
+ {
+ if (Gbl_ExceptionCount[ASL_ERROR] > 0)
+ {
+ return (AE_ERROR);
+ }
+
+ /* Optionally treat warnings as errors */
+
+ if (Gbl_WarningsAsErrors)
+ {
+ if ((Gbl_ExceptionCount[ASL_WARNING] > 0) ||
+ (Gbl_ExceptionCount[ASL_WARNING2] > 0) ||
+ (Gbl_ExceptionCount[ASL_WARNING3] > 0))
+ {
+ return (AE_ERROR);
+ }
+ }
+ }
+
+ return (AE_OK);
+}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/aslsupport.l
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/contrib/dev/acpica/compiler/aslsupport.l Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,804 @@
+
+/******************************************************************************
+ *
+ * Module Name: aslsupport.l - Flex/lex scanner C support routines.
+ * NOTE: Included into aslcompile.l, not compiled by itself.
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+/* Configuration */
+
+#define ASL_SPACES_PER_TAB 4
+
+#define ASL_NORMAL_CHAR 0
+#define ASL_ESCAPE_SEQUENCE 1
+#define ASL_OCTAL_CONSTANT 2
+#define ASL_HEX_CONSTANT 3
+
+
+/* File node - used for "Include" operator file stack */
+
+typedef struct asl_file_node
+{
+ FILE *File;
+ UINT32 CurrentLineNumber;
+ YY_BUFFER_STATE State;
+ char *Filename;
+ struct asl_file_node *Next;
+
+} ASL_FILE_NODE;
+
+/* File stack for the "Include" operator (NOT #include operator) */
+
+ASL_FILE_NODE *Gbl_IncludeFileStack = NULL;
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslDoLineDirective
+ *
+ * PARAMETERS: None. Uses input() to access current source code line
+ *
+ * RETURN: Updates global line number and filename
+ *
+ * DESCRIPTION: Handle #line directives emitted by the preprocessor.
+ *
+ * The #line directive is emitted by the preprocesser, and is used to
+ * pass through line numbers from the original source code file to the
+ * preprocessor output file (.i). This allows any compiler-generated
+ * error messages to be displayed with the correct line number.
+ *
+ ******************************************************************************/
+
+static void
+AslDoLineDirective (
+ void)
+{
+ int c;
+ char *Token;
+ UINT32 LineNumber;
+ char *Filename;
+ UINT32 i;
+
+
+ /* Eat the entire line that contains the #line directive */
+
+ Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
+
+ while ((c = input()) != '\n' && c != EOF)
+ {
+ *Gbl_LineBufPtr = c;
+ Gbl_LineBufPtr++;
+ }
+ *Gbl_LineBufPtr = 0;
+
+ /* First argument is the actual line number */
+
+ Token = strtok (Gbl_CurrentLineBuffer, " ");
+ if (!Token)
+ {
+ goto ResetAndExit;
+ }
+
+ /* First argument is the line number */
+
+ LineNumber = (UINT32) UtDoConstant (Token);
+
+ /* Emit the appropriate number of newlines */
+
+ Gbl_CurrentColumn = 0;
+ if (LineNumber > Gbl_CurrentLineNumber)
+ {
+ for (i = 0; i < (LineNumber - Gbl_CurrentLineNumber); i++)
+ {
+ FlWriteFile (ASL_FILE_SOURCE_OUTPUT, "\n", 1);
+ Gbl_CurrentColumn++;
+ }
+ }
+
+ FlSetLineNumber (LineNumber);
+
+ /* Second argument is the optional filename (in double quotes) */
+
+ Token = strtok (NULL, " \"");
+ if (Token)
+ {
+ Filename = ACPI_ALLOCATE_ZEROED (strlen (Token) + 1);
+ strcpy (Filename, Token);
+ FlSetFilename (Filename);
+ }
+
+ /* Third argument is not supported at this time */
+
+ResetAndExit:
+
+ /* Reset globals for a new line */
+
+ Gbl_CurrentLineOffset += Gbl_CurrentColumn;
+ Gbl_CurrentColumn = 0;
+ Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslPopInputFileStack
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: 0 if a node was popped, -1 otherwise
+ *
+ * DESCRIPTION: Pop the top of the input file stack and point the parser to
+ * the saved parse buffer contained in the fnode. Also, set the
+ * global line counters to the saved values. This function is
+ * called when an include file reaches EOF.
+ *
+ ******************************************************************************/
+
+int
+AslPopInputFileStack (
+ void)
+{
+ ASL_FILE_NODE *Fnode;
+
+
+ Fnode = Gbl_IncludeFileStack;
+ DbgPrint (ASL_PARSE_OUTPUT, "\nPop InputFile Stack, Fnode %p\n\n", Fnode);
+
+ if (!Fnode)
+ {
+ return (-1);
+ }
+
+ /* Close the current include file */
+
+ fclose (yyin);
+
+ /* Update the top-of-stack */
+
+ Gbl_IncludeFileStack = Fnode->Next;
+
+ /* Reset global line counter and filename */
+
+ Gbl_Files[ASL_FILE_INPUT].Filename = Fnode->Filename;
+ Gbl_CurrentLineNumber = Fnode->CurrentLineNumber;
+
+ /* Point the parser to the popped file */
+
+ yy_delete_buffer (YY_CURRENT_BUFFER);
+ yy_switch_to_buffer (Fnode->State);
+
+ /* All done with this node */
+
+ ACPI_FREE (Fnode);
+ return (0);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslPushInputFileStack
+ *
+ * PARAMETERS: InputFile - Open file pointer
+ * Filename - Name of the file
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Push the InputFile onto the file stack, and point the parser
+ * to this file. Called when an include file is successfully
+ * opened.
+ *
+ ******************************************************************************/
+
+void
+AslPushInputFileStack (
+ FILE *InputFile,
+ char *Filename)
+{
+ ASL_FILE_NODE *Fnode;
+ YY_BUFFER_STATE State;
+
+
+ /* Save the current state in an Fnode */
+
+ Fnode = UtLocalCalloc (sizeof (ASL_FILE_NODE));
+
+ Fnode->File = yyin;
+ Fnode->Next = Gbl_IncludeFileStack;
+ Fnode->State = YY_CURRENT_BUFFER;
+ Fnode->CurrentLineNumber = Gbl_CurrentLineNumber;
+ Fnode->Filename = Gbl_Files[ASL_FILE_INPUT].Filename;
+
+ /* Push it on the stack */
+
+ Gbl_IncludeFileStack = Fnode;
+
+ /* Point the parser to this file */
+
+ State = yy_create_buffer (InputFile, YY_BUF_SIZE);
+ yy_switch_to_buffer (State);
+
+ DbgPrint (ASL_PARSE_OUTPUT, "\nPush InputFile Stack, returning %p\n\n", InputFile);
+
+ /* Reset the global line count and filename */
+
+ Gbl_Files[ASL_FILE_INPUT].Filename = Filename;
+ Gbl_CurrentLineNumber = 1;
+ yyin = InputFile;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslResetCurrentLineBuffer
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Reset the Line Buffer to zero, increment global line numbers.
+ *
+ ******************************************************************************/
+
+void
+AslResetCurrentLineBuffer (
+ void)
+{
+
+ if (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle)
+ {
+ FlWriteFile (ASL_FILE_SOURCE_OUTPUT, Gbl_CurrentLineBuffer,
+ Gbl_LineBufPtr - Gbl_CurrentLineBuffer);
+ }
+
+ Gbl_CurrentLineOffset += Gbl_CurrentColumn;
+ Gbl_CurrentColumn = 0;
+
+ Gbl_CurrentLineNumber++;
+ Gbl_LogicalLineNumber++;
+ Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslInsertLineBuffer
+ *
+ * PARAMETERS: SourceChar - One char from the input ASL source file
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Put one character of the source file into the temp line buffer
+ *
+ ******************************************************************************/
+
+void
+AslInsertLineBuffer (
+ int SourceChar)
+{
+ UINT32 i;
+ UINT32 Count = 1;
+
+
+ if (SourceChar == EOF)
+ {
+ return;
+ }
+
+ Gbl_InputByteCount++;
+
+ /* Handle tabs. Convert to spaces */
+
+ if (SourceChar == '\t')
+ {
+ SourceChar = ' ';
+ Count = ASL_SPACES_PER_TAB -
+ (Gbl_CurrentColumn & (ASL_SPACES_PER_TAB-1));
+ }
+
+ for (i = 0; i < Count; i++)
+ {
+ Gbl_CurrentColumn++;
+
+ /* Insert the character into the line buffer */
+
+ *Gbl_LineBufPtr = (UINT8) SourceChar;
+ Gbl_LineBufPtr++;
+
+ if (Gbl_LineBufPtr > (Gbl_CurrentLineBuffer + (ASL_LINE_BUFFER_SIZE - 1)))
+ {
+#if 0
+ /*
+ * Warning if we have split a long source line.
+ * <Probably overkill>
+ */
+ sprintf (MsgBuffer, "Max %u", ASL_LINE_BUFFER_SIZE);
+ AslCommonError (ASL_WARNING, ASL_MSG_LONG_LINE,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_CurrentLineOffset, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, MsgBuffer);
+#endif
+
+ AslResetCurrentLineBuffer ();
+ }
+ else if (SourceChar == '\n')
+ {
+ /* End of line */
+
+ AslResetCurrentLineBuffer ();
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: count
+ *
+ * PARAMETERS: yytext - Contains the matched keyword.
+ * Type - Keyword/Character type:
+ * 0 = anything except a keyword
+ * 1 = pseudo-keywords
+ * 2 = non-executable ASL keywords
+ * 3 = executable ASL keywords
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Count keywords and put them into the line buffer
+ *
+ ******************************************************************************/
+
+static void
+count (
+ int Type)
+{
+ int i;
+
+
+ switch (Type)
+ {
+ case 2:
+ TotalKeywords++;
+ TotalNamedObjects++;
+ break;
+
+ case 3:
+ TotalKeywords++;
+ TotalExecutableOpcodes++;
+ break;
+ }
+
+ for (i = 0; (yytext[i] != 0) && (yytext[i] != EOF); i++)
+ {
+ AslInsertLineBuffer (yytext[i]);
+ *Gbl_LineBufPtr = 0;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslDoComment
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: none
+ *
+ * DESCRIPTION: Process a standard comment.
+ *
+ ******************************************************************************/
+
+static char
+AslDoComment (
+ void)
+{
+ int c;
+ int c1 = 0;
+
+
+ AslInsertLineBuffer ('/');
+ AslInsertLineBuffer ('*');
+
+loop:
+
+ /* Eat chars until end-of-comment */
+
+ while ((c = input()) != '*' && c != EOF)
+ {
+ AslInsertLineBuffer (c);
+ c1 = c;
+ }
+
+ if (c == EOF)
+ {
+ goto EarlyEOF;
+ }
+
+ /*
+ * Check for nested comment -- can help catch cases where a previous
+ * comment was accidently left unterminated
+ */
+ if ((c1 == '/') && (c == '*'))
+ {
+ AslCommonError (ASL_WARNING, ASL_MSG_NESTED_COMMENT,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_InputByteCount, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
+ }
+
+ /* Comment is closed only if the NEXT character is a slash */
+
+ AslInsertLineBuffer (c);
+
+ if ((c1 = input()) != '/' && c1 != EOF)
+ {
+ unput(c1);
+ goto loop;
+ }
+
+ if (c1 == EOF)
+ {
+ goto EarlyEOF;
+ }
+
+ AslInsertLineBuffer (c1);
+ return (TRUE);
+
+
+EarlyEOF:
+ /*
+ * Premature End-Of-File
+ */
+ AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_CurrentLineOffset, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslDoCommentType2
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: none
+ *
+ * DESCRIPTION: Process a new "//" comment.
+ *
+ ******************************************************************************/
+
+static char
+AslDoCommentType2 (
+ void)
+{
+ int c;
+
+
+ AslInsertLineBuffer ('/');
+ AslInsertLineBuffer ('/');
+
+ while ((c = input()) != '\n' && c != EOF)
+ {
+ AslInsertLineBuffer (c);
+ }
+
+ if (c == EOF)
+ {
+ /* End of file is OK, change to newline. Let parser detect EOF later */
+
+ c = '\n';
+ }
+
+ AslInsertLineBuffer (c);
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AslDoStringLiteral
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: none
+ *
+ * DESCRIPTION: Process a string literal (surrounded by quotes)
+ *
+ ******************************************************************************/
+
+static char
+AslDoStringLiteral (
+ void)
+{
+ char *StringBuffer = MsgBuffer;
+ char *EndBuffer = MsgBuffer + ASL_MSG_BUFFER_SIZE;
+ char *CleanString;
+ int StringChar;
+ UINT32 State = ASL_NORMAL_CHAR;
+ UINT32 i = 0;
+ UINT8 Digit;
+ char ConvertBuffer[4];
+
+
+ /*
+ * Eat chars until end-of-literal.
+ * NOTE: Put back the original surrounding quotes into the
+ * source line buffer.
+ */
+ AslInsertLineBuffer ('\"');
+ while ((StringChar = input()) != EOF)
+ {
+ AslInsertLineBuffer (StringChar);
+
+DoCharacter:
+
+ switch (State)
+ {
+ case ASL_NORMAL_CHAR:
+
+ switch (StringChar)
+ {
+ case '\\':
+ /*
+ * Special handling for backslash-escape sequence. We will
+ * toss the backslash and translate the escape char(s).
+ */
+ State = ASL_ESCAPE_SEQUENCE;
+ continue;
+
+ case '\"':
+
+ /* String terminator */
+
+ goto CompletedString;
+ }
+ break;
+
+
+ case ASL_ESCAPE_SEQUENCE:
+
+ State = ASL_NORMAL_CHAR;
+ switch (StringChar)
+ {
+ case 'a':
+ StringChar = 0x07; /* BELL */
+ break;
+
+ case 'b':
+ StringChar = 0x08; /* BACKSPACE */
+ break;
+
+ case 'f':
+ StringChar = 0x0C; /* FORMFEED */
+ break;
+
+ case 'n':
+ StringChar = 0x0A; /* LINEFEED */
+ break;
+
+ case 'r':
+ StringChar = 0x0D; /* CARRIAGE RETURN*/
+ break;
+
+ case 't':
+ StringChar = 0x09; /* HORIZONTAL TAB */
+ break;
+
+ case 'v':
+ StringChar = 0x0B; /* VERTICAL TAB */
+ break;
+
+ case 'x':
+ State = ASL_HEX_CONSTANT;
+ i = 0;
+ continue;
+
+ case '\'': /* Single Quote */
+ case '\"': /* Double Quote */
+ case '\\': /* Backslash */
+ break;
+
+ default:
+
+ /* Check for an octal digit (0-7) */
+
+ if (ACPI_IS_OCTAL_DIGIT (StringChar))
+ {
+ State = ASL_OCTAL_CONSTANT;
+ ConvertBuffer[0] = StringChar;
+ i = 1;
+ continue;
+ }
+
+ /* Unknown escape sequence issue warning, but use the character */
+
+ AslCommonError (ASL_WARNING, ASL_MSG_INVALID_ESCAPE,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_CurrentLineOffset, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
+ break;
+ }
+ break;
+
+
+ case ASL_OCTAL_CONSTANT:
+
+ /* Up to three octal digits allowed */
+
+ if (!ACPI_IS_OCTAL_DIGIT (StringChar) ||
+ (i > 2))
+ {
+ /*
+ * Reached end of the constant. Convert the assembled ASCII
+ * string and resume processing of the next character
+ */
+ ConvertBuffer[i] = 0;
+ Digit = (UINT8) ACPI_STRTOUL (ConvertBuffer, NULL, 8);
+
+ /* Check for NULL or non-ascii character (ignore if so) */
+
+ if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
+ {
+ AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_CurrentLineOffset, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
+ }
+ else
+ {
+ *StringBuffer = (char) Digit;
+ StringBuffer++;
+ if (StringBuffer >= EndBuffer)
+ {
+ goto BufferOverflow;
+ }
+ }
+
+ State = ASL_NORMAL_CHAR;
+ goto DoCharacter;
+ break;
+ }
+
+ /* Append another digit of the constant */
+
+ ConvertBuffer[i] = StringChar;
+ i++;
+ continue;
+
+
+ case ASL_HEX_CONSTANT:
+
+ /* Up to two hex digits allowed */
+
+ if (!ACPI_IS_XDIGIT (StringChar) ||
+ (i > 1))
+ {
+ /*
+ * Reached end of the constant. Convert the assembled ASCII
+ * string and resume processing of the next character
+ */
+ ConvertBuffer[i] = 0;
+ Digit = (UINT8) ACPI_STRTOUL (ConvertBuffer, NULL, 16);
+
+ /* Check for NULL or non-ascii character (ignore if so) */
+
+ if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
+ {
+ AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_CurrentLineOffset, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
+ }
+ else
+ {
+ *StringBuffer = (char) Digit;
+ StringBuffer++;
+ if (StringBuffer >= EndBuffer)
+ {
+ goto BufferOverflow;
+ }
+ }
+
+ State = ASL_NORMAL_CHAR;
+ goto DoCharacter;
+ break;
+ }
+
+ /* Append another digit of the constant */
+
+ ConvertBuffer[i] = StringChar;
+ i++;
+ continue;
+ }
+
+ /* Save the finished character */
+
+ *StringBuffer = StringChar;
+ StringBuffer++;
+ if (StringBuffer >= EndBuffer)
+ {
+ goto BufferOverflow;
+ }
+ }
+
+ /*
+ * Premature End-Of-File
+ */
+ AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_CurrentLineOffset, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
+ return (FALSE);
+
+
+CompletedString:
+ /*
+ * Null terminate the input string and copy string to a new buffer
+ */
+ *StringBuffer = 0;
+
+ CleanString = UtGetStringBuffer (strlen (MsgBuffer) + 1);
+ if (!CleanString)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_CurrentLineOffset, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
+ return (FALSE);
+ }
+
+ ACPI_STRCPY (CleanString, MsgBuffer);
+ AslCompilerlval.s = CleanString;
+ return (TRUE);
+
+
+BufferOverflow:
+
+ /* Literal was too long */
+
+ AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_CurrentLineOffset, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096");
+ return (FALSE);
+}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/aslutils.c
--- a/head/sys/contrib/dev/acpica/compiler/aslutils.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/aslutils.c Wed Jul 25 16:45:04 2012 +0300
@@ -139,7 +139,7 @@
/*******************************************************************************
*
- * FUNCTION: AcpiPsDisplayConstantOpcodes
+ * FUNCTION: UtDisplayConstantOpcodes
*
* PARAMETERS: None
*
@@ -172,11 +172,11 @@
*
* FUNCTION: UtLocalCalloc
*
- * PARAMETERS: Size - Bytes to be allocated
+ * PARAMETERS: Size - Bytes to be allocated
*
- * RETURN: Pointer to the allocated memory. Guaranteed to be valid.
+ * RETURN: Pointer to the allocated memory. Guaranteed to be valid.
*
- * DESCRIPTION: Allocate zero-initialized memory. Aborts the compile on an
+ * DESCRIPTION: Allocate zero-initialized memory. Aborts the compile on an
* allocation failure, on the assumption that nothing more can be
* accomplished.
*
@@ -211,9 +211,9 @@
*
* FUNCTION: UtBeginEvent
*
- * PARAMETERS: Name - Ascii name of this event
+ * PARAMETERS: Name - Ascii name of this event
*
- * RETURN: Event - Event number (integer index)
+ * RETURN: Event number (integer index)
*
* DESCRIPTION: Saves the current time with this event
*
@@ -244,7 +244,7 @@
*
* FUNCTION: UtEndEvent
*
- * PARAMETERS: Event - Event number (integer index)
+ * PARAMETERS: Event - Event number (integer index)
*
* RETURN: None
*
@@ -254,7 +254,7 @@
void
UtEndEvent (
- UINT8 Event)
+ UINT8 Event)
{
if (Event >= ASL_NUM_EVENTS)
@@ -272,7 +272,7 @@
*
* FUNCTION: UtHexCharToValue
*
- * PARAMETERS: HexChar - Hex character in Ascii
+ * PARAMETERS: HexChar - Hex character in Ascii
*
* RETURN: The binary value of the hex character
*
@@ -303,12 +303,13 @@
*
* FUNCTION: UtConvertByteToHex
*
- * PARAMETERS: RawByte - Binary data
- * Buffer - Pointer to where the hex bytes will be stored
+ * PARAMETERS: RawByte - Binary data
+ * Buffer - Pointer to where the hex bytes will be
+ * stored
*
* RETURN: Ascii hex byte is stored in Buffer.
*
- * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed
+ * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed
* with "0x"
*
******************************************************************************/
@@ -331,12 +332,13 @@
*
* FUNCTION: UtConvertByteToAsmHex
*
- * PARAMETERS: RawByte - Binary data
- * Buffer - Pointer to where the hex bytes will be stored
+ * PARAMETERS: RawByte - Binary data
+ * Buffer - Pointer to where the hex bytes will be
+ * stored
*
* RETURN: Ascii hex byte is stored in Buffer.
*
- * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed
+ * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed
* with "0x"
*
******************************************************************************/
@@ -358,13 +360,13 @@
*
* FUNCTION: DbgPrint
*
- * PARAMETERS: Type - Type of output
- * Fmt - Printf format string
- * ... - variable printf list
+ * PARAMETERS: Type - Type of output
+ * Fmt - Printf format string
+ * ... - variable printf list
*
* RETURN: None
*
- * DESCRIPTION: Conditional print statement. Prints to stderr only if the
+ * DESCRIPTION: Conditional print statement. Prints to stderr only if the
* debug flag is set.
*
******************************************************************************/
@@ -438,7 +440,7 @@
*
* FUNCTION: UtSetParseOpName
*
- * PARAMETERS: Op
+ * PARAMETERS: Op - Parse op to be named.
*
* RETURN: None
*
@@ -460,7 +462,7 @@
*
* FUNCTION: UtDisplaySummary
*
- * PARAMETERS: FileID - ID of outpout file
+ * PARAMETERS: FileID - ID of outpout file
*
* RETURN: None
*
@@ -571,11 +573,11 @@
/*******************************************************************************
*
- * FUNCTION: UtDisplaySummary
+ * FUNCTION: UtCheckIntegerRange
*
- * PARAMETERS: Op - Integer parse node
- * LowValue - Smallest allowed value
- * HighValue - Largest allowed value
+ * PARAMETERS: Op - Integer parse node
+ * LowValue - Smallest allowed value
+ * HighValue - Largest allowed value
*
* RETURN: Op if OK, otherwise NULL
*
@@ -626,11 +628,11 @@
*
* FUNCTION: UtGetStringBuffer
*
- * PARAMETERS: Length - Size of buffer requested
+ * PARAMETERS: Length - Size of buffer requested
*
- * RETURN: Pointer to the buffer. Aborts on allocation failure
+ * RETURN: Pointer to the buffer. Aborts on allocation failure
*
- * DESCRIPTION: Allocate a string buffer. Bypass the local
+ * DESCRIPTION: Allocate a string buffer. Bypass the local
* dynamic memory manager for performance reasons (This has a
* major impact on the speed of the compiler.)
*
@@ -661,8 +663,8 @@
*
* FUNCTION: UtInternalizeName
*
- * PARAMETERS: ExternalName - Name to convert
- * ConvertedName - Where the converted name is returned
+ * PARAMETERS: ExternalName - Name to convert
+ * ConvertedName - Where the converted name is returned
*
* RETURN: Status
*
@@ -714,8 +716,8 @@
*
* FUNCTION: UtPadNameWithUnderscores
*
- * PARAMETERS: NameSeg - Input nameseg
- * PaddedNameSeg - Output padded nameseg
+ * PARAMETERS: NameSeg - Input nameseg
+ * PaddedNameSeg - Output padded nameseg
*
* RETURN: Padded nameseg.
*
@@ -752,8 +754,8 @@
*
* FUNCTION: UtAttachNameseg
*
- * PARAMETERS: Op - Parent parse node
- * Name - Full ExternalName
+ * PARAMETERS: Op - Parent parse node
+ * Name - Full ExternalName
*
* RETURN: None; Sets the NameSeg field in parent node
*
@@ -809,12 +811,12 @@
*
* FUNCTION: UtAttachNamepathToOwner
*
- * PARAMETERS: Op - Parent parse node
- * NameOp - Node that contains the name
+ * PARAMETERS: Op - Parent parse node
+ * NameOp - Node that contains the name
*
* RETURN: Sets the ExternalName and Namepath in the parent node
*
- * DESCRIPTION: Store the name in two forms in the parent node: The original
+ * DESCRIPTION: Store the name in two forms in the parent node: The original
* (external) name, and the internalized name that is used within
* the ACPI namespace manager.
*
@@ -854,11 +856,11 @@
*
* FUNCTION: UtDoConstant
*
- * PARAMETERS: String - Hex, Octal, or Decimal string
+ * PARAMETERS: String - Hex, Octal, or Decimal string
*
* RETURN: Converted Integer
*
- * DESCRIPTION: Convert a string to an integer. With error checking.
+ * DESCRIPTION: Convert a string to an integer, with error checking.
*
******************************************************************************/
@@ -889,10 +891,10 @@
*
* FUNCTION: UtStrtoul64
*
- * PARAMETERS: String - Null terminated string
- * Terminater - Where a pointer to the terminating byte is
- * returned
- * Base - Radix of the string
+ * PARAMETERS: String - Null terminated string
+ * Terminater - Where a pointer to the terminating byte
+ * is returned
+ * Base - Radix of the string
*
* RETURN: Converted value
*
@@ -1072,5 +1074,3 @@
return (Status);
}
-
-
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/dtio.c
--- a/head/sys/contrib/dev/acpica/compiler/dtio.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/dtio.c Wed Jul 25 16:45:04 2012 +0300
@@ -89,6 +89,7 @@
#define DT_SLASH_SLASH_COMMENT 4
#define DT_END_COMMENT 5
#define DT_MERGE_LINES 6
+#define DT_ESCAPE_SEQUENCE 7
static UINT32 Gbl_NextLineOffset;
@@ -412,6 +413,7 @@
BOOLEAN LineNotAllBlanks = FALSE;
UINT32 State = DT_NORMAL_TEXT;
UINT32 CurrentLineOffset;
+ UINT32 BeyondBufferCount;
UINT32 i;
char c;
@@ -425,7 +427,6 @@
{
case DT_START_QUOTED_STRING:
case DT_SLASH_ASTERISK_COMMENT:
- case DT_SLASH_SLASH_COMMENT:
AcpiOsPrintf ("**** EOF within comment/string %u\n", State);
break;
@@ -434,7 +435,22 @@
break;
}
- return (ASL_EOF);
+ /* Standalone EOF is OK */
+
+ if (i == 0)
+ {
+ return (ASL_EOF);
+ }
+
+ /*
+ * Received an EOF in the middle of a line. Terminate the
+ * line with a newline. The next call to this function will
+ * return a standalone EOF. Thus, the upper parsing software
+ * never has to deal with an EOF within a valid line (or
+ * the last line does not get tossed on the floor.)
+ */
+ c = '\n';
+ State = DT_NORMAL_TEXT;
}
switch (State)
@@ -503,12 +519,36 @@
Gbl_CurrentLineBuffer[i] = c;
i++;
- if (c == '"')
+ switch (c)
{
+ case '"':
State = DT_NORMAL_TEXT;
+ break;
+
+ case '\\':
+ State = DT_ESCAPE_SEQUENCE;
+ break;
+
+ case '\n':
+ AcpiOsPrintf ("ERROR at line %u: Unterminated quoted string\n",
+ Gbl_CurrentLineNumber++);
+ State = DT_NORMAL_TEXT;
+ break;
+
+ default: /* Get next character */
+ break;
}
break;
+ case DT_ESCAPE_SEQUENCE:
+
+ /* Just copy the escaped character. TBD: sufficient for table compiler? */
+
+ Gbl_CurrentLineBuffer[i] = c;
+ i++;
+ State = DT_START_QUOTED_STRING;
+ break;
+
case DT_START_COMMENT:
/* Open comment if this character is an asterisk or slash */
@@ -629,7 +669,19 @@
}
}
- printf ("ERROR - Input line is too long (max %u)\n", ASL_LINE_BUFFER_SIZE);
+ /* Line is too long for internal buffer. Determine actual length */
+
+ BeyondBufferCount = 1;
+ c = (char) getc (Handle);
+ while (c != '\n')
+ {
+ c = (char) getc (Handle);
+ BeyondBufferCount++;
+ }
+
+ printf ("ERROR - At %u: Input line (%u bytes) is too long (max %u)\n",
+ Gbl_CurrentLineNumber++, ASL_LINE_BUFFER_SIZE + BeyondBufferCount,
+ ASL_LINE_BUFFER_SIZE);
return (ASL_EOF);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/dttemplate.c
--- a/head/sys/contrib/dev/acpica/compiler/dttemplate.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/dttemplate.c Wed Jul 25 16:45:04 2012 +0300
@@ -226,7 +226,7 @@
}
/*
- * Create the "special ACPI tables:
+ * Create the special ACPI tables:
* 1) DSDT/SSDT are AML tables, not data tables
* 2) FACS and RSDP have non-standard headers
*/
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/preprocess.h
--- a/head/sys/contrib/dev/acpica/compiler/preprocess.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/preprocess.h Wed Jul 25 16:45:04 2012 +0300
@@ -124,13 +124,6 @@
} PR_FILE_NODE;
-typedef struct pr_line_mapping
-{
- UINT32 *Map;
- struct pr_line_mapping *Next;
-
-} PR_LINE_MAPPING;
-
/*
* Globals
@@ -140,7 +133,6 @@
PR_EXTERN char Gbl_MacroTokenBuffer[ASL_LINE_BUFFER_SIZE];
PR_EXTERN char Gbl_ExpressionTokenBuffer[ASL_LINE_BUFFER_SIZE];
-PR_EXTERN PR_LINE_MAPPING *Gbl_MapBlockHead;
PR_EXTERN PR_FILE_NODE *Gbl_InputFileList;
PR_EXTERN PR_DEFINE_INFO PR_INIT_GLOBAL (*Gbl_DefineList, NULL);
PR_EXTERN UINT32 Gbl_PreprocessorLineNumber;
@@ -167,10 +159,6 @@
PrDoPreprocess (
void);
-UINT32
-PrGetLineNumber (
- UINT32 PreprocessorLineNumber);
-
UINT64
PrIsDefined (
char *Identifier);
@@ -252,11 +240,6 @@
char **Next);
void
-PrSetLineNumber (
- UINT32 OriginalLineNumber,
- UINT32 NewLineNumber);
-
-void
PrError (
UINT8 Level,
UINT8 MessageId,
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/prscan.c
--- a/head/sys/contrib/dev/acpica/compiler/prscan.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/prscan.c Wed Jul 25 16:45:04 2012 +0300
@@ -161,9 +161,6 @@
Gbl_CurrentLineNumber = 0;
Gbl_PreprocessorLineNumber = 1;
Gbl_PreprocessorError = FALSE;
-
- Gbl_MapBlockHead = UtLocalCalloc (sizeof (PR_LINE_MAPPING));
- Gbl_MapBlockHead->Map = UtLocalCalloc (PR_LINES_PER_BLOCK * sizeof (UINT32));
}
@@ -186,7 +183,6 @@
void)
{
PR_DEFINE_INFO *DefineInfo;
- PR_LINE_MAPPING *MapInfo;
/*
@@ -202,17 +198,6 @@
ACPI_FREE (DefineInfo->Identifier);
ACPI_FREE (DefineInfo);
}
-
- /* Clear the line number mappings */
-
- while (Gbl_MapBlockHead)
- {
- MapInfo = Gbl_MapBlockHead;
- Gbl_MapBlockHead = MapInfo->Next;
-
- ACPI_FREE (MapInfo->Map);
- ACPI_FREE (MapInfo);
- }
}
@@ -393,8 +378,6 @@
Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next);
}
- /* Write the possibly modified line to the .i file*/
-
#if 0
/* Line prefix */
FlPrintFile (ASL_FILE_PREPROCESSOR, "/* %14s %.5u i:%.5u */ ",
@@ -402,11 +385,27 @@
Gbl_CurrentLineNumber, Gbl_PreprocessorLineNumber);
#endif
+ /*
+ * Emit a #line directive if necessary, to keep the line numbers in
+ * the (.i) file synchronized with the original source code file, so
+ * that the correct line number appears in any error messages
+ * generated by the actual compiler.
+ */
+ if (Gbl_CurrentLineNumber > (Gbl_PreviousLineNumber + 1))
+ {
+ FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u\n",
+ Gbl_CurrentLineNumber);
+ }
+
+ Gbl_PreviousLineNumber = Gbl_CurrentLineNumber;
+ Gbl_PreprocessorLineNumber++;
+
+ /*
+ * Now we can write the possibly modified source line to the
+ * preprocessor (.i) file
+ */
FlWriteFile (ASL_FILE_PREPROCESSOR, Gbl_CurrentLineBuffer,
strlen (Gbl_CurrentLineBuffer));
-
- PrSetLineNumber (Gbl_CurrentLineNumber, Gbl_PreprocessorLineNumber);
- Gbl_PreprocessorLineNumber++;
}
}
@@ -546,8 +545,9 @@
if (*(&Gbl_CurrentLineBuffer[TokenOffset]) == '(')
{
#ifndef MACROS_SUPPORTED
- AcpiOsPrintf ("#define macros not supported\n");
- goto SyntaxError;
+ AcpiOsPrintf ("%s ERROR - line %u: #define macros are not supported yet\n",
+ Gbl_CurrentLineBuffer, Gbl_CurrentLineNumber);
+ exit(1);
#else
PrAddMacro (Token, Next);
#endif
@@ -654,12 +654,37 @@
}
DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
- "Start #include file %s\n", Gbl_CurrentLineNumber,
+ "Start #include file \"%s\"\n", Gbl_CurrentLineNumber,
Token, Gbl_CurrentLineNumber);
PrOpenIncludeFile (Token);
break;
+ case PR_DIRECTIVE_LINE:
+ TokenOffset = Token - Gbl_MainTokenBuffer;
+
+ Status = PrResolveIntegerExpression (
+ &Gbl_CurrentLineBuffer[TokenOffset-1], &Value);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
+ "User #line invocation %s\n", Gbl_CurrentLineNumber,
+ Token);
+
+ /* Update local line numbers */
+
+ Gbl_CurrentLineNumber = (UINT32) Value;
+ Gbl_PreviousLineNumber = 0;
+
+ /* Emit #line into the preprocessor file */
+
+ FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\"\n",
+ Gbl_CurrentLineNumber, Gbl_Files[ASL_FILE_INPUT].Filename);
+ break;
+
case PR_DIRECTIVE_PRAGMA:
/* Only "#pragma message" supported at this time */
@@ -692,8 +717,6 @@
THIS_TOKEN_OFFSET (Token));
break;
- case PR_DIRECTIVE_LINE:
- /* TBD: set line number -- or, do this in main compiler */
default:
/* Should never get here */
DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/compiler/prutils.c
--- a/head/sys/contrib/dev/acpica/compiler/prutils.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/compiler/prutils.c Wed Jul 25 16:45:04 2012 +0300
@@ -49,100 +49,6 @@
ACPI_MODULE_NAME ("prutils")
-/*******************************************************************************
- *
- * FUNCTION: PrSetLineNumber
- *
- * PARAMETERS: OriginalLineNumber - Line number in original source file,
- * or include file
- * PreprocessorLineNumber - Line number in the preprocessed file
- *
- * RETURN: None
- *
- * DESCRIPTION: Insert this mapping into the mapping data structure, for use
- * in possible error/warning messages.
- *
- * Line number mapping functions.
- * For error messages, we need to keep track of the line number in the
- * original file, versus the preprocessed (.i) file.
- *
- ******************************************************************************/
-
-void
-PrSetLineNumber (
- UINT32 OriginalLineNumber,
- UINT32 PreprocessorLineNumber)
-{
- UINT32 Entry;
- PR_LINE_MAPPING *Block;
- UINT32 Index;
- UINT32 i;
-
-
- Entry = PreprocessorLineNumber / PR_LINES_PER_BLOCK;
- Index = PreprocessorLineNumber % PR_LINES_PER_BLOCK;
- Block = Gbl_MapBlockHead;
-
- for (i = 0; i < Entry; i++)
- {
- /* Allocate new mapping blocks as necessary */
-
- if (!Block->Next)
- {
- Block->Next = UtLocalCalloc (sizeof (PR_LINE_MAPPING));
- Block->Next->Map = UtLocalCalloc (PR_LINES_PER_BLOCK * sizeof (UINT32));
- }
-
- Block = Block->Next;
- }
-
- Block->Map[Index] = OriginalLineNumber;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: PrGetLineNumber
- *
- * PARAMETERS: PreprocessorLineNumber - Line number in the preprocessed file
- * (or, the "logical line number)
- *
- * RETURN: The line number in the original source file or include file.
- *
- * DESCRIPTION: Return the mapped value of a line number in the preprocessed
- * source file to the actual line number in the original source
- * file.
- *
- ******************************************************************************/
-
-UINT32
-PrGetLineNumber (
- UINT32 PreprocessorLineNumber)
-{
- UINT32 Entry;
- PR_LINE_MAPPING *Block;
- UINT32 Index;
- UINT32 i;
-
-
- Entry = PreprocessorLineNumber / PR_LINES_PER_BLOCK;
- Index = PreprocessorLineNumber % PR_LINES_PER_BLOCK;
- Block = Gbl_MapBlockHead;
-
- for (i = 0; i < Entry; i++)
- {
- Block = Block->Next;
- if (!Block)
- {
- /* Bad error, should not happen */
- return (0);
- }
- }
-
- return (Block->Map[Index]);
-}
-
-
/******************************************************************************
*
* FUNCTION: PrGetNextToken
@@ -340,13 +246,11 @@
ASL_INCLUDE_DIR *NextDir;
- /*
- * start the actual include file on the next line
- */
+ /* Start the actual include file on the next line */
+
Gbl_CurrentLineOffset++;
/* Attempt to open the include file */
-
/* If the file specifies an absolute path, just open it */
if ((Filename[0] == '/') ||
@@ -424,13 +328,10 @@
/* Build the full pathname to the file */
- Pathname = ACPI_ALLOCATE (strlen (PrefixDir) + strlen (Filename) + 1);
+ Pathname = FlMergePathnames (PrefixDir, Filename);
- strcpy (Pathname, PrefixDir);
- strcat (Pathname, Filename);
-
- DbgPrint (ASL_PARSE_OUTPUT, "\n" PR_PREFIX_ID
- "Opening include file: path %s\n",
+ DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
+ "Include: Opening file - \"%s\"\n",
Gbl_CurrentLineNumber, Pathname);
/* Attempt to open the file, push if successful */
@@ -486,14 +387,20 @@
Gbl_InputFileList = Fnode;
DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID
- "Push InputFile Stack, returning %p\n\n",
+ "Push InputFile Stack: handle %p\n\n",
Gbl_CurrentLineNumber, InputFile);
/* Reset the global line count and filename */
Gbl_Files[ASL_FILE_INPUT].Filename = Filename;
Gbl_Files[ASL_FILE_INPUT].Handle = InputFile;
- Gbl_CurrentLineNumber = 1;
+ Gbl_PreviousLineNumber = 0;
+ Gbl_CurrentLineNumber = 0;
+
+ /* Emit a new #line directive for the include file */
+
+ FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\"\n",
+ 1, Filename);
}
@@ -542,6 +449,12 @@
Gbl_Files[ASL_FILE_INPUT].Filename = Fnode->Filename;
Gbl_Files[ASL_FILE_INPUT].Handle = Fnode->File;
Gbl_CurrentLineNumber = Fnode->CurrentLineNumber;
+ Gbl_PreviousLineNumber = 0;
+
+ /* Emit a new #line directive after the include file */
+
+ FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\"\n",
+ Gbl_CurrentLineNumber + 1, Fnode->Filename);
/* All done with this node */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/debugger/dbcmds.c
--- a/head/sys/contrib/dev/acpica/components/debugger/dbcmds.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/debugger/dbcmds.c Wed Jul 25 16:45:04 2012 +0300
@@ -254,12 +254,53 @@
ACPI_STATUS Status;
+ /* Header */
+
+ AcpiOsPrintf ("Idx ID Status Type Sig Address Len Header\n");
+
/* Walk the entire root table list */
for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
{
TableDesc = &AcpiGbl_RootTableList.Tables[i];
- AcpiOsPrintf ("%u ", i);
+
+ /* Index and Table ID */
+
+ AcpiOsPrintf ("%3u %.2u ", i, TableDesc->OwnerId);
+
+ /* Decode the table flags */
+
+ if (!(TableDesc->Flags & ACPI_TABLE_IS_LOADED))
+ {
+ AcpiOsPrintf ("NotLoaded ");
+ }
+ else
+ {
+ AcpiOsPrintf (" Loaded ");
+ }
+
+ switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
+ {
+ case ACPI_TABLE_ORIGIN_UNKNOWN:
+ AcpiOsPrintf ("Unknown ");
+ break;
+
+ case ACPI_TABLE_ORIGIN_MAPPED:
+ AcpiOsPrintf ("Mapped ");
+ break;
+
+ case ACPI_TABLE_ORIGIN_ALLOCATED:
+ AcpiOsPrintf ("Allocated ");
+ break;
+
+ case ACPI_TABLE_ORIGIN_OVERRIDE:
+ AcpiOsPrintf ("Override ");
+ break;
+
+ default:
+ AcpiOsPrintf ("INVALID ");
+ break;
+ }
/* Make sure that the table is mapped */
@@ -290,55 +331,45 @@
*
* FUNCTION: AcpiDbUnloadAcpiTable
*
- * PARAMETERS: TableArg - Name of the table to be unloaded
- * InstanceArg - Which instance of the table to unload (if
- * there are multiple tables of the same type)
+ * PARAMETERS: ObjectName - Namespace pathname for an object that
+ * is owned by the table to be unloaded
*
- * RETURN: Nonde
+ * RETURN: None
*
- * DESCRIPTION: Unload an ACPI table.
- * Instance is not implemented
+ * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned
+ * by the table.
*
******************************************************************************/
void
AcpiDbUnloadAcpiTable (
- char *TableArg,
- char *InstanceArg)
+ char *ObjectName)
{
-/* TBD: Need to reimplement for new data structures */
-
-#if 0
- UINT32 i;
+ ACPI_NAMESPACE_NODE *Node;
ACPI_STATUS Status;
- /* Search all tables for the target type */
+ /* Translate name to an Named object */
- for (i = 0; i < (ACPI_TABLE_ID_MAX+1); i++)
+ Node = AcpiDbConvertToNode (ObjectName);
+ if (!Node)
{
- if (!ACPI_STRNCMP (TableArg, AcpiGbl_TableData[i].Signature,
- AcpiGbl_TableData[i].SigLength))
- {
- /* Found the table, unload it */
-
- Status = AcpiUnloadTable (i);
- if (ACPI_SUCCESS (Status))
- {
- AcpiOsPrintf ("[%s] unloaded and uninstalled\n", TableArg);
- }
- else
- {
- AcpiOsPrintf ("%s, while unloading [%s]\n",
- AcpiFormatException (Status), TableArg);
- }
-
- return;
- }
+ AcpiOsPrintf ("Could not find [%s] in namespace\n",
+ ObjectName);
+ return;
}
- AcpiOsPrintf ("Unknown table type [%s]\n", TableArg);
-#endif
+ Status = AcpiUnloadParentTable (ACPI_CAST_PTR (ACPI_HANDLE, Node));
+ if (ACPI_SUCCESS (Status))
+ {
+ AcpiOsPrintf ("Parent of [%s] (%p) unloaded and uninstalled\n",
+ ObjectName, Node);
+ }
+ else
+ {
+ AcpiOsPrintf ("%s, while unloading parent table of [%s]\n",
+ AcpiFormatException (Status), ObjectName);
+ }
}
@@ -373,25 +404,20 @@
return;
}
- /* Decode Named object type */
+ /* Dispatch the notify if legal */
- switch (Node->Type)
+ if (AcpiEvIsNotifyObject (Node))
{
- case ACPI_TYPE_DEVICE:
- case ACPI_TYPE_THERMAL:
-
- /* Send the notify */
-
Status = AcpiEvQueueNotifyRequest (Node, Value);
if (ACPI_FAILURE (Status))
{
AcpiOsPrintf ("Could not queue notify\n");
}
- break;
-
- default:
- AcpiOsPrintf ("Named object is not a device or a thermal object\n");
- break;
+ }
+ else
+ {
+ AcpiOsPrintf ("Named object [%4.4s] Type %s, must be Device/Thermal/Processor type\n",
+ AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type));
}
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/debugger/dbdisply.c
--- a/head/sys/contrib/dev/acpica/components/debugger/dbdisply.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/debugger/dbdisply.c Wed Jul 25 16:45:04 2012 +0300
@@ -107,8 +107,8 @@
static ACPI_HANDLER_INFO AcpiGbl_HandlerList[] =
{
- {&AcpiGbl_SystemNotify.Handler, "System Notifications"},
- {&AcpiGbl_DeviceNotify.Handler, "Device Notifications"},
+ {&AcpiGbl_GlobalNotify[0].Handler, "System Notifications"},
+ {&AcpiGbl_GlobalNotify[1].Handler, "Device Notifications"},
{&AcpiGbl_TableHandler, "ACPI Table Events"},
{&AcpiGbl_ExceptionHandler, "Control Method Exceptions"},
{&AcpiGbl_InterfaceHandler, "OSI Invocations"}
@@ -792,10 +792,12 @@
ACPI_GPE_EVENT_INFO *GpeEventInfo;
ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
char *GpeType;
+ ACPI_GPE_NOTIFY_INFO *Notify;
UINT32 GpeIndex;
UINT32 Block = 0;
UINT32 i;
UINT32 j;
+ UINT32 Count;
char Buffer[80];
ACPI_BUFFER RetBuf;
ACPI_STATUS Status;
@@ -916,7 +918,14 @@
AcpiOsPrintf ("Handler");
break;
case ACPI_GPE_DISPATCH_NOTIFY:
- AcpiOsPrintf ("Notify");
+ Count = 0;
+ Notify = GpeEventInfo->Dispatch.NotifyList;
+ while (Notify)
+ {
+ Count++;
+ Notify = Notify->Next;
+ }
+ AcpiOsPrintf ("Implicit Notify on %u devices", Count);
break;
default:
AcpiOsPrintf ("UNKNOWN: %X",
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/debugger/dbexec.c
--- a/head/sys/contrib/dev/acpica/components/debugger/dbexec.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/debugger/dbexec.c Wed Jul 25 16:45:04 2012 +0300
@@ -872,8 +872,8 @@
if (Info->InitArgs)
{
- AcpiDbUInt32ToHexString (Info->NumCreated, Info->IndexOfThreadStr);
- AcpiDbUInt32ToHexString ((UINT32) AcpiOsGetThreadId (), Info->IdOfThreadStr);
+ AcpiDbUint32ToHexString (Info->NumCreated, Info->IndexOfThreadStr);
+ AcpiDbUint32ToHexString ((UINT32) AcpiOsGetThreadId (), Info->IdOfThreadStr);
}
if (Info->Threads && (Info->NumCreated < Info->NumThreads))
@@ -1063,7 +1063,7 @@
AcpiGbl_DbMethodInfo.ArgTypes[1] = ACPI_TYPE_INTEGER;
AcpiGbl_DbMethodInfo.ArgTypes[2] = ACPI_TYPE_INTEGER;
- AcpiDbUInt32ToHexString (NumThreads, AcpiGbl_DbMethodInfo.NumThreadsStr);
+ AcpiDbUint32ToHexString (NumThreads, AcpiGbl_DbMethodInfo.NumThreadsStr);
AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/debugger/dbfileio.c
--- a/head/sys/contrib/dev/acpica/components/debugger/dbfileio.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/debugger/dbfileio.c Wed Jul 25 16:45:04 2012 +0300
@@ -51,6 +51,10 @@
#include <contrib/dev/acpica/include/actables.h>
#endif
+#ifdef ACPI_ASL_COMPILER
+#include <contrib/dev/acpica/compiler/aslcompiler.h>
+#endif
+
#if (defined ACPI_DEBUGGER || defined ACPI_DISASSEMBLER)
#define _COMPONENT ACPI_CA_DEBUGGER
@@ -309,6 +313,15 @@
AcpiOsPrintf (
"TableHeader length [0x%X] greater than the input file size [0x%X]\n",
TableHeader.Length, FileSize);
+
+#ifdef ACPI_ASL_COMPILER
+ Status = FlCheckForAscii (fp, NULL, FALSE);
+ if (ACPI_SUCCESS (Status))
+ {
+ AcpiOsPrintf ("File appears to be ASCII only, must be binary\n",
+ TableHeader.Length, FileSize);
+ }
+#endif
return (AE_BAD_HEADER);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/debugger/dbinput.c
--- a/head/sys/contrib/dev/acpica/components/debugger/dbinput.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/debugger/dbinput.c Wed Jul 25 16:45:04 2012 +0300
@@ -250,7 +250,7 @@
AcpiOsPrintf (" Stack Display CPU stack usage\n");
AcpiOsPrintf (" Tables Info about current ACPI table(s)\n");
AcpiOsPrintf (" Tables Display info about loaded ACPI tables\n");
- AcpiOsPrintf (" Unload <TableSig> [Instance] Unload an ACPI table\n");
+ AcpiOsPrintf (" Unload <Namepath> Unload an ACPI table via namespace object\n");
AcpiOsPrintf (" ! <CommandNumber> Execute command from history buffer\n");
AcpiOsPrintf (" !! Execute last command again\n");
@@ -894,7 +894,7 @@
break;
case CMD_UNLOAD:
- AcpiDbUnloadAcpiTable (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
+ AcpiDbUnloadAcpiTable (AcpiGbl_DbArgs[1]);
break;
case CMD_EXIT:
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/debugger/dbstats.c
--- a/head/sys/contrib/dev/acpica/components/debugger/dbstats.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/debugger/dbstats.c Wed Jul 25 16:45:04 2012 +0300
@@ -227,8 +227,8 @@
case ACPI_TYPE_DEVICE:
- AcpiDbEnumerateObject (ObjDesc->Device.SystemNotify);
- AcpiDbEnumerateObject (ObjDesc->Device.DeviceNotify);
+ AcpiDbEnumerateObject (ObjDesc->Device.NotifyList[0]);
+ AcpiDbEnumerateObject (ObjDesc->Device.NotifyList[1]);
AcpiDbEnumerateObject (ObjDesc->Device.Handler);
break;
@@ -248,21 +248,21 @@
case ACPI_TYPE_POWER:
- AcpiDbEnumerateObject (ObjDesc->PowerResource.SystemNotify);
- AcpiDbEnumerateObject (ObjDesc->PowerResource.DeviceNotify);
+ AcpiDbEnumerateObject (ObjDesc->PowerResource.NotifyList[0]);
+ AcpiDbEnumerateObject (ObjDesc->PowerResource.NotifyList[1]);
break;
case ACPI_TYPE_PROCESSOR:
- AcpiDbEnumerateObject (ObjDesc->Processor.SystemNotify);
- AcpiDbEnumerateObject (ObjDesc->Processor.DeviceNotify);
+ AcpiDbEnumerateObject (ObjDesc->Processor.NotifyList[0]);
+ AcpiDbEnumerateObject (ObjDesc->Processor.NotifyList[1]);
AcpiDbEnumerateObject (ObjDesc->Processor.Handler);
break;
case ACPI_TYPE_THERMAL:
- AcpiDbEnumerateObject (ObjDesc->ThermalZone.SystemNotify);
- AcpiDbEnumerateObject (ObjDesc->ThermalZone.DeviceNotify);
+ AcpiDbEnumerateObject (ObjDesc->ThermalZone.NotifyList[0]);
+ AcpiDbEnumerateObject (ObjDesc->ThermalZone.NotifyList[1]);
AcpiDbEnumerateObject (ObjDesc->ThermalZone.Handler);
break;
@@ -522,6 +522,18 @@
AcpiOsPrintf ("NamespaceNode %3d\n", sizeof (ACPI_NAMESPACE_NODE));
AcpiOsPrintf ("AcpiObject %3d\n", sizeof (ACPI_OBJECT));
+ AcpiOsPrintf ("\n");
+
+ AcpiOsPrintf ("Generic State %3d\n", sizeof (ACPI_GENERIC_STATE));
+ AcpiOsPrintf ("Common State %3d\n", sizeof (ACPI_COMMON_STATE));
+ AcpiOsPrintf ("Control State %3d\n", sizeof (ACPI_CONTROL_STATE));
+ AcpiOsPrintf ("Update State %3d\n", sizeof (ACPI_UPDATE_STATE));
+ AcpiOsPrintf ("Scope State %3d\n", sizeof (ACPI_SCOPE_STATE));
+ AcpiOsPrintf ("Parse Scope %3d\n", sizeof (ACPI_PSCOPE_STATE));
+ AcpiOsPrintf ("Package State %3d\n", sizeof (ACPI_PKG_STATE));
+ AcpiOsPrintf ("Thread State %3d\n", sizeof (ACPI_THREAD_STATE));
+ AcpiOsPrintf ("Result Values %3d\n", sizeof (ACPI_RESULT_VALUES));
+ AcpiOsPrintf ("Notify Info %3d\n", sizeof (ACPI_NOTIFY_INFO));
break;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/debugger/dbutils.c
--- a/head/sys/contrib/dev/acpica/components/debugger/dbutils.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/debugger/dbutils.c Wed Jul 25 16:45:04 2012 +0300
@@ -190,10 +190,7 @@
case ACPI_TYPE_STRING:
AcpiOsPrintf ("[String] Length %.2X = ", ObjDesc->String.Length);
- for (i = 0; i < ObjDesc->String.Length; i++)
- {
- AcpiOsPrintf ("%c", ObjDesc->String.Pointer[i]);
- }
+ AcpiUtPrintString (ObjDesc->String.Pointer, ACPI_UINT8_MAX);
AcpiOsPrintf ("\n");
break;
@@ -363,7 +360,7 @@
/*******************************************************************************
*
- * FUNCTION: AcpiDbUInt32ToHexString
+ * FUNCTION: AcpiDbUint32ToHexString
*
* PARAMETERS: Value - The value to be converted to string
* Buffer - Buffer for result (not less than 11 bytes)
@@ -378,7 +375,7 @@
******************************************************************************/
void
-AcpiDbUInt32ToHexString (
+AcpiDbUint32ToHexString (
UINT32 Value,
char *Buffer)
{
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/disassembler/dmopcode.c
--- a/head/sys/contrib/dev/acpica/components/disassembler/dmopcode.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/disassembler/dmopcode.c Wed Jul 25 16:45:04 2012 +0300
@@ -46,6 +46,7 @@
#include <contrib/dev/acpica/include/acparser.h>
#include <contrib/dev/acpica/include/amlcode.h>
#include <contrib/dev/acpica/include/acdisasm.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
#ifdef ACPI_DISASSEMBLER
@@ -61,6 +62,218 @@
/*******************************************************************************
*
+ * FUNCTION: AcpiDmPredefinedDescription
+ *
+ * PARAMETERS: Op - Name() parse object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit a description comment for a predefined ACPI name.
+ * Used for iASL compiler only.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmPredefinedDescription (
+ ACPI_PARSE_OBJECT *Op)
+{
+#ifdef ACPI_ASL_COMPILER
+ const AH_PREDEFINED_NAME *Info;
+ char *NameString;
+ int LastCharIsDigit;
+ int LastCharsAreHex;
+
+
+ if (!Op)
+ {
+ return;
+ }
+
+ /* Ensure that the comment field is emitted only once */
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEF_CHECKED)
+ {
+ return;
+ }
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEF_CHECKED;
+
+ /* Predefined name must start with an underscore */
+
+ NameString = ACPI_CAST_PTR (char, &Op->Named.Name);
+ if (NameString[0] != '_')
+ {
+ return;
+ }
+
+ /*
+ * Check for the special ACPI names:
+ * _ACd, _ALd, _EJd, _Exx, _Lxx, _Qxx, _Wxx, _T_a
+ * (where d=decimal_digit, x=hex_digit, a=anything)
+ *
+ * Convert these to the generic name for table lookup.
+ * Note: NameString is guaranteed to be upper case here.
+ */
+ LastCharIsDigit =
+ (ACPI_IS_DIGIT (NameString[3])); /* d */
+ LastCharsAreHex =
+ (ACPI_IS_XDIGIT (NameString[2]) && /* xx */
+ ACPI_IS_XDIGIT (NameString[3]));
+
+ switch (NameString[1])
+ {
+ case 'A':
+ if ((NameString[2] == 'C') && (LastCharIsDigit))
+ {
+ NameString = "_ACx";
+ }
+ else if ((NameString[2] == 'L') && (LastCharIsDigit))
+ {
+ NameString = "_ALx";
+ }
+ break;
+
+ case 'E':
+ if ((NameString[2] == 'J') && (LastCharIsDigit))
+ {
+ NameString = "_EJx";
+ }
+ else if (LastCharsAreHex)
+ {
+ NameString = "_Exx";
+ }
+ break;
+
+ case 'L':
+ if (LastCharsAreHex)
+ {
+ NameString = "_Lxx";
+ }
+ break;
+
+ case 'Q':
+ if (LastCharsAreHex)
+ {
+ NameString = "_Qxx";
+ }
+ break;
+
+ case 'T':
+ if (NameString[2] == '_')
+ {
+ NameString = "_T_x";
+ }
+ break;
+
+ case 'W':
+ if (LastCharsAreHex)
+ {
+ NameString = "_Wxx";
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Match the name in the info table */
+
+ for (Info = AslPredefinedInfo; Info->Name; Info++)
+ {
+ if (ACPI_COMPARE_NAME (NameString, Info->Name))
+ {
+ AcpiOsPrintf (" // %4.4s: %s",
+ NameString, ACPI_CAST_PTR (char, Info->Description));
+ return;
+ }
+ }
+
+#endif
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFieldPredefinedDescription
+ *
+ * PARAMETERS: Op - Parse object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit a description comment for a resource descriptor tag
+ * (which is a predefined ACPI name.) Used for iASL compiler only.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmFieldPredefinedDescription (
+ ACPI_PARSE_OBJECT *Op)
+{
+#ifdef ACPI_ASL_COMPILER
+ ACPI_PARSE_OBJECT *IndexOp;
+ char *Tag;
+ const ACPI_OPCODE_INFO *OpInfo;
+ const AH_PREDEFINED_NAME *Info;
+
+
+ if (!Op)
+ {
+ return;
+ }
+
+ /* Ensure that the comment field is emitted only once */
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEF_CHECKED)
+ {
+ return;
+ }
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEF_CHECKED;
+
+ /*
+ * Op must be one of the Create* operators: CreateField, CreateBitField,
+ * CreateByteField, CreateWordField, CreateDwordField, CreateQwordField
+ */
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (!(OpInfo->Flags & AML_CREATE))
+ {
+ return;
+ }
+
+ /* Second argument is the Index argument */
+
+ IndexOp = Op->Common.Value.Arg;
+ IndexOp = IndexOp->Common.Next;
+
+ /* Index argument must be a namepath */
+
+ if (IndexOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)
+ {
+ return;
+ }
+
+ /* Major cheat: We previously put the Tag ptr in the Node field */
+
+ Tag = ACPI_CAST_PTR (char, IndexOp->Common.Node);
+
+ /* Match the name in the info table */
+
+ for (Info = AslPredefinedInfo; Info->Name; Info++)
+ {
+ if (ACPI_COMPARE_NAME (Tag, Info->Name))
+ {
+ AcpiOsPrintf (" // %4.4s: %s", Tag,
+ ACPI_CAST_PTR (char, Info->Description));
+ return;
+ }
+ }
+
+#endif
+ return;
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiDmMethodFlags
*
* PARAMETERS: Op - Method Object to be examined
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/disassembler/dmwalk.c
--- a/head/sys/contrib/dev/acpica/components/disassembler/dmwalk.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/disassembler/dmwalk.c Wed Jul 25 16:45:04 2012 +0300
@@ -453,7 +453,7 @@
* keep track of the current column.
*/
Info->Count++;
- if (Info->Count /*+Info->LastLevel*/ > 10)
+ if (Info->Count /* +Info->LastLevel */ > 10)
{
Info->Count = 0;
AcpiOsPrintf ("\n");
@@ -533,6 +533,10 @@
AcpiDmMethodFlags (Op);
AcpiOsPrintf (")");
+
+ /* Emit description comment for Method() with a predefined ACPI name */
+
+ AcpiDmPredefinedDescription (Op);
break;
@@ -603,7 +607,8 @@
default:
- AcpiOsPrintf ("*** Unhandled named opcode %X\n", Op->Common.AmlOpcode);
+ AcpiOsPrintf ("*** Unhandled named opcode %X\n",
+ Op->Common.AmlOpcode);
break;
}
}
@@ -644,7 +649,8 @@
NextOp = NextOp->Common.Next;
Info->Flags = ACPI_PARSEOP_PARAMLIST;
- AcpiDmWalkParseTree (NextOp, AcpiDmDescendingOp, AcpiDmAscendingOp, Info);
+ AcpiDmWalkParseTree (NextOp, AcpiDmDescendingOp,
+ AcpiDmAscendingOp, Info);
Info->Flags = 0;
Info->Level = Level;
@@ -686,12 +692,18 @@
if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE)
{
/*
- * We have a resource list. Don't need to output
- * the buffer size Op. Open up a new block
+ * We have a resource list. Don't need to output
+ * the buffer size Op. Open up a new block
*/
NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
NextOp = NextOp->Common.Next;
- AcpiOsPrintf (")\n");
+ AcpiOsPrintf (")");
+
+ /* Emit description comment for Name() with a predefined ACPI name */
+
+ AcpiDmPredefinedDescription (Op->Asl.Parent);
+
+ AcpiOsPrintf ("\n");
AcpiDmIndent (Info->Level);
AcpiOsPrintf ("{\n");
return (AE_OK);
@@ -719,7 +731,7 @@
case AML_PACKAGE_OP:
- /* The next op is the size or predicate parameter */
+ /* The next op is the size parameter */
NextOp = AcpiPsGetDepthNext (NULL, Op);
if (NextOp)
@@ -772,6 +784,7 @@
void *Context)
{
ACPI_OP_WALK_INFO *Info = Context;
+ ACPI_PARSE_OBJECT *ParentOp;
if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
@@ -797,6 +810,19 @@
AcpiOsPrintf (")");
+ if (Op->Common.AmlOpcode == AML_NAME_OP)
+ {
+ /* Emit description comment for Name() with a predefined ACPI name */
+
+ AcpiDmPredefinedDescription (Op);
+ }
+ else
+ {
+ /* For Create* operators, attempt to emit resource tag description */
+
+ AcpiDmFieldPredefinedDescription (Op);
+ }
+
/* Could be a nested operator, check if comma required */
if (!AcpiDmCommaIfListMember (Op))
@@ -911,7 +937,20 @@
*/
if (Op->Common.Next)
{
- AcpiOsPrintf (")\n");
+ AcpiOsPrintf (")");
+
+ /* Emit description comment for Name() with a predefined ACPI name */
+
+ ParentOp = Op->Common.Parent;
+ if (ParentOp)
+ {
+ ParentOp = ParentOp->Common.Parent;
+ if (ParentOp && ParentOp->Asl.AmlOpcode == AML_NAME_OP)
+ {
+ AcpiDmPredefinedDescription (ParentOp);
+ }
+ }
+ AcpiOsPrintf ("\n");
AcpiDmIndent (Level - 1);
AcpiOsPrintf ("{\n");
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/dispatcher/dsfield.c
--- a/head/sys/contrib/dev/acpica/components/dispatcher/dsfield.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/dispatcher/dsfield.c Wed Jul 25 16:45:04 2012 +0300
@@ -57,6 +57,18 @@
/* Local prototypes */
+#ifdef ACPI_ASL_COMPILER
+#include <contrib/dev/acpica/include/acdisasm.h>
+
+static ACPI_STATUS
+AcpiDsCreateExternalRegion (
+ ACPI_STATUS LookupStatus,
+ ACPI_PARSE_OBJECT *Op,
+ char *Path,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE **Node);
+#endif
+
static ACPI_STATUS
AcpiDsGetFieldNames (
ACPI_CREATE_FIELD_INFO *Info,
@@ -64,6 +76,69 @@
ACPI_PARSE_OBJECT *Arg);
+#ifdef ACPI_ASL_COMPILER
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCreateExternalRegion (iASL Disassembler only)
+ *
+ * PARAMETERS: LookupStatus - Status from NsLookup operation
+ * Op - Op containing the Field definition and args
+ * Path - Pathname of the region
+ * ` WalkState - Current method state
+ * Node - Where the new region node is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
+ * region node/object.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsCreateExternalRegion (
+ ACPI_STATUS LookupStatus,
+ ACPI_PARSE_OBJECT *Op,
+ char *Path,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE **Node)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+
+
+ if (LookupStatus != AE_NOT_FOUND)
+ {
+ return (LookupStatus);
+ }
+
+ /*
+ * Table disassembly:
+ * OperationRegion not found. Generate an External for it, and
+ * insert the name into the namespace.
+ */
+ AcpiDmAddToExternalList (Op, Path, ACPI_TYPE_REGION, 0);
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_REGION,
+ ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, WalkState, Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Must create and install a region object for the new node */
+
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
+ if (!ObjDesc)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ ObjDesc->Region.Node = *Node;
+ Status = AcpiNsAttachObject (*Node, ObjDesc, ACPI_TYPE_REGION);
+ return (Status);
+}
+#endif
+
+
/*******************************************************************************
*
* FUNCTION: AcpiDsCreateBufferField
@@ -77,8 +152,8 @@
* CreateBitFieldOp,
* CreateByteFieldOp,
* CreateWordFieldOp,
- * CreateDWordFieldOp,
- * CreateQWordFieldOp,
+ * CreateDwordFieldOp,
+ * CreateQwordFieldOp,
* CreateFieldOp (all of which define a field in a buffer)
*
******************************************************************************/
@@ -438,11 +513,16 @@
/* First arg is the name of the parent OpRegion (must already exist) */
Arg = Op->Common.Value.Arg;
+
if (!RegionNode)
{
Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
+#ifdef ACPI_ASL_COMPILER
+ Status = AcpiDsCreateExternalRegion (Status, Arg,
+ Arg->Common.Value.Name, WalkState, &RegionNode);
+#endif
if (ACPI_FAILURE (Status))
{
ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
@@ -628,6 +708,10 @@
Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
+#ifdef ACPI_ASL_COMPILER
+ Status = AcpiDsCreateExternalRegion (Status, Arg,
+ Arg->Common.Value.Name, WalkState, &RegionNode);
+#endif
if (ACPI_FAILURE (Status))
{
ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/dispatcher/dsopcode.c
--- a/head/sys/contrib/dev/acpica/components/dispatcher/dsopcode.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/dispatcher/dsopcode.c Wed Jul 25 16:45:04 2012 +0300
@@ -523,18 +523,18 @@
/*
- * This is where we evaluate the SignatureString and OemIDString
- * and OemTableIDString of the DataTableRegion declaration
+ * This is where we evaluate the Signature string, OemId string,
+ * and OemTableId string of the Data Table Region declaration
*/
Node = Op->Common.Node;
- /* NextOp points to SignatureString op */
+ /* NextOp points to Signature string op */
NextOp = Op->Common.Value.Arg;
/*
- * Evaluate/create the SignatureString and OemIDString
- * and OemTableIDString operands
+ * Evaluate/create the Signature string, OemId string,
+ * and OemTableId string operands
*/
Status = AcpiDsCreateOperands (WalkState, NextOp);
if (ACPI_FAILURE (Status))
@@ -543,8 +543,8 @@
}
/*
- * Resolve the SignatureString and OemIDString
- * and OemTableIDString operands
+ * Resolve the Signature string, OemId string,
+ * and OemTableId string operands
*/
Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
ACPI_WALK_OPERANDS, WalkState);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/events/evgpe.c
--- a/head/sys/contrib/dev/acpica/components/events/evgpe.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/events/evgpe.c Wed Jul 25 16:45:04 2012 +0300
@@ -518,6 +518,7 @@
ACPI_STATUS Status;
ACPI_GPE_EVENT_INFO *LocalGpeEventInfo;
ACPI_EVALUATE_INFO *Info;
+ ACPI_GPE_NOTIFY_INFO *Notify;
ACPI_FUNCTION_TRACE (EvAsynchExecuteGpeMethod);
@@ -573,10 +574,18 @@
* completes. The notify handlers are NOT invoked synchronously
* from this thread -- because handlers may in turn run other
* control methods.
+ *
+ * June 2012: Expand implicit notify mechanism to support
+ * notifies on multiple device objects.
*/
- Status = AcpiEvQueueNotifyRequest (
- LocalGpeEventInfo->Dispatch.DeviceNode,
- ACPI_NOTIFY_DEVICE_WAKE);
+ Notify = LocalGpeEventInfo->Dispatch.NotifyList;
+ while (ACPI_SUCCESS (Status) && Notify)
+ {
+ Status = AcpiEvQueueNotifyRequest (Notify->DeviceNode,
+ ACPI_NOTIFY_DEVICE_WAKE);
+
+ Notify = Notify->Next;
+ }
break;
case ACPI_GPE_DISPATCH_METHOD:
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/events/evgpeutil.c
--- a/head/sys/contrib/dev/acpica/components/events/evgpeutil.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/events/evgpeutil.c Wed Jul 25 16:45:04 2012 +0300
@@ -391,6 +391,8 @@
void *Context)
{
ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_GPE_NOTIFY_INFO *Notify;
+ ACPI_GPE_NOTIFY_INFO *Next;
UINT32 i;
UINT32 j;
@@ -412,10 +414,27 @@
if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_HANDLER)
{
+ /* Delete an installed handler block */
+
ACPI_FREE (GpeEventInfo->Dispatch.Handler);
GpeEventInfo->Dispatch.Handler = NULL;
GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;
}
+ else if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
+ ACPI_GPE_DISPATCH_NOTIFY)
+ {
+ /* Delete the implicit notification device list */
+
+ Notify = GpeEventInfo->Dispatch.NotifyList;
+ while (Notify)
+ {
+ Next = Notify->Next;
+ ACPI_FREE (Notify);
+ Notify = Next;
+ }
+ GpeEventInfo->Dispatch.NotifyList = NULL;
+ GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;
+ }
}
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/events/evmisc.c
--- a/head/sys/contrib/dev/acpica/components/events/evmisc.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/events/evmisc.c Wed Jul 25 16:45:04 2012 +0300
@@ -111,107 +111,82 @@
UINT32 NotifyValue)
{
ACPI_OPERAND_OBJECT *ObjDesc;
- ACPI_OPERAND_OBJECT *HandlerObj = NULL;
- ACPI_GENERIC_STATE *NotifyInfo;
+ ACPI_OPERAND_OBJECT *HandlerListHead = NULL;
+ ACPI_GENERIC_STATE *Info;
+ UINT8 HandlerListId = 0;
ACPI_STATUS Status = AE_OK;
ACPI_FUNCTION_NAME (EvQueueNotifyRequest);
+ /* Are Notifies allowed on this object? */
+
+ if (!AcpiEvIsNotifyObject (Node))
+ {
+ return (AE_TYPE);
+ }
+
+ /* Get the correct notify list type (System or Device) */
+
+ if (NotifyValue <= ACPI_MAX_SYS_NOTIFY)
+ {
+ HandlerListId = ACPI_SYSTEM_HANDLER_LIST;
+ }
+ else
+ {
+ HandlerListId = ACPI_DEVICE_HANDLER_LIST;
+ }
+
+ /* Get the notify object attached to the namespace Node */
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (ObjDesc)
+ {
+ /* We have an attached object, Get the correct handler list */
+
+ HandlerListHead = ObjDesc->CommonNotify.NotifyList[HandlerListId];
+ }
+
/*
- * For value 0x03 (Ejection Request), may need to run a device method.
- * For value 0x02 (Device Wake), if _PRW exists, may need to run
- * the _PS0 method.
- * For value 0x80 (Status Change) on the power button or sleep button,
- * initiate soft-off or sleep operation.
- *
- * For all cases, simply dispatch the notify to the handler.
+ * If there is no notify handler (Global or Local)
+ * for this object, just ignore the notify
*/
+ if (!AcpiGbl_GlobalNotify[HandlerListId].Handler && !HandlerListHead)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "No notify handler for Notify, ignoring (%4.4s, %X) node %p\n",
+ AcpiUtGetNodeName (Node), NotifyValue, Node));
+
+ return (AE_OK);
+ }
+
+ /* Setup notify info and schedule the notify dispatcher */
+
+ Info = AcpiUtCreateGenericState ();
+ if (!Info)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ Info->Common.DescriptorType = ACPI_DESC_TYPE_STATE_NOTIFY;
+
+ Info->Notify.Node = Node;
+ Info->Notify.Value = (UINT16) NotifyValue;
+ Info->Notify.HandlerListId = HandlerListId;
+ Info->Notify.HandlerListHead = HandlerListHead;
+ Info->Notify.Global = &AcpiGbl_GlobalNotify[HandlerListId];
+
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n",
AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type),
NotifyValue, AcpiUtGetNotifyName (NotifyValue), Node));
- /* Get the notify object attached to the NS Node */
-
- ObjDesc = AcpiNsGetAttachedObject (Node);
- if (ObjDesc)
+ Status = AcpiOsExecute (OSL_NOTIFY_HANDLER, AcpiEvNotifyDispatch,
+ Info);
+ if (ACPI_FAILURE (Status))
{
- /* We have the notify object, Get the correct handler */
-
- switch (Node->Type)
- {
- /* Notify is allowed only on these types */
-
- case ACPI_TYPE_DEVICE:
- case ACPI_TYPE_THERMAL:
- case ACPI_TYPE_PROCESSOR:
-
- if (NotifyValue <= ACPI_MAX_SYS_NOTIFY)
- {
- HandlerObj = ObjDesc->CommonNotify.SystemNotify;
- }
- else
- {
- HandlerObj = ObjDesc->CommonNotify.DeviceNotify;
- }
- break;
-
- default:
-
- /* All other types are not supported */
-
- return (AE_TYPE);
- }
- }
-
- /*
- * If there is a handler to run, schedule the dispatcher.
- * Check for:
- * 1) Global system notify handler
- * 2) Global device notify handler
- * 3) Per-device notify handler
- */
- if ((AcpiGbl_SystemNotify.Handler &&
- (NotifyValue <= ACPI_MAX_SYS_NOTIFY)) ||
- (AcpiGbl_DeviceNotify.Handler &&
- (NotifyValue > ACPI_MAX_SYS_NOTIFY)) ||
- HandlerObj)
- {
- NotifyInfo = AcpiUtCreateGenericState ();
- if (!NotifyInfo)
- {
- return (AE_NO_MEMORY);
- }
-
- if (!HandlerObj)
- {
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Executing system notify handler for Notify (%4.4s, %X) "
- "node %p\n",
- AcpiUtGetNodeName (Node), NotifyValue, Node));
- }
-
- NotifyInfo->Common.DescriptorType = ACPI_DESC_TYPE_STATE_NOTIFY;
- NotifyInfo->Notify.Node = Node;
- NotifyInfo->Notify.Value = (UINT16) NotifyValue;
- NotifyInfo->Notify.HandlerObj = HandlerObj;
-
- Status = AcpiOsExecute (
- OSL_NOTIFY_HANDLER, AcpiEvNotifyDispatch, NotifyInfo);
- if (ACPI_FAILURE (Status))
- {
- AcpiUtDeleteGenericState (NotifyInfo);
- }
- }
- else
- {
- /* There is no notify handler (per-device or system) for this device */
-
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "No notify handler for Notify (%4.4s, %X) node %p\n",
- AcpiUtGetNodeName (Node), NotifyValue, Node));
+ AcpiUtDeleteGenericState (Info);
}
return (Status);
@@ -235,61 +210,37 @@
AcpiEvNotifyDispatch (
void *Context)
{
- ACPI_GENERIC_STATE *NotifyInfo = (ACPI_GENERIC_STATE *) Context;
- ACPI_NOTIFY_HANDLER GlobalHandler = NULL;
- void *GlobalContext = NULL;
+ ACPI_GENERIC_STATE *Info = (ACPI_GENERIC_STATE *) Context;
ACPI_OPERAND_OBJECT *HandlerObj;
ACPI_FUNCTION_ENTRY ();
- /*
- * We will invoke a global notify handler if installed. This is done
- * _before_ we invoke the per-device handler attached to the device.
- */
- if (NotifyInfo->Notify.Value <= ACPI_MAX_SYS_NOTIFY)
+ /* Invoke a global notify handler if installed */
+
+ if (Info->Notify.Global->Handler)
{
- /* Global system notification handler */
-
- if (AcpiGbl_SystemNotify.Handler)
- {
- GlobalHandler = AcpiGbl_SystemNotify.Handler;
- GlobalContext = AcpiGbl_SystemNotify.Context;
- }
- }
- else
- {
- /* Global driver notification handler */
-
- if (AcpiGbl_DeviceNotify.Handler)
- {
- GlobalHandler = AcpiGbl_DeviceNotify.Handler;
- GlobalContext = AcpiGbl_DeviceNotify.Context;
- }
+ Info->Notify.Global->Handler (Info->Notify.Node,
+ Info->Notify.Value,
+ Info->Notify.Global->Context);
}
- /* Invoke the system handler first, if present */
+ /* Now invoke the local notify handler(s) if any are installed */
- if (GlobalHandler)
+ HandlerObj = Info->Notify.HandlerListHead;
+ while (HandlerObj)
{
- GlobalHandler (NotifyInfo->Notify.Node, NotifyInfo->Notify.Value,
- GlobalContext);
- }
+ HandlerObj->Notify.Handler (Info->Notify.Node,
+ Info->Notify.Value,
+ HandlerObj->Notify.Context);
- /* Now invoke the per-device handler, if present */
-
- HandlerObj = NotifyInfo->Notify.HandlerObj;
- if (HandlerObj)
- {
- HandlerObj->Notify.Handler (NotifyInfo->Notify.Node,
- NotifyInfo->Notify.Value,
- HandlerObj->Notify.Context);
+ HandlerObj = HandlerObj->Notify.Next[Info->Notify.HandlerListId];
}
/* All done with the info object */
- AcpiUtDeleteGenericState (NotifyInfo);
+ AcpiUtDeleteGenericState (Info);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/events/evxface.c
--- a/head/sys/contrib/dev/acpica/components/events/evxface.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/events/evxface.c Wed Jul 25 16:45:04 2012 +0300
@@ -60,15 +60,21 @@
*
* PARAMETERS: Device - The device for which notifies will be handled
* HandlerType - The type of handler:
- * ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
- * ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
- * ACPI_ALL_NOTIFY: both system and device
+ * ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
+ * ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
+ * ACPI_ALL_NOTIFY: Both System and Device
* Handler - Address of the handler
* Context - Value passed to the handler on each GPE
*
* RETURN: Status
*
- * DESCRIPTION: Install a handler for notifies on an ACPI device
+ * DESCRIPTION: Install a handler for notifications on an ACPI Device,
+ * ThermalZone, or Processor object.
+ *
+ * NOTES: The Root namespace object may have only one handler for each
+ * type of notify (System/Device). Device/Thermal/Processor objects
+ * may have one device notify handler, and multiple system notify
+ * handlers.
*
******************************************************************************/
@@ -79,10 +85,11 @@
ACPI_NOTIFY_HANDLER Handler,
void *Context)
{
+ ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
ACPI_OPERAND_OBJECT *ObjDesc;
- ACPI_OPERAND_OBJECT *NotifyObj;
- ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *HandlerObj;
ACPI_STATUS Status;
+ UINT32 i;
ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler);
@@ -90,8 +97,7 @@
/* Parameter validation */
- if ((!Device) ||
- (!Handler) ||
+ if ((!Device) || (!Handler) || (!HandlerType) ||
(HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
{
return_ACPI_STATUS (AE_BAD_PARAMETER);
@@ -103,137 +109,126 @@
return_ACPI_STATUS (Status);
}
- /* Convert and validate the device handle */
-
- Node = AcpiNsValidateHandle (Device);
- if (!Node)
- {
- Status = AE_BAD_PARAMETER;
- goto UnlockAndExit;
- }
-
/*
* Root Object:
* Registering a notify handler on the root object indicates that the
* caller wishes to receive notifications for all objects. Note that
- * only one <external> global handler can be regsitered (per notify type).
+ * only one global handler can be registered per notify type.
+ * Ensure that a handler is not already installed.
*/
if (Device == ACPI_ROOT_OBJECT)
{
- /* Make sure the handler is not already installed */
+ for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
+ {
+ if (HandlerType & (i+1))
+ {
+ if (AcpiGbl_GlobalNotify[i].Handler)
+ {
+ Status = AE_ALREADY_EXISTS;
+ goto UnlockAndExit;
+ }
- if (((HandlerType & ACPI_SYSTEM_NOTIFY) &&
- AcpiGbl_SystemNotify.Handler) ||
- ((HandlerType & ACPI_DEVICE_NOTIFY) &&
- AcpiGbl_DeviceNotify.Handler))
- {
- Status = AE_ALREADY_EXISTS;
- goto UnlockAndExit;
+ AcpiGbl_GlobalNotify[i].Handler = Handler;
+ AcpiGbl_GlobalNotify[i].Context = Context;
+ }
}
- if (HandlerType & ACPI_SYSTEM_NOTIFY)
- {
- AcpiGbl_SystemNotify.Node = Node;
- AcpiGbl_SystemNotify.Handler = Handler;
- AcpiGbl_SystemNotify.Context = Context;
- }
-
- if (HandlerType & ACPI_DEVICE_NOTIFY)
- {
- AcpiGbl_DeviceNotify.Node = Node;
- AcpiGbl_DeviceNotify.Handler = Handler;
- AcpiGbl_DeviceNotify.Context = Context;
- }
-
- /* Global notify handler installed */
+ goto UnlockAndExit; /* Global notify handler installed, all done */
}
/*
* All Other Objects:
- * Caller will only receive notifications specific to the target object.
- * Note that only certain object types can receive notifications.
+ * Caller will only receive notifications specific to the target
+ * object. Note that only certain object types are allowed to
+ * receive notifications.
*/
- else
+
+ /* Are Notifies allowed on this object? */
+
+ if (!AcpiEvIsNotifyObject (Node))
{
- /* Notifies allowed on this object? */
+ Status = AE_TYPE;
+ goto UnlockAndExit;
+ }
- if (!AcpiEvIsNotifyObject (Node))
- {
- Status = AE_TYPE;
- goto UnlockAndExit;
- }
+ /* Check for an existing internal object, might not exist */
- /* Check for an existing internal object */
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc)
+ {
+ /* Create a new object */
- ObjDesc = AcpiNsGetAttachedObject (Node);
- if (ObjDesc)
- {
- /* Object exists - make sure there's no handler */
-
- if (((HandlerType & ACPI_SYSTEM_NOTIFY) &&
- ObjDesc->CommonNotify.SystemNotify) ||
- ((HandlerType & ACPI_DEVICE_NOTIFY) &&
- ObjDesc->CommonNotify.DeviceNotify))
- {
- Status = AE_ALREADY_EXISTS;
- goto UnlockAndExit;
- }
- }
- else
- {
- /* Create a new object */
-
- ObjDesc = AcpiUtCreateInternalObject (Node->Type);
- if (!ObjDesc)
- {
- Status = AE_NO_MEMORY;
- goto UnlockAndExit;
- }
-
- /* Attach new object to the Node */
-
- Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
-
- /* Remove local reference to the object */
-
- AcpiUtRemoveReference (ObjDesc);
- if (ACPI_FAILURE (Status))
- {
- goto UnlockAndExit;
- }
- }
-
- /* Install the handler */
-
- NotifyObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY);
- if (!NotifyObj)
+ ObjDesc = AcpiUtCreateInternalObject (Node->Type);
+ if (!ObjDesc)
{
Status = AE_NO_MEMORY;
goto UnlockAndExit;
}
- NotifyObj->Notify.Node = Node;
- NotifyObj->Notify.Handler = Handler;
- NotifyObj->Notify.Context = Context;
+ /* Attach new object to the Node, remove local reference */
- if (HandlerType & ACPI_SYSTEM_NOTIFY)
+ Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
+ AcpiUtRemoveReference (ObjDesc);
+ if (ACPI_FAILURE (Status))
{
- ObjDesc->CommonNotify.SystemNotify = NotifyObj;
+ goto UnlockAndExit;
}
+ }
- if (HandlerType & ACPI_DEVICE_NOTIFY)
+ /* Ensure that the handler is not already installed in the lists */
+
+ for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
+ {
+ if (HandlerType & (i+1))
{
- ObjDesc->CommonNotify.DeviceNotify = NotifyObj;
+ HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
+ while (HandlerObj)
+ {
+ if (HandlerObj->Notify.Handler == Handler)
+ {
+ Status = AE_ALREADY_EXISTS;
+ goto UnlockAndExit;
+ }
+
+ HandlerObj = HandlerObj->Notify.Next[i];
+ }
}
+ }
- if (HandlerType == ACPI_ALL_NOTIFY)
+ /* Create and populate a new notify handler object */
+
+ HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY);
+ if (!HandlerObj)
+ {
+ Status = AE_NO_MEMORY;
+ goto UnlockAndExit;
+ }
+
+ HandlerObj->Notify.Node = Node;
+ HandlerObj->Notify.HandlerType = HandlerType;
+ HandlerObj->Notify.Handler = Handler;
+ HandlerObj->Notify.Context = Context;
+
+ /* Install the handler at the list head(s) */
+
+ for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
+ {
+ if (HandlerType & (i+1))
{
- /* Extra ref if installed in both */
+ HandlerObj->Notify.Next[i] =
+ ObjDesc->CommonNotify.NotifyList[i];
- AcpiUtAddReference (NotifyObj);
+ ObjDesc->CommonNotify.NotifyList[i] = HandlerObj;
}
}
+ /* Add an extra reference if handler was installed in both lists */
+
+ if (HandlerType == ACPI_ALL_NOTIFY)
+ {
+ AcpiUtAddReference (HandlerObj);
+ }
+
UnlockAndExit:
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
@@ -247,11 +242,11 @@
*
* FUNCTION: AcpiRemoveNotifyHandler
*
- * PARAMETERS: Device - The device for which notifies will be handled
+ * PARAMETERS: Device - The device for which the handler is installed
* HandlerType - The type of handler:
- * ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
- * ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
- * ACPI_ALL_NOTIFY: both system and device
+ * ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
+ * ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
+ * ACPI_ALL_NOTIFY: Both System and Device
* Handler - Address of the handler
*
* RETURN: Status
@@ -266,10 +261,12 @@
UINT32 HandlerType,
ACPI_NOTIFY_HANDLER Handler)
{
- ACPI_OPERAND_OBJECT *NotifyObj;
+ ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
ACPI_OPERAND_OBJECT *ObjDesc;
- ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *HandlerObj;
+ ACPI_OPERAND_OBJECT *PreviousHandlerObj;
ACPI_STATUS Status;
+ UINT32 i;
ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler);
@@ -277,122 +274,103 @@
/* Parameter validation */
- if ((!Device) ||
- (!Handler) ||
+ if ((!Device) || (!Handler) || (!HandlerType) ||
(HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
{
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
+ /* Make sure all deferred notify tasks are completed */
+
+ AcpiOsWaitEventsComplete ();
+
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
- /* Convert and validate the device handle */
+ /* Root Object. Global handlers are removed here */
- Node = AcpiNsValidateHandle (Device);
- if (!Node)
+ if (Device == ACPI_ROOT_OBJECT)
{
- Status = AE_BAD_PARAMETER;
+ for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
+ {
+ if (HandlerType & (i+1))
+ {
+ if (!AcpiGbl_GlobalNotify[i].Handler ||
+ (AcpiGbl_GlobalNotify[i].Handler != Handler))
+ {
+ Status = AE_NOT_EXIST;
+ goto UnlockAndExit;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Removing global notify handler\n"));
+
+ AcpiGbl_GlobalNotify[i].Handler = NULL;
+ AcpiGbl_GlobalNotify[i].Context = NULL;
+ }
+ }
+
goto UnlockAndExit;
}
- /* Root Object */
+ /* All other objects: Are Notifies allowed on this object? */
- if (Device == ACPI_ROOT_OBJECT)
+ if (!AcpiEvIsNotifyObject (Node))
{
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Removing notify handler for namespace root object\n"));
-
- if (((HandlerType & ACPI_SYSTEM_NOTIFY) &&
- !AcpiGbl_SystemNotify.Handler) ||
- ((HandlerType & ACPI_DEVICE_NOTIFY) &&
- !AcpiGbl_DeviceNotify.Handler))
- {
- Status = AE_NOT_EXIST;
- goto UnlockAndExit;
- }
-
- if (HandlerType & ACPI_SYSTEM_NOTIFY)
- {
- AcpiGbl_SystemNotify.Node = NULL;
- AcpiGbl_SystemNotify.Handler = NULL;
- AcpiGbl_SystemNotify.Context = NULL;
- }
-
- if (HandlerType & ACPI_DEVICE_NOTIFY)
- {
- AcpiGbl_DeviceNotify.Node = NULL;
- AcpiGbl_DeviceNotify.Handler = NULL;
- AcpiGbl_DeviceNotify.Context = NULL;
- }
+ Status = AE_TYPE;
+ goto UnlockAndExit;
}
- /* All Other Objects */
+ /* Must have an existing internal object */
- else
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc)
{
- /* Notifies allowed on this object? */
+ Status = AE_NOT_EXIST;
+ goto UnlockAndExit;
+ }
- if (!AcpiEvIsNotifyObject (Node))
+ /* Internal object exists. Find the handler and remove it */
+
+ for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
+ {
+ if (HandlerType & (i+1))
{
- Status = AE_TYPE;
- goto UnlockAndExit;
- }
+ HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
+ PreviousHandlerObj = NULL;
- /* Check for an existing internal object */
+ /* Attempt to find the handler in the handler list */
- ObjDesc = AcpiNsGetAttachedObject (Node);
- if (!ObjDesc)
- {
- Status = AE_NOT_EXIST;
- goto UnlockAndExit;
- }
+ while (HandlerObj &&
+ (HandlerObj->Notify.Handler != Handler))
+ {
+ PreviousHandlerObj = HandlerObj;
+ HandlerObj = HandlerObj->Notify.Next[i];
+ }
- /* Object exists - make sure there's an existing handler */
-
- if (HandlerType & ACPI_SYSTEM_NOTIFY)
- {
- NotifyObj = ObjDesc->CommonNotify.SystemNotify;
- if (!NotifyObj)
+ if (!HandlerObj)
{
Status = AE_NOT_EXIST;
goto UnlockAndExit;
}
- if (NotifyObj->Notify.Handler != Handler)
+ /* Remove the handler object from the list */
+
+ if (PreviousHandlerObj) /* Handler is not at the list head */
{
- Status = AE_BAD_PARAMETER;
- goto UnlockAndExit;
+ PreviousHandlerObj->Notify.Next[i] =
+ HandlerObj->Notify.Next[i];
+ }
+ else /* Handler is at the list head */
+ {
+ ObjDesc->CommonNotify.NotifyList[i] =
+ HandlerObj->Notify.Next[i];
}
- /* Remove the handler */
-
- ObjDesc->CommonNotify.SystemNotify = NULL;
- AcpiUtRemoveReference (NotifyObj);
- }
-
- if (HandlerType & ACPI_DEVICE_NOTIFY)
- {
- NotifyObj = ObjDesc->CommonNotify.DeviceNotify;
- if (!NotifyObj)
- {
- Status = AE_NOT_EXIST;
- goto UnlockAndExit;
- }
-
- if (NotifyObj->Notify.Handler != Handler)
- {
- Status = AE_BAD_PARAMETER;
- goto UnlockAndExit;
- }
-
- /* Remove the handler */
-
- ObjDesc->CommonNotify.DeviceNotify = NULL;
- AcpiUtRemoveReference (NotifyObj);
+ AcpiUtRemoveReference (HandlerObj);
}
}
@@ -822,6 +800,10 @@
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
+ /* Make sure all deferred GPE tasks are completed */
+
+ AcpiOsWaitEventsComplete ();
+
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
if (ACPI_FAILURE (Status))
{
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/events/evxfgpe.c
--- a/head/sys/contrib/dev/acpica/components/events/evxfgpe.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/events/evxfgpe.c Wed Jul 25 16:45:04 2012 +0300
@@ -83,7 +83,7 @@
ACPI_STATUS Status;
- ACPI_FUNCTION_TRACE (AcpiUpdateGpes);
+ ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes);
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
@@ -295,9 +295,11 @@
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber)
{
- ACPI_STATUS Status = AE_BAD_PARAMETER;
+ ACPI_STATUS Status;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
ACPI_NAMESPACE_NODE *DeviceNode;
+ ACPI_GPE_NOTIFY_INFO *Notify;
+ ACPI_GPE_NOTIFY_INFO *NewNotify;
ACPI_CPU_FLAGS Flags;
@@ -333,32 +335,88 @@
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
+ /*
+ * Allocate a new notify object up front, in case it is needed.
+ * Memory allocation while holding a spinlock is a big no-no
+ * on some hosts.
+ */
+ NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO));
+ if (!NewNotify)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
/* Ensure that we have a valid GPE number */
GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
- if (GpeEventInfo)
+ if (!GpeEventInfo)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ /*
+ * If there is no method or handler for this GPE, then the
+ * WakeDevice will be notified whenever this GPE fires. This is
+ * known as an "implicit notify". Note: The GPE is assumed to be
+ * level-triggered (for windows compatibility).
+ */
+ if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
+ ACPI_GPE_DISPATCH_NONE)
{
/*
- * If there is no method or handler for this GPE, then the
- * WakeDevice will be notified whenever this GPE fires (aka
- * "implicit notify") Note: The GPE is assumed to be
- * level-triggered (for windows compatibility).
+ * This is the first device for implicit notify on this GPE.
+ * Just set the flags here, and enter the NOTIFY block below.
*/
- if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
- ACPI_GPE_DISPATCH_NONE)
+ GpeEventInfo->Flags =
+ (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
+ }
+
+ /*
+ * If we already have an implicit notify on this GPE, add
+ * this device to the notify list.
+ */
+ if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
+ ACPI_GPE_DISPATCH_NOTIFY)
+ {
+ /* Ensure that the device is not already in the list */
+
+ Notify = GpeEventInfo->Dispatch.NotifyList;
+ while (Notify)
{
- GpeEventInfo->Flags =
- (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
- GpeEventInfo->Dispatch.DeviceNode = DeviceNode;
+ if (Notify->DeviceNode == DeviceNode)
+ {
+ Status = AE_ALREADY_EXISTS;
+ goto UnlockAndExit;
+ }
+ Notify = Notify->Next;
}
- GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
- Status = AE_OK;
+ /* Add this device to the notify list for this GPE */
+
+ NewNotify->DeviceNode = DeviceNode;
+ NewNotify->Next = GpeEventInfo->Dispatch.NotifyList;
+ GpeEventInfo->Dispatch.NotifyList = NewNotify;
+ NewNotify = NULL;
}
+ /* Mark the GPE as a possible wake event */
+
+ GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
+ Status = AE_OK;
+
+
+UnlockAndExit:
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+
+ /* Delete the notify object if it was not used above */
+
+ if (NewNotify)
+ {
+ ACPI_FREE (NewNotify);
+ }
return_ACPI_STATUS (Status);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/executer/exconfig.c
--- a/head/sys/contrib/dev/acpica/components/executer/exconfig.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/executer/exconfig.c Wed Jul 25 16:45:04 2012 +0300
@@ -179,7 +179,7 @@
ACPI_FUNCTION_TRACE (ExLoadTableOp);
- /* Validate lengths for the SignatureString, OEMIDString, OEMTableID */
+ /* Validate lengths for the Signature, OemId, and OemTableId strings */
if ((Operand[0]->String.Length > ACPI_NAME_SIZE) ||
(Operand[1]->String.Length > ACPI_OEM_ID_SIZE) ||
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/executer/exdump.c
--- a/head/sys/contrib/dev/acpica/components/executer/exdump.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/executer/exdump.c Wed Jul 25 16:45:04 2012 +0300
@@ -131,8 +131,8 @@
{
{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpDevice), NULL},
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Device.Handler), "Handler"},
- {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Device.SystemNotify), "System Notify"},
- {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Device.DeviceNotify), "Device Notify"}
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Device.NotifyList[0]), "System Notify"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Device.NotifyList[1]), "Device Notify"}
};
static ACPI_EXDUMP_INFO AcpiExDumpEvent[2] =
@@ -179,8 +179,8 @@
{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpPower), NULL},
{ACPI_EXD_UINT32, ACPI_EXD_OFFSET (PowerResource.SystemLevel), "System Level"},
{ACPI_EXD_UINT32, ACPI_EXD_OFFSET (PowerResource.ResourceOrder), "Resource Order"},
- {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (PowerResource.SystemNotify), "System Notify"},
- {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (PowerResource.DeviceNotify), "Device Notify"}
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (PowerResource.NotifyList[0]), "System Notify"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (PowerResource.NotifyList[1]), "Device Notify"}
};
static ACPI_EXDUMP_INFO AcpiExDumpProcessor[7] =
@@ -189,16 +189,16 @@
{ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Processor.ProcId), "Processor ID"},
{ACPI_EXD_UINT8 , ACPI_EXD_OFFSET (Processor.Length), "Length"},
{ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET (Processor.Address), "Address"},
- {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Processor.SystemNotify), "System Notify"},
- {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Processor.DeviceNotify), "Device Notify"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Processor.NotifyList[0]), "System Notify"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Processor.NotifyList[1]), "Device Notify"},
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Processor.Handler), "Handler"}
};
static ACPI_EXDUMP_INFO AcpiExDumpThermal[4] =
{
{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpThermal), NULL},
- {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (ThermalZone.SystemNotify), "System Notify"},
- {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (ThermalZone.DeviceNotify), "Device Notify"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (ThermalZone.NotifyList[0]), "System Notify"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (ThermalZone.NotifyList[1]), "Device Notify"},
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET (ThermalZone.Handler), "Handler"}
};
@@ -258,11 +258,15 @@
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET (AddressSpace.Context), "Context"}
};
-static ACPI_EXDUMP_INFO AcpiExDumpNotify[3] =
+static ACPI_EXDUMP_INFO AcpiExDumpNotify[7] =
{
{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpNotify), NULL},
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Notify.Node), "Node"},
- {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Notify.Context), "Context"}
+ {ACPI_EXD_UINT32, ACPI_EXD_OFFSET (Notify.HandlerType), "Handler Type"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Notify.Handler), "Handler"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Notify.Context), "Context"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Notify.Next[0]), "Next System Notify"},
+ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Notify.Next[1]), "Next Device Notify"}
};
@@ -1001,10 +1005,7 @@
case ACPI_TYPE_STRING:
AcpiOsPrintf ("[String] Value: ");
- for (i = 0; i < ObjDesc->String.Length; i++)
- {
- AcpiOsPrintf ("%c", ObjDesc->String.Pointer[i]);
- }
+ AcpiUtPrintString (ObjDesc->String.Pointer, ACPI_UINT8_MAX);
AcpiOsPrintf ("\n");
break;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/executer/exprep.c
--- a/head/sys/contrib/dev/acpica/components/executer/exprep.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/executer/exprep.c Wed Jul 25 16:45:04 2012 +0300
@@ -418,8 +418,8 @@
*
* RETURN: Status
*
- * DESCRIPTION: Construct an ACPI_OPERAND_OBJECT of type DefField and
- * connect it to the parent Node.
+ * DESCRIPTION: Construct an object of type ACPI_OPERAND_OBJECT with a
+ * subtype of DefField and connect it to the parent Node.
*
******************************************************************************/
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/executer/exresolv.c
--- a/head/sys/contrib/dev/acpica/components/executer/exresolv.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/executer/exresolv.c Wed Jul 25 16:45:04 2012 +0300
@@ -165,7 +165,7 @@
StackDesc = *StackPtr;
- /* This is an ACPI_OPERAND_OBJECT */
+ /* This is an object of type ACPI_OPERAND_OBJECT */
switch (StackDesc->Common.Type)
{
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/executer/exstore.c
--- a/head/sys/contrib/dev/acpica/components/executer/exstore.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/executer/exstore.c Wed Jul 25 16:45:04 2012 +0300
@@ -68,15 +68,15 @@
* FUNCTION: AcpiExStore
*
* PARAMETERS: *SourceDesc - Value to be stored
- * *DestDesc - Where to store it. Must be an NS node
- * or an ACPI_OPERAND_OBJECT of type
+ * *DestDesc - Where to store it. Must be an NS node
+ * or ACPI_OPERAND_OBJECT of type
* Reference;
* WalkState - Current walk state
*
* RETURN: Status
*
* DESCRIPTION: Store the value described by SourceDesc into the location
- * described by DestDesc. Called by various interpreter
+ * described by DestDesc. Called by various interpreter
* functions to store the result of an operation into
* the destination operand -- not just simply the actual "Store"
* ASL operator.
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/executer/exutils.c
--- a/head/sys/contrib/dev/acpica/components/executer/exutils.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/executer/exutils.c Wed Jul 25 16:45:04 2012 +0300
@@ -121,7 +121,7 @@
*
* DESCRIPTION: Reacquire the interpreter execution region from within the
* interpreter code. Failure to enter the interpreter region is a
- * fatal system error. Used in conjuction with
+ * fatal system error. Used in conjunction with
* RelinquishInterpreter
*
******************************************************************************/
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/hardware/hwesleep.c
--- a/head/sys/contrib/dev/acpica/components/hardware/hwesleep.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/hardware/hwesleep.c Wed Jul 25 16:45:04 2012 +0300
@@ -132,7 +132,7 @@
/* Clear wake status (WAK_STS) */
- Status = AcpiWrite (ACPI_X_WAKE_STATUS, &AcpiGbl_FADT.SleepStatus);
+ Status = AcpiWrite ((UINT64) ACPI_X_WAKE_STATUS, &AcpiGbl_FADT.SleepStatus);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
@@ -163,7 +163,7 @@
SleepTypeValue = ((AcpiGbl_SleepTypeA << ACPI_X_SLEEP_TYPE_POSITION) &
ACPI_X_SLEEP_TYPE_MASK);
- Status = AcpiWrite ((SleepTypeValue | ACPI_X_SLEEP_ENABLE),
+ Status = AcpiWrite ((UINT64) (SleepTypeValue | ACPI_X_SLEEP_ENABLE),
&AcpiGbl_FADT.SleepControl);
if (ACPI_FAILURE (Status))
{
@@ -219,7 +219,7 @@
SleepTypeValue = ((AcpiGbl_SleepTypeA << ACPI_X_SLEEP_TYPE_POSITION) &
ACPI_X_SLEEP_TYPE_MASK);
- (void) AcpiWrite ((SleepTypeValue | ACPI_X_SLEEP_ENABLE),
+ (void) AcpiWrite ((UINT64) (SleepTypeValue | ACPI_X_SLEEP_ENABLE),
&AcpiGbl_FADT.SleepControl);
}
@@ -269,7 +269,7 @@
* and use it to determine whether the system is rebooting or
* resuming. Clear WAK_STS for compatibility.
*/
- (void) AcpiWrite (ACPI_X_WAKE_STATUS, &AcpiGbl_FADT.SleepStatus);
+ (void) AcpiWrite ((UINT64) ACPI_X_WAKE_STATUS, &AcpiGbl_FADT.SleepStatus);
AcpiGbl_SystemAwakeAndRunning = TRUE;
AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, ACPI_SST_WORKING);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/hardware/hwsleep.c
--- a/head/sys/contrib/dev/acpica/components/hardware/hwsleep.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/hardware/hwsleep.c Wed Jul 25 16:45:04 2012 +0300
@@ -100,20 +100,6 @@
return_ACPI_STATUS (Status);
}
- if (SleepState != ACPI_STATE_S5)
- {
- /*
- * Disable BM arbitration. This feature is contained within an
- * optional register (PM2 Control), so ignore a BAD_ADDRESS
- * exception.
- */
- Status = AcpiWriteBitRegister (ACPI_BITREG_ARB_DISABLE, 1);
- if (ACPI_FAILURE (Status) && (Status != AE_BAD_ADDRESS))
- {
- return_ACPI_STATUS (Status);
- }
- }
-
/*
* 1) Disable/Clear all GPEs
* 2) Enable all wakeup GPEs
@@ -394,17 +380,6 @@
AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].StatusRegisterId,
ACPI_CLEAR_STATUS);
- /*
- * Enable BM arbitration. This feature is contained within an
- * optional register (PM2 Control), so ignore a BAD_ADDRESS
- * exception.
- */
- Status = AcpiWriteBitRegister (ACPI_BITREG_ARB_DISABLE, 0);
- if (ACPI_FAILURE (Status) && (Status != AE_BAD_ADDRESS))
- {
- return_ACPI_STATUS (Status);
- }
-
AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, ACPI_SST_WORKING);
return_ACPI_STATUS (Status);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c
--- a/head/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c Wed Jul 25 16:45:04 2012 +0300
@@ -101,6 +101,14 @@
ACPI_FUNCTION_TRACE (AcpiSetFirmwareWakingVector);
+ /*
+ * According to the ACPI specification 2.0c and later, the 64-bit
+ * waking vector should be cleared and the 32-bit waking vector should
+ * be used, unless we want the wake-up code to be called by the BIOS in
+ * Protected Mode. Some systems (for example HP dv5-1004nr) are known
+ * to fail to resume if the 64-bit vector is used.
+ */
+
/* Set the 32-bit vector */
AcpiGbl_FACS->FirmwareWakingVector = PhysicalAddress;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/namespace/nspredef.c
--- a/head/sys/contrib/dev/acpica/components/namespace/nspredef.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/namespace/nspredef.c Wed Jul 25 16:45:04 2012 +0300
@@ -681,7 +681,7 @@
{
/* Create the new outer package and populate it */
- Status = AcpiNsWrapWithPackage (Data, *Elements, ReturnObjectPtr);
+ Status = AcpiNsWrapWithPackage (Data, ReturnObject, ReturnObjectPtr);
if (ACPI_FAILURE (Status))
{
return (Status);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/parser/psxface.c
--- a/head/sys/contrib/dev/acpica/components/parser/psxface.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/parser/psxface.c Wed Jul 25 16:45:04 2012 +0300
@@ -348,8 +348,8 @@
}
/*
- * Start method evaluation with an implicit return of zero. This is done
- * for Windows compatibility.
+ * Start method evaluation with an implicit return of zero.
+ * This is done for Windows compatibility.
*/
if (AcpiGbl_EnableInterpreterSlack)
{
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/resources/rscreate.c
--- a/head/sys/contrib/dev/acpica/components/resources/rscreate.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/resources/rscreate.c Wed Jul 25 16:45:04 2012 +0300
@@ -209,8 +209,8 @@
*
* FUNCTION: AcpiRsCreatePciRoutingTable
*
- * PARAMETERS: PackageObject - Pointer to an ACPI_OPERAND_OBJECT
- * package
+ * PARAMETERS: PackageObject - Pointer to a package containing one
+ * of more ACPI_OPERAND_OBJECTs
* OutputBuffer - Pointer to the user's buffer
*
* RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code.
@@ -218,7 +218,7 @@
* AE_BUFFER_OVERFLOW and OutputBuffer->Length will point
* to the size buffer needed.
*
- * DESCRIPTION: Takes the ACPI_OPERAND_OBJECT package and creates a
+ * DESCRIPTION: Takes the ACPI_OPERAND_OBJECT package and creates a
* linked list of PCI interrupt descriptions
*
* NOTE: It is the caller's responsibility to ensure that the start of the
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/resources/rsutils.c
--- a/head/sys/contrib/dev/acpica/components/resources/rsutils.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/resources/rsutils.c Wed Jul 25 16:45:04 2012 +0300
@@ -181,7 +181,7 @@
/*
* 16-, 32-, and 64-bit cases must use the move macros that perform
- * endian conversion and/or accomodate hardware that cannot perform
+ * endian conversion and/or accommodate hardware that cannot perform
* misaligned memory transfers
*/
case ACPI_RSC_MOVE16:
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/tables/tbfadt.c
--- a/head/sys/contrib/dev/acpica/components/tables/tbfadt.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/tables/tbfadt.c Wed Jul 25 16:45:04 2012 +0300
@@ -52,12 +52,13 @@
/* Local prototypes */
-static ACPI_INLINE void
+static void
AcpiTbInitGenericAddress (
ACPI_GENERIC_ADDRESS *GenericAddress,
UINT8 SpaceId,
UINT8 ByteWidth,
- UINT64 Address);
+ UINT64 Address,
+ char *RegisterName);
static void
AcpiTbConvertFadt (
@@ -191,7 +192,7 @@
*
* PARAMETERS: GenericAddress - GAS struct to be initialized
* SpaceId - ACPI Space ID for this register
- * ByteWidth - Width of this register, in bytes
+ * ByteWidth - Width of this register
* Address - Address of the register
*
* RETURN: None
@@ -202,13 +203,30 @@
*
******************************************************************************/
-static ACPI_INLINE void
+static void
AcpiTbInitGenericAddress (
ACPI_GENERIC_ADDRESS *GenericAddress,
UINT8 SpaceId,
UINT8 ByteWidth,
- UINT64 Address)
+ UINT64 Address,
+ char *RegisterName)
{
+ UINT8 BitWidth;
+
+
+ /* Bit width field in the GAS is only one byte long, 255 max */
+
+ BitWidth = (UINT8) (ByteWidth * 8);
+
+ if (ByteWidth > 31) /* (31*8)=248 */
+ {
+ ACPI_ERROR ((AE_INFO,
+ "%s - 32-bit FADT register is too long (%u bytes, %u bits) "
+ "to convert to GAS struct - 255 bits max, truncating",
+ RegisterName, ByteWidth, (ByteWidth * 8)));
+
+ BitWidth = 255;
+ }
/*
* The 64-bit Address field is non-aligned in the byte packed
@@ -219,7 +237,7 @@
/* All other fields are byte-wide */
GenericAddress->SpaceId = SpaceId;
- GenericAddress->BitWidth = (UINT8) ACPI_MUL_8 (ByteWidth);
+ GenericAddress->BitWidth = BitWidth;
GenericAddress->BitOffset = 0;
GenericAddress->AccessWidth = 0; /* Access width ANY */
}
@@ -320,7 +338,7 @@
*/
if (Length > sizeof (ACPI_TABLE_FADT))
{
- ACPI_WARNING ((AE_INFO,
+ ACPI_BIOS_WARNING ((AE_INFO,
"FADT (revision %u) is longer than ACPI 5.0 version, "
"truncating length %u to %u",
Table->Revision, Length, (UINT32) sizeof (ACPI_TABLE_FADT)));
@@ -468,8 +486,9 @@
if (Address64->Address && Address32 &&
(Address64->Address != (UINT64) Address32))
{
- ACPI_ERROR ((AE_INFO,
- "32/64X address mismatch in %s: 0x%8.8X/0x%8.8X%8.8X, using 32",
+ ACPI_BIOS_ERROR ((AE_INFO,
+ "32/64X address mismatch in FADT/%s: "
+ "0x%8.8X/0x%8.8X%8.8X, using 32",
FadtInfoTable[i].Name, Address32,
ACPI_FORMAT_UINT64 (Address64->Address)));
}
@@ -484,7 +503,7 @@
*/
AcpiTbInitGenericAddress (Address64, ACPI_ADR_SPACE_SYSTEM_IO,
*ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT, FadtInfoTable[i].Length),
- (UINT64) Address32);
+ (UINT64) Address32, FadtInfoTable[i].Name);
}
}
}
@@ -528,7 +547,7 @@
if (AcpiGbl_FADT.Facs &&
(AcpiGbl_FADT.XFacs != (UINT64) AcpiGbl_FADT.Facs))
{
- ACPI_WARNING ((AE_INFO,
+ ACPI_BIOS_WARNING ((AE_INFO,
"32/64X FACS address mismatch in FADT - "
"0x%8.8X/0x%8.8X%8.8X, using 32",
AcpiGbl_FADT.Facs, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XFacs)));
@@ -539,7 +558,7 @@
if (AcpiGbl_FADT.Dsdt &&
(AcpiGbl_FADT.XDsdt != (UINT64) AcpiGbl_FADT.Dsdt))
{
- ACPI_WARNING ((AE_INFO,
+ ACPI_BIOS_WARNING ((AE_INFO,
"32/64X DSDT address mismatch in FADT - "
"0x%8.8X/0x%8.8X%8.8X, using 32",
AcpiGbl_FADT.Dsdt, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XDsdt)));
@@ -575,8 +594,8 @@
if (Address64->Address &&
(Address64->BitWidth != ACPI_MUL_8 (Length)))
{
- ACPI_WARNING ((AE_INFO,
- "32/64X length mismatch in %s: %u/%u",
+ ACPI_BIOS_WARNING ((AE_INFO,
+ "32/64X length mismatch in FADT/%s: %u/%u",
Name, ACPI_MUL_8 (Length), Address64->BitWidth));
}
@@ -588,9 +607,9 @@
*/
if (!Address64->Address || !Length)
{
- ACPI_ERROR ((AE_INFO,
- "Required field %s has zero address and/or length:"
- " 0x%8.8X%8.8X/0x%X",
+ ACPI_BIOS_ERROR ((AE_INFO,
+ "Required FADT field %s has zero address and/or length: "
+ "0x%8.8X%8.8X/0x%X",
Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
}
}
@@ -604,8 +623,8 @@
if ((Address64->Address && !Length) ||
(!Address64->Address && Length))
{
- ACPI_WARNING ((AE_INFO,
- "Optional field %s has zero address or length: "
+ ACPI_BIOS_WARNING ((AE_INFO,
+ "Optional FADT field %s has zero address or length: "
"0x%8.8X%8.8X/0x%X",
Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
}
@@ -656,8 +675,8 @@
(FadtInfoTable[i].DefaultLength > 0) &&
(FadtInfoTable[i].DefaultLength != Target64->BitWidth))
{
- ACPI_WARNING ((AE_INFO,
- "Invalid length for %s: %u, using default %u",
+ ACPI_BIOS_WARNING ((AE_INFO,
+ "Invalid length for FADT/%s: %u, using default %u",
FadtInfoTable[i].Name, Target64->BitWidth,
FadtInfoTable[i].DefaultLength));
@@ -700,7 +719,8 @@
AcpiTbInitGenericAddress (FadtPmInfoTable[i].Target,
Source64->SpaceId, Pm1RegisterByteWidth,
Source64->Address +
- (FadtPmInfoTable[i].RegisterNum * Pm1RegisterByteWidth));
+ (FadtPmInfoTable[i].RegisterNum * Pm1RegisterByteWidth),
+ "PmRegisters");
}
}
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/tables/tbinstal.c
--- a/head/sys/contrib/dev/acpica/components/tables/tbinstal.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/tables/tbinstal.c Wed Jul 25 16:45:04 2012 +0300
@@ -157,8 +157,9 @@
(!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)) &&
(ACPI_STRNCMP (TableDesc->Pointer->Signature, "OEM", 3)))
{
- ACPI_ERROR ((AE_INFO,
- "Table has invalid signature [%4.4s] (0x%8.8X), must be SSDT or OEMx",
+ ACPI_BIOS_ERROR ((AE_INFO,
+ "Table has invalid signature [%4.4s] (0x%8.8X), "
+ "must be SSDT or OEMx",
AcpiUtValidAcpiName (*(UINT32 *) TableDesc->Pointer->Signature) ?
TableDesc->Pointer->Signature : "????",
*(UINT32 *) TableDesc->Pointer->Signature));
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/tables/tbutils.c
--- a/head/sys/contrib/dev/acpica/components/tables/tbutils.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/tables/tbutils.c Wed Jul 25 16:45:04 2012 +0300
@@ -287,8 +287,9 @@
if (Checksum)
{
- ACPI_WARNING ((AE_INFO,
- "Incorrect checksum in table [%4.4s] - 0x%2.2X, should be 0x%2.2X",
+ ACPI_BIOS_WARNING ((AE_INFO,
+ "Incorrect checksum in table [%4.4s] - 0x%2.2X, "
+ "should be 0x%2.2X",
Table->Signature, Table->Checksum,
(UINT8) (Table->Checksum - Checksum)));
@@ -356,8 +357,9 @@
if (AcpiGbl_OriginalDsdtHeader.Length != AcpiGbl_DSDT->Length ||
AcpiGbl_OriginalDsdtHeader.Checksum != AcpiGbl_DSDT->Checksum)
{
- ACPI_ERROR ((AE_INFO,
- "The DSDT has been corrupted or replaced - old, new headers below"));
+ ACPI_BIOS_ERROR ((AE_INFO,
+ "The DSDT has been corrupted or replaced - "
+ "old, new headers below"));
AcpiTbPrintTableHeader (0, &AcpiGbl_OriginalDsdtHeader);
AcpiTbPrintTableHeader (0, AcpiGbl_DSDT);
@@ -460,27 +462,12 @@
return;
}
- /* Skip SSDT when DSDT is overriden */
-
- if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT) &&
- (AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Flags &
- ACPI_TABLE_ORIGIN_OVERRIDE))
- {
- ACPI_INFO ((AE_INFO,
- "%4.4s @ 0x%p Table override, replaced with:", ACPI_SIG_SSDT,
- ACPI_CAST_PTR (void, Address)));
- AcpiTbPrintTableHeader (
- AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Address,
- AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer);
- goto UnmapAndExit;
- }
-
/* If a particular signature is expected (DSDT/FACS), it must match */
if (Signature &&
!ACPI_COMPARE_NAME (Table->Signature, Signature))
{
- ACPI_ERROR ((AE_INFO,
+ ACPI_BIOS_ERROR ((AE_INFO,
"Invalid signature 0x%X for ACPI table, expected [%s]",
*ACPI_CAST_PTR (UINT32, Table->Signature), Signature));
goto UnmapAndExit;
@@ -498,6 +485,19 @@
TableDesc->Flags = ACPI_TABLE_ORIGIN_MAPPED;
ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature);
+ /* When DSDT is overriden, assume SSDT is also overriden with it */
+
+ if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT) &&
+ (AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Flags &
+ ACPI_TABLE_ORIGIN_OVERRIDE))
+ {
+ TableDesc->Flags = ACPI_TABLE_ORIGIN_OVERRIDE;
+ ACPI_INFO ((AE_INFO,
+ "%4.4s %p Logical table override, replaced with %4.4s",
+ ACPI_SIG_SSDT, ACPI_CAST_PTR (void, Address), ACPI_SIG_DSDT));
+ goto UnmapAndExit;
+ }
+
/*
* ACPI Table Override:
*
@@ -599,7 +599,7 @@
{
/* Will truncate 64-bit address to 32 bits, issue warning */
- ACPI_WARNING ((AE_INFO,
+ ACPI_BIOS_WARNING ((AE_INFO,
"64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X),"
" truncating",
ACPI_FORMAT_UINT64 (Address64)));
@@ -701,7 +701,8 @@
if (Length < sizeof (ACPI_TABLE_HEADER))
{
- ACPI_ERROR ((AE_INFO, "Invalid length 0x%X in RSDT/XSDT", Length));
+ ACPI_BIOS_ERROR ((AE_INFO,
+ "Invalid table length 0x%X in RSDT/XSDT", Length));
return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/tables/tbxface.c
--- a/head/sys/contrib/dev/acpica/components/tables/tbxface.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/tables/tbxface.c Wed Jul 25 16:45:04 2012 +0300
@@ -1,7 +1,6 @@
/******************************************************************************
*
- * Module Name: tbxface - Public interfaces to the ACPI subsystem
- * ACPI table oriented interfaces
+ * Module Name: tbxface - ACPI table oriented external interfaces
*
*****************************************************************************/
@@ -46,18 +45,11 @@
#include <contrib/dev/acpica/include/acpi.h>
#include <contrib/dev/acpica/include/accommon.h>
-#include <contrib/dev/acpica/include/acnamesp.h>
#include <contrib/dev/acpica/include/actables.h>
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME ("tbxface")
-/* Local prototypes */
-
-static ACPI_STATUS
-AcpiTbLoadNamespace (
- void);
-
/*******************************************************************************
*
@@ -458,165 +450,6 @@
/*******************************************************************************
*
- * FUNCTION: AcpiTbLoadNamespace
- *
- * PARAMETERS: None
- *
- * RETURN: Status
- *
- * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in
- * the RSDT/XSDT.
- *
- ******************************************************************************/
-
-static ACPI_STATUS
-AcpiTbLoadNamespace (
- void)
-{
- ACPI_STATUS Status;
- UINT32 i;
- ACPI_TABLE_HEADER *NewDsdt;
-
-
- ACPI_FUNCTION_TRACE (TbLoadNamespace);
-
-
- (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
-
- /*
- * Load the namespace. The DSDT is required, but any SSDT and
- * PSDT tables are optional. Verify the DSDT.
- */
- if (!AcpiGbl_RootTableList.CurrentTableCount ||
- !ACPI_COMPARE_NAME (
- &(AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Signature),
- ACPI_SIG_DSDT) ||
- ACPI_FAILURE (AcpiTbVerifyTable (
- &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT])))
- {
- Status = AE_NO_ACPI_TABLES;
- goto UnlockAndExit;
- }
-
- /*
- * Save the DSDT pointer for simple access. This is the mapped memory
- * address. We must take care here because the address of the .Tables
- * array can change dynamically as tables are loaded at run-time. Note:
- * .Pointer field is not validated until after call to AcpiTbVerifyTable.
- */
- AcpiGbl_DSDT = AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer;
-
- /*
- * Optionally copy the entire DSDT to local memory (instead of simply
- * mapping it.) There are some BIOSs that corrupt or replace the original
- * DSDT, creating the need for this option. Default is FALSE, do not copy
- * the DSDT.
- */
- if (AcpiGbl_CopyDsdtLocally)
- {
- NewDsdt = AcpiTbCopyDsdt (ACPI_TABLE_INDEX_DSDT);
- if (NewDsdt)
- {
- AcpiGbl_DSDT = NewDsdt;
- }
- }
-
- /*
- * Save the original DSDT header for detection of table corruption
- * and/or replacement of the DSDT from outside the OS.
- */
- ACPI_MEMCPY (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
- sizeof (ACPI_TABLE_HEADER));
-
- (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
-
- /* Load and parse tables */
-
- Status = AcpiNsLoadTable (ACPI_TABLE_INDEX_DSDT, AcpiGbl_RootNode);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
-
- /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
-
- (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
- for (i = 2; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
- {
- if ((!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
- ACPI_SIG_SSDT) &&
- !ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
- ACPI_SIG_PSDT)) ||
- ACPI_FAILURE (AcpiTbVerifyTable (
- &AcpiGbl_RootTableList.Tables[i])))
- {
- continue;
- }
-
- /* Skip SSDT when DSDT is overriden */
-
- if (ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
- ACPI_SIG_SSDT) &&
- (AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Flags &
- ACPI_TABLE_ORIGIN_OVERRIDE))
- {
- continue;
- }
-
- /* Ignore errors while loading tables, get as many as possible */
-
- (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
- (void) AcpiNsLoadTable (i, AcpiGbl_RootNode);
- (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
- }
-
- ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
-
-UnlockAndExit:
- (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
- return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiLoadTables
- *
- * PARAMETERS: None
- *
- * RETURN: Status
- *
- * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiLoadTables (
- void)
-{
- ACPI_STATUS Status;
-
-
- ACPI_FUNCTION_TRACE (AcpiLoadTables);
-
-
- /* Load the namespace from the tables */
-
- Status = AcpiTbLoadNamespace ();
- if (ACPI_FAILURE (Status))
- {
- ACPI_EXCEPTION ((AE_INFO, Status,
- "While loading namespace from ACPI tables"));
- }
-
- return_ACPI_STATUS (Status);
-}
-
-ACPI_EXPORT_SYMBOL (AcpiLoadTables)
-
-
-/*******************************************************************************
- *
* FUNCTION: AcpiInstallTableHandler
*
* PARAMETERS: Handler - Table event handler
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/tables/tbxfload.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/contrib/dev/acpica/components/tables/tbxfload.c Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,415 @@
+/******************************************************************************
+ *
+ * Module Name: tbxfload - Table load/unload external interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#define __TBXFLOAD_C__
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT ACPI_TABLES
+ ACPI_MODULE_NAME ("tbxfload")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiTbLoadNamespace (
+ void);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiLoadTables
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiLoadTables (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiLoadTables);
+
+
+ /* Load the namespace from the tables */
+
+ Status = AcpiTbLoadNamespace ();
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "While loading namespace from ACPI tables"));
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiLoadTables)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbLoadNamespace
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in
+ * the RSDT/XSDT.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiTbLoadNamespace (
+ void)
+{
+ ACPI_STATUS Status;
+ UINT32 i;
+ ACPI_TABLE_HEADER *NewDsdt;
+
+
+ ACPI_FUNCTION_TRACE (TbLoadNamespace);
+
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+
+ /*
+ * Load the namespace. The DSDT is required, but any SSDT and
+ * PSDT tables are optional. Verify the DSDT.
+ */
+ if (!AcpiGbl_RootTableList.CurrentTableCount ||
+ !ACPI_COMPARE_NAME (
+ &(AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Signature),
+ ACPI_SIG_DSDT) ||
+ ACPI_FAILURE (AcpiTbVerifyTable (
+ &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT])))
+ {
+ Status = AE_NO_ACPI_TABLES;
+ goto UnlockAndExit;
+ }
+
+ /*
+ * Save the DSDT pointer for simple access. This is the mapped memory
+ * address. We must take care here because the address of the .Tables
+ * array can change dynamically as tables are loaded at run-time. Note:
+ * .Pointer field is not validated until after call to AcpiTbVerifyTable.
+ */
+ AcpiGbl_DSDT = AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer;
+
+ /*
+ * Optionally copy the entire DSDT to local memory (instead of simply
+ * mapping it.) There are some BIOSs that corrupt or replace the original
+ * DSDT, creating the need for this option. Default is FALSE, do not copy
+ * the DSDT.
+ */
+ if (AcpiGbl_CopyDsdtLocally)
+ {
+ NewDsdt = AcpiTbCopyDsdt (ACPI_TABLE_INDEX_DSDT);
+ if (NewDsdt)
+ {
+ AcpiGbl_DSDT = NewDsdt;
+ }
+ }
+
+ /*
+ * Save the original DSDT header for detection of table corruption
+ * and/or replacement of the DSDT from outside the OS.
+ */
+ ACPI_MEMCPY (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
+ sizeof (ACPI_TABLE_HEADER));
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+
+ /* Load and parse tables */
+
+ Status = AcpiNsLoadTable (ACPI_TABLE_INDEX_DSDT, AcpiGbl_RootNode);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ for (i = 2; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
+ {
+ if ((!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
+ ACPI_SIG_SSDT) &&
+ !ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
+ ACPI_SIG_PSDT)) ||
+ ACPI_FAILURE (AcpiTbVerifyTable (
+ &AcpiGbl_RootTableList.Tables[i])))
+ {
+ continue;
+ }
+
+ /* Skip SSDT when it is overriden with DSDT */
+ if (ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
+ ACPI_SIG_SSDT) &&
+ (AcpiGbl_RootTableList.Tables[i].Flags &
+ ACPI_TABLE_ORIGIN_OVERRIDE))
+ {
+ continue;
+ }
+
+ /* Ignore errors while loading tables, get as many as possible */
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ (void) AcpiNsLoadTable (i, AcpiGbl_RootNode);
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiLoadTable
+ *
+ * PARAMETERS: Table - Pointer to a buffer containing the ACPI
+ * table to be loaded.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Dynamically load an ACPI table from the caller's buffer. Must
+ * be a valid ACPI table with a valid ACPI table header.
+ * Note1: Mainly intended to support hotplug addition of SSDTs.
+ * Note2: Does not copy the incoming table. User is reponsible
+ * to ensure that the table is not deleted or unmapped.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiLoadTable (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_TABLE_DESC TableDesc;
+ UINT32 TableIndex;
+
+
+ ACPI_FUNCTION_TRACE (AcpiLoadTable);
+
+
+ /* Parameter validation */
+
+ if (!Table)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Init local table descriptor */
+
+ ACPI_MEMSET (&TableDesc, 0, sizeof (ACPI_TABLE_DESC));
+ TableDesc.Address = ACPI_PTR_TO_PHYSADDR (Table);
+ TableDesc.Pointer = Table;
+ TableDesc.Length = Table->Length;
+ TableDesc.Flags = ACPI_TABLE_ORIGIN_UNKNOWN;
+
+ /* Must acquire the interpreter lock during this operation */
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Install the table and load it into the namespace */
+
+ ACPI_INFO ((AE_INFO, "Host-directed Dynamic ACPI Table Load:"));
+ Status = AcpiTbAddTable (&TableDesc, &TableIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+
+ Status = AcpiNsLoadTable (TableIndex, AcpiGbl_RootNode);
+
+ /* Invoke table handler if present */
+
+ if (AcpiGbl_TableHandler)
+ {
+ (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
+ AcpiGbl_TableHandlerContext);
+ }
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiLoadTable)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUnloadParentTable
+ *
+ * PARAMETERS: Object - Handle to any namespace object owned by
+ * the table to be unloaded
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Via any namespace object within an SSDT or OEMx table, unloads
+ * the table and deletes all namespace objects associated with
+ * that table. Unloading of the DSDT is not allowed.
+ * Note: Mainly intended to support hotplug removal of SSDTs.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUnloadParentTable (
+ ACPI_HANDLE Object)
+{
+ ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Object);
+ ACPI_STATUS Status = AE_NOT_EXIST;
+ ACPI_OWNER_ID OwnerId;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (AcpiUnloadParentTable);
+
+
+ /* Parameter validation */
+
+ if (!Object)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * The node OwnerId is currently the same as the parent table ID.
+ * However, this could change in the future.
+ */
+ OwnerId = Node->OwnerId;
+ if (!OwnerId)
+ {
+ /* OwnerId==0 means DSDT is the owner. DSDT cannot be unloaded */
+
+ return_ACPI_STATUS (AE_TYPE);
+ }
+
+ /* Must acquire the interpreter lock during this operation */
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Find the table in the global table list */
+
+ for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
+ {
+ if (OwnerId != AcpiGbl_RootTableList.Tables[i].OwnerId)
+ {
+ continue;
+ }
+
+ /*
+ * Allow unload of SSDT and OEMx tables only. Do not allow unload
+ * of the DSDT. No other types of tables should get here, since
+ * only these types can contain AML and thus are the only types
+ * that can create namespace objects.
+ */
+ if (ACPI_COMPARE_NAME (
+ AcpiGbl_RootTableList.Tables[i].Signature.Ascii,
+ ACPI_SIG_DSDT))
+ {
+ Status = AE_TYPE;
+ break;
+ }
+
+ /* Ensure the table is actually loaded */
+
+ if (!AcpiTbIsTableLoaded (i))
+ {
+ Status = AE_NOT_EXIST;
+ break;
+ }
+
+ /* Invoke table handler if present */
+
+ if (AcpiGbl_TableHandler)
+ {
+ (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD,
+ AcpiGbl_RootTableList.Tables[i].Pointer,
+ AcpiGbl_TableHandlerContext);
+ }
+
+ /*
+ * Delete all namespace objects owned by this table. Note that
+ * these objects can appear anywhere in the namespace by virtue
+ * of the AML "Scope" operator. Thus, we need to track ownership
+ * by an ID, not simply a position within the hierarchy.
+ */
+ Status = AcpiTbDeleteNamespaceByOwner (i);
+ if (ACPI_FAILURE (Status))
+ {
+ break;
+ }
+
+ Status = AcpiTbReleaseOwnerId (i);
+ AcpiTbSetTableLoadedFlag (i, FALSE);
+ break;
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiUnloadParentTable)
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/tables/tbxfroot.c
--- a/head/sys/contrib/dev/acpica/components/tables/tbxfroot.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/tables/tbxfroot.c Wed Jul 25 16:45:04 2012 +0300
@@ -234,7 +234,7 @@
/* A valid RSDP was not found */
- ACPI_ERROR ((AE_INFO, "A valid RSDP was not found"));
+ ACPI_BIOS_ERROR ((AE_INFO, "A valid RSDP was not found"));
return_ACPI_STATUS (AE_NOT_FOUND);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/utilities/utdecode.c
--- a/head/sys/contrib/dev/acpica/components/utilities/utdecode.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/utilities/utdecode.c Wed Jul 25 16:45:04 2012 +0300
@@ -51,47 +51,6 @@
ACPI_MODULE_NAME ("utdecode")
-/*******************************************************************************
- *
- * FUNCTION: AcpiFormatException
- *
- * PARAMETERS: Status - The ACPI_STATUS code to be formatted
- *
- * RETURN: A string containing the exception text. A valid pointer is
- * always returned.
- *
- * DESCRIPTION: This function translates an ACPI exception into an ASCII string
- * It is here instead of utxface.c so it is always present.
- *
- ******************************************************************************/
-
-const char *
-AcpiFormatException (
- ACPI_STATUS Status)
-{
- const char *Exception = NULL;
-
-
- ACPI_FUNCTION_ENTRY ();
-
-
- Exception = AcpiUtValidateException (Status);
- if (!Exception)
- {
- /* Exception code was not recognized */
-
- ACPI_ERROR ((AE_INFO,
- "Unknown exception code: 0x%8.8X", Status));
-
- Exception = "UNKNOWN_STATUS_CODE";
- }
-
- return (ACPI_CAST_PTR (const char, Exception));
-}
-
-ACPI_EXPORT_SYMBOL (AcpiFormatException)
-
-
/*
* Properties of the ACPI Object Types, both internal and external.
* The table is indexed by values of ACPI_OBJECT_TYPE
@@ -180,16 +139,17 @@
const char *AcpiGbl_RegionTypes[ACPI_NUM_PREDEFINED_REGIONS] =
{
- "SystemMemory",
- "SystemIO",
- "PCI_Config",
- "EmbeddedControl",
- "SMBus",
- "SystemCMOS",
- "PCIBARTarget",
- "IPMI",
- "GeneralPurposeIo",
- "GenericSerialBus"
+ "SystemMemory", /* 0x00 */
+ "SystemIO", /* 0x01 */
+ "PCI_Config", /* 0x02 */
+ "EmbeddedControl", /* 0x03 */
+ "SMBus", /* 0x04 */
+ "SystemCMOS", /* 0x05 */
+ "PCIBARTarget", /* 0x06 */
+ "IPMI", /* 0x07 */
+ "GeneralPurposeIo", /* 0x08 */
+ "GenericSerialBus", /* 0x09 */
+ "PCC" /* 0x0A */
};
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/utilities/utdelete.c
--- a/head/sys/contrib/dev/acpica/components/utilities/utdelete.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/utilities/utdelete.c Wed Jul 25 16:45:04 2012 +0300
@@ -167,7 +167,7 @@
case ACPI_TYPE_PROCESSOR:
case ACPI_TYPE_THERMAL:
- /* Walk the notify handler list for this object */
+ /* Walk the address handler list for this object */
HandlerDesc = Object->CommonNotify.Handler;
while (HandlerDesc)
@@ -523,6 +523,7 @@
ACPI_STATUS Status = AE_OK;
ACPI_GENERIC_STATE *StateList = NULL;
ACPI_OPERAND_OBJECT *NextObject = NULL;
+ ACPI_OPERAND_OBJECT *PrevObject;
ACPI_GENERIC_STATE *State;
UINT32 i;
@@ -552,10 +553,20 @@
case ACPI_TYPE_POWER:
case ACPI_TYPE_THERMAL:
- /* Update the notify objects for these types (if present) */
-
- AcpiUtUpdateRefCount (Object->CommonNotify.SystemNotify, Action);
- AcpiUtUpdateRefCount (Object->CommonNotify.DeviceNotify, Action);
+ /*
+ * Update the notify objects for these types (if present)
+ * Two lists, system and device notify handlers.
+ */
+ for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
+ {
+ PrevObject = Object->CommonNotify.NotifyList[i];
+ while (PrevObject)
+ {
+ NextObject = PrevObject->Notify.Next[i];
+ AcpiUtUpdateRefCount (PrevObject, Action);
+ PrevObject = NextObject;
+ }
+ }
break;
case ACPI_TYPE_PACKAGE:
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/utilities/utexcep.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/contrib/dev/acpica/components/utilities/utexcep.c Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ *
+ * Module Name: utexcep - Exception code support
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#define __UTEXCEP_C__
+
+#define ACPI_DEFINE_EXCEPTION_TABLE
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utexcep")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiFormatException
+ *
+ * PARAMETERS: Status - The ACPI_STATUS code to be formatted
+ *
+ * RETURN: A string containing the exception text. A valid pointer is
+ * always returned.
+ *
+ * DESCRIPTION: This function translates an ACPI exception into an ASCII
+ * string. Returns "unknown status" string for invalid codes.
+ *
+ ******************************************************************************/
+
+const char *
+AcpiFormatException (
+ ACPI_STATUS Status)
+{
+ const char *Exception = NULL;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ Exception = AcpiUtValidateException (Status);
+ if (!Exception)
+ {
+ /* Exception code was not recognized */
+
+ ACPI_ERROR ((AE_INFO,
+ "Unknown exception code: 0x%8.8X", Status));
+
+ Exception = "UNKNOWN_STATUS_CODE";
+ }
+
+ return (ACPI_CAST_PTR (const char, Exception));
+}
+
+ACPI_EXPORT_SYMBOL (AcpiFormatException)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtValidateException
+ *
+ * PARAMETERS: Status - The ACPI_STATUS code to be formatted
+ *
+ * RETURN: A string containing the exception text. NULL if exception is
+ * not valid.
+ *
+ * DESCRIPTION: This function validates and translates an ACPI exception into
+ * an ASCII string.
+ *
+ ******************************************************************************/
+
+const char *
+AcpiUtValidateException (
+ ACPI_STATUS Status)
+{
+ UINT32 SubStatus;
+ const char *Exception = NULL;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /*
+ * Status is composed of two parts, a "type" and an actual code
+ */
+ SubStatus = (Status & ~AE_CODE_MASK);
+
+ switch (Status & AE_CODE_MASK)
+ {
+ case AE_CODE_ENVIRONMENTAL:
+
+ if (SubStatus <= AE_CODE_ENV_MAX)
+ {
+ Exception = AcpiGbl_ExceptionNames_Env [SubStatus];
+ }
+ break;
+
+ case AE_CODE_PROGRAMMER:
+
+ if (SubStatus <= AE_CODE_PGM_MAX)
+ {
+ Exception = AcpiGbl_ExceptionNames_Pgm [SubStatus];
+ }
+ break;
+
+ case AE_CODE_ACPI_TABLES:
+
+ if (SubStatus <= AE_CODE_TBL_MAX)
+ {
+ Exception = AcpiGbl_ExceptionNames_Tbl [SubStatus];
+ }
+ break;
+
+ case AE_CODE_AML:
+
+ if (SubStatus <= AE_CODE_AML_MAX)
+ {
+ Exception = AcpiGbl_ExceptionNames_Aml [SubStatus];
+ }
+ break;
+
+ case AE_CODE_CONTROL:
+
+ if (SubStatus <= AE_CODE_CTRL_MAX)
+ {
+ Exception = AcpiGbl_ExceptionNames_Ctrl [SubStatus];
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return (ACPI_CAST_PTR (const char, Exception));
+}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/utilities/utglobal.c
--- a/head/sys/contrib/dev/acpica/components/utilities/utglobal.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/utilities/utglobal.c Wed Jul 25 16:45:04 2012 +0300
@@ -211,8 +211,9 @@
*
* RETURN: Status
*
- * DESCRIPTION: Init ACPICA globals. All globals that require specific
- * initialization should be initialized here!
+ * DESCRIPTION: Initialize ACPICA globals. All globals that require specific
+ * initialization should be initialized here. This allows for
+ * a warm restart.
*
******************************************************************************/
@@ -287,8 +288,8 @@
/* Global handlers */
- AcpiGbl_SystemNotify.Handler = NULL;
- AcpiGbl_DeviceNotify.Handler = NULL;
+ AcpiGbl_GlobalNotify[0].Handler = NULL;
+ AcpiGbl_GlobalNotify[1].Handler = NULL;
AcpiGbl_ExceptionHandler = NULL;
AcpiGbl_InitHandler = NULL;
AcpiGbl_TableHandler = NULL;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/utilities/utmisc.c
--- a/head/sys/contrib/dev/acpica/components/utilities/utmisc.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/utilities/utmisc.c Wed Jul 25 16:45:04 2012 +0300
@@ -53,84 +53,41 @@
ACPI_MODULE_NAME ("utmisc")
+#if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP
/*******************************************************************************
*
- * FUNCTION: AcpiUtValidateException
+ * FUNCTION: UtConvertBackslashes
*
- * PARAMETERS: Status - The ACPI_STATUS code to be formatted
+ * PARAMETERS: Pathname - File pathname string to be converted
*
- * RETURN: A string containing the exception text. NULL if exception is
- * not valid.
+ * RETURN: Modifies the input Pathname
*
- * DESCRIPTION: This function validates and translates an ACPI exception into
- * an ASCII string.
+ * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within
+ * the entire input file pathname string.
*
******************************************************************************/
-const char *
-AcpiUtValidateException (
- ACPI_STATUS Status)
+void
+UtConvertBackslashes (
+ char *Pathname)
{
- UINT32 SubStatus;
- const char *Exception = NULL;
-
- ACPI_FUNCTION_ENTRY ();
-
-
- /*
- * Status is composed of two parts, a "type" and an actual code
- */
- SubStatus = (Status & ~AE_CODE_MASK);
-
- switch (Status & AE_CODE_MASK)
+ if (!Pathname)
{
- case AE_CODE_ENVIRONMENTAL:
-
- if (SubStatus <= AE_CODE_ENV_MAX)
- {
- Exception = AcpiGbl_ExceptionNames_Env [SubStatus];
- }
- break;
-
- case AE_CODE_PROGRAMMER:
-
- if (SubStatus <= AE_CODE_PGM_MAX)
- {
- Exception = AcpiGbl_ExceptionNames_Pgm [SubStatus];
- }
- break;
-
- case AE_CODE_ACPI_TABLES:
-
- if (SubStatus <= AE_CODE_TBL_MAX)
- {
- Exception = AcpiGbl_ExceptionNames_Tbl [SubStatus];
- }
- break;
-
- case AE_CODE_AML:
-
- if (SubStatus <= AE_CODE_AML_MAX)
- {
- Exception = AcpiGbl_ExceptionNames_Aml [SubStatus];
- }
- break;
-
- case AE_CODE_CONTROL:
-
- if (SubStatus <= AE_CODE_CTRL_MAX)
- {
- Exception = AcpiGbl_ExceptionNames_Ctrl [SubStatus];
- }
- break;
-
- default:
- break;
+ return;
}
- return (ACPI_CAST_PTR (const char, Exception));
+ while (*Pathname)
+ {
+ if (*Pathname == '\\')
+ {
+ *Pathname = '/';
+ }
+
+ Pathname++;
+ }
}
+#endif
/*******************************************************************************
@@ -1295,5 +1252,3 @@
return_ACPI_STATUS (AE_AML_INTERNAL);
}
-
-
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/utilities/utobject.c
--- a/head/sys/contrib/dev/acpica/components/utilities/utobject.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/utilities/utobject.c Wed Jul 25 16:45:04 2012 +0300
@@ -366,7 +366,7 @@
*
* RETURN: TRUE if object is valid, FALSE otherwise
*
- * DESCRIPTION: Validate a pointer to be an ACPI_OPERAND_OBJECT
+ * DESCRIPTION: Validate a pointer to be of type ACPI_OPERAND_OBJECT
*
******************************************************************************/
@@ -392,7 +392,7 @@
{
case ACPI_DESC_TYPE_OPERAND:
- /* The object appears to be a valid ACPI_OPERAND_OBJECT */
+ /* The object appears to be a valid ACPI_OPERAND_OBJECT */
return (TRUE);
@@ -473,7 +473,7 @@
ACPI_FUNCTION_TRACE_PTR (UtDeleteObjectDesc, Object);
- /* Object must be an ACPI_OPERAND_OBJECT */
+ /* Object must be of type ACPI_OPERAND_OBJECT */
if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
{
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/utilities/utresrc.c
--- a/head/sys/contrib/dev/acpica/components/utilities/utresrc.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/utilities/utresrc.c Wed Jul 25 16:45:04 2012 +0300
@@ -1,6 +1,6 @@
/*******************************************************************************
*
- * Module Name: utresrc - Resource managment utilities
+ * Module Name: utresrc - Resource management utilities
*
******************************************************************************/
@@ -57,7 +57,7 @@
/*
* Strings used to decode resource descriptors.
- * Used by both the disasssembler and the debugger resource dump routines
+ * Used by both the disassembler and the debugger resource dump routines
*/
const char *AcpiGbl_BmDecode[] =
{
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/utilities/uttrack.c
--- a/head/sys/contrib/dev/acpica/components/utilities/uttrack.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/utilities/uttrack.c Wed Jul 25 16:45:04 2012 +0300
@@ -633,21 +633,21 @@
switch (ACPI_GET_DESCRIPTOR_TYPE (Descriptor))
{
case ACPI_DESC_TYPE_OPERAND:
- if (Element->Size == sizeof (ACPI_DESC_TYPE_OPERAND))
+ if (Element->Size == sizeof (ACPI_OPERAND_OBJECT))
{
DescriptorType = ACPI_DESC_TYPE_OPERAND;
}
break;
case ACPI_DESC_TYPE_PARSER:
- if (Element->Size == sizeof (ACPI_DESC_TYPE_PARSER))
+ if (Element->Size == sizeof (ACPI_PARSE_OBJECT))
{
DescriptorType = ACPI_DESC_TYPE_PARSER;
}
break;
case ACPI_DESC_TYPE_NAMED:
- if (Element->Size == sizeof (ACPI_DESC_TYPE_NAMED))
+ if (Element->Size == sizeof (ACPI_NAMESPACE_NODE))
{
DescriptorType = ACPI_DESC_TYPE_NAMED;
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/components/utilities/utxferror.c
--- a/head/sys/contrib/dev/acpica/components/utilities/utxferror.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/components/utilities/utxferror.c Wed Jul 25 16:45:04 2012 +0300
@@ -87,6 +87,9 @@
#define ACPI_MSG_WARNING "ACPI Warning: "
#define ACPI_MSG_INFO "ACPI: "
+#define ACPI_MSG_BIOS_ERROR "ACPI Firmware Error: "
+#define ACPI_MSG_BIOS_WARNING "ACPI Firmware Warning: "
+
/*
* Common message suffix
*/
@@ -257,6 +260,84 @@
ACPI_EXPORT_SYMBOL (AcpiInfo)
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiBiosError
+ *
+ * PARAMETERS: ModuleName - Caller's module name (for error output)
+ * LineNumber - Caller's line number (for error output)
+ * Format - Printf format string + additional args
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print "ACPI Firmware Error" message with module/line/version
+ * info
+ *
+ ******************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE
+AcpiBiosError (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ const char *Format,
+ ...)
+{
+ va_list ArgList;
+
+
+ ACPI_MSG_REDIRECT_BEGIN;
+ AcpiOsPrintf (ACPI_MSG_BIOS_ERROR);
+
+ va_start (ArgList, Format);
+ AcpiOsVprintf (Format, ArgList);
+ ACPI_MSG_SUFFIX;
+ va_end (ArgList);
+
+ ACPI_MSG_REDIRECT_END;
+}
+
+ACPI_EXPORT_SYMBOL (AcpiBiosError)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiBiosWarning
+ *
+ * PARAMETERS: ModuleName - Caller's module name (for error output)
+ * LineNumber - Caller's line number (for error output)
+ * Format - Printf format string + additional args
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print "ACPI Firmware Warning" message with module/line/version
+ * info
+ *
+ ******************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE
+AcpiBiosWarning (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ const char *Format,
+ ...)
+{
+ va_list ArgList;
+
+
+ ACPI_MSG_REDIRECT_BEGIN;
+ AcpiOsPrintf (ACPI_MSG_BIOS_WARNING);
+
+ va_start (ArgList, Format);
+ AcpiOsVprintf (Format, ArgList);
+ ACPI_MSG_SUFFIX;
+ va_end (ArgList);
+
+ ACPI_MSG_REDIRECT_END;
+}
+
+ACPI_EXPORT_SYMBOL (AcpiBiosWarning)
+
+
/*
* The remainder of this module contains internal error functions that may
* be configured out.
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/include/acdebug.h
--- a/head/sys/contrib/dev/acpica/include/acdebug.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/include/acdebug.h Wed Jul 25 16:45:04 2012 +0300
@@ -112,8 +112,7 @@
void
AcpiDbUnloadAcpiTable (
- char *TableArg,
- char *InstanceArg);
+ char *Name);
void
AcpiDbSendNotify (
@@ -405,7 +404,7 @@
char *Name);
void
-AcpiDbUInt32ToHexString (
+AcpiDbUint32ToHexString (
UINT32 Value,
char *Buffer);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/include/acdisasm.h
--- a/head/sys/contrib/dev/acpica/include/acdisasm.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/include/acdisasm.h Wed Jul 25 16:45:04 2012 +0300
@@ -519,6 +519,14 @@
ACPI_PARSE_OBJECT *Op);
void
+AcpiDmPredefinedDescription (
+ ACPI_PARSE_OBJECT *Op);
+
+void
+AcpiDmFieldPredefinedDescription (
+ ACPI_PARSE_OBJECT *Op);
+
+void
AcpiDmFieldFlags (
ACPI_PARSE_OBJECT *Op);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/include/acexcep.h
--- a/head/sys/contrib/dev/acpica/include/acexcep.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/include/acexcep.h Wed Jul 25 16:45:04 2012 +0300
@@ -53,6 +53,7 @@
#define AE_CODE_ACPI_TABLES 0x2000
#define AE_CODE_AML 0x3000
#define AE_CODE_CONTROL 0x4000
+#define AE_CODE_MAX 0x4000
#define AE_CODE_MASK 0xF000
@@ -188,7 +189,7 @@
/* Exception strings for AcpiFormatException */
-#ifdef DEFINE_ACPI_GLOBALS
+#ifdef ACPI_DEFINE_EXCEPTION_TABLE
/*
* String versions of the exception codes above
@@ -307,6 +308,6 @@
"AE_CTRL_PARSE_PENDING"
};
-#endif /* ACPI GLOBALS */
+#endif /* EXCEPTION_TABLE */
#endif /* __ACEXCEP_H__ */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/include/acglobal.h
--- a/head/sys/contrib/dev/acpica/include/acglobal.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/include/acglobal.h Wed Jul 25 16:45:04 2012 +0300
@@ -254,8 +254,7 @@
/* Global handlers */
-ACPI_EXTERN ACPI_OBJECT_NOTIFY_HANDLER AcpiGbl_DeviceNotify;
-ACPI_EXTERN ACPI_OBJECT_NOTIFY_HANDLER AcpiGbl_SystemNotify;
+ACPI_EXTERN ACPI_GLOBAL_NOTIFY_HANDLER AcpiGbl_GlobalNotify[2];
ACPI_EXTERN ACPI_EXCEPTION_HANDLER AcpiGbl_ExceptionHandler;
ACPI_EXTERN ACPI_INIT_HANDLER AcpiGbl_InitHandler;
ACPI_EXTERN ACPI_TABLE_HANDLER AcpiGbl_TableHandler;
@@ -288,17 +287,8 @@
ACPI_EXTERN ACPI_INTERFACE_INFO *AcpiGbl_SupportedInterfaces;
ACPI_EXTERN ACPI_ADDRESS_RANGE *AcpiGbl_AddressRangeList[ACPI_ADDRESS_RANGE_MAX];
-
#ifndef DEFINE_ACPI_GLOBALS
-/* Exception codes */
-
-extern char const *AcpiGbl_ExceptionNames_Env[];
-extern char const *AcpiGbl_ExceptionNames_Pgm[];
-extern char const *AcpiGbl_ExceptionNames_Tbl[];
-extern char const *AcpiGbl_ExceptionNames_Aml[];
-extern char const *AcpiGbl_ExceptionNames_Ctrl[];
-
/* Other miscellaneous */
extern BOOLEAN AcpiGbl_Shutdown;
@@ -480,4 +470,14 @@
#endif /* ACPI_DEBUGGER */
+
+/*****************************************************************************
+ *
+ * Info/help support
+ *
+ ****************************************************************************/
+
+extern const AH_PREDEFINED_NAME AslPredefinedInfo[];
+
+
#endif /* __ACGLOBAL_H__ */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/include/aclocal.h
--- a/head/sys/contrib/dev/acpica/include/aclocal.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/include/aclocal.h Wed Jul 25 16:45:04 2012 +0300
@@ -462,6 +462,15 @@
} ACPI_GPE_HANDLER_INFO;
+/* Notify info for implicit notify, multiple device objects */
+
+typedef struct acpi_gpe_notify_info
+{
+ ACPI_NAMESPACE_NODE *DeviceNode; /* Device to be notified */
+ struct acpi_gpe_notify_info *Next;
+
+} ACPI_GPE_NOTIFY_INFO;
+
/*
* GPE dispatch info. At any time, the GPE can have at most one type
* of dispatch - Method, Handler, or Implicit Notify.
@@ -469,8 +478,8 @@
typedef union acpi_gpe_dispatch_info
{
ACPI_NAMESPACE_NODE *MethodNode; /* Method node for this GPE level */
- struct acpi_gpe_handler_info *Handler; /* Installed GPE handler */
- ACPI_NAMESPACE_NODE *DeviceNode; /* Parent _PRW device for implicit notify */
+ ACPI_GPE_HANDLER_INFO *Handler; /* Installed GPE handler */
+ ACPI_GPE_NOTIFY_INFO *NotifyList; /* List of _PRW devices for implicit notifies */
} ACPI_GPE_DISPATCH_INFO;
@@ -480,7 +489,7 @@
*/
typedef struct acpi_gpe_event_info
{
- union acpi_gpe_dispatch_info Dispatch; /* Either Method or Handler */
+ union acpi_gpe_dispatch_info Dispatch; /* Either Method, Handler, or NotifyList */
struct acpi_gpe_register_info *RegisterInfo; /* Backpointer to register info */
UINT8 Flags; /* Misc info about this GPE */
UINT8 GpeNumber; /* This GPE */
@@ -716,6 +725,15 @@
struct acpi_walk_state *WalkState);
+/* Global handlers for AML Notifies */
+
+typedef struct acpi_global_notify_handler
+{
+ ACPI_NOTIFY_HANDLER Handler;
+ void *Context;
+
+} ACPI_GLOBAL_NOTIFY_HANDLER;
+
/*
* Notify info - used to pass info to the deferred notify
* handler/dispatcher.
@@ -723,8 +741,10 @@
typedef struct acpi_notify_info
{
ACPI_STATE_COMMON
+ UINT8 HandlerListId;
ACPI_NAMESPACE_NODE *Node;
- union acpi_operand_object *HandlerObj;
+ union acpi_operand_object *HandlerListHead;
+ ACPI_GLOBAL_NOTIFY_HANDLER *Global;
} ACPI_NOTIFY_INFO;
@@ -949,6 +969,7 @@
#define ACPI_PARSEOP_IGNORE 0x01
#define ACPI_PARSEOP_PARAMLIST 0x02
#define ACPI_PARSEOP_EMPTY_TERMLIST 0x04
+#define ACPI_PARSEOP_PREDEF_CHECKED 0x08
#define ACPI_PARSEOP_SPECIAL 0x10
@@ -1300,4 +1321,20 @@
#define ACPI_NUM_MEM_LISTS 2
+/*****************************************************************************
+ *
+ * Info/help support
+ *
+ ****************************************************************************/
+
+typedef struct ah_predefined_name
+{
+ char *Name;
+ char *Description;
+#ifndef ACPI_ASL_COMPILER
+ char *Action;
+#endif
+
+} AH_PREDEFINED_NAME;
+
#endif /* __ACLOCAL_H__ */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/include/acmacros.h
--- a/head/sys/contrib/dev/acpica/include/acmacros.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/include/acmacros.h Wed Jul 25 16:45:04 2012 +0300
@@ -274,8 +274,8 @@
#define ACPI_INSERT_BITS(Target, Mask, Source) Target = ((Target & (~(Mask))) | (Source & Mask))
/*
- * An ACPI_NAMESPACE_NODE can appear in some contexts
- * where a pointer to an ACPI_OPERAND_OBJECT can also
+ * An object of type ACPI_NAMESPACE_NODE can appear in some contexts
+ * where a pointer to an object of type ACPI_OPERAND_OBJECT can also
* appear. This macro is used to distinguish them.
*
* The "Descriptor" field is the first field in both structures.
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/include/acobject.h
--- a/head/sys/contrib/dev/acpica/include/acobject.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/include/acobject.h Wed Jul 25 16:45:04 2012 +0300
@@ -94,7 +94,7 @@
#define AOPOBJ_AML_CONSTANT 0x01 /* Integer is an AML constant */
#define AOPOBJ_STATIC_POINTER 0x02 /* Data is part of an ACPI table, don't delete */
-#define AOPOBJ_DATA_VALID 0x04 /* Object is intialized and data is valid */
+#define AOPOBJ_DATA_VALID 0x04 /* Object is initialized and data is valid */
#define AOPOBJ_OBJECT_INITIALIZED 0x08 /* Region is initialized, _REG was run */
#define AOPOBJ_SETUP_COMPLETE 0x10 /* Region setup is complete */
#define AOPOBJ_INVALID 0x20 /* Host OS won't allow a Region address */
@@ -123,8 +123,8 @@
/*
- * Note: The String and Buffer object must be identical through the Pointer
- * and length elements. There is code that depends on this.
+ * Note: The String and Buffer object must be identical through the
+ * pointer and length elements. There is code that depends on this.
*
* Fields common to both Strings and Buffers
*/
@@ -246,8 +246,7 @@
* Common fields for objects that support ASL notifications
*/
#define ACPI_COMMON_NOTIFY_INFO \
- union acpi_operand_object *SystemNotify; /* Handler for system notifies */\
- union acpi_operand_object *DeviceNotify; /* Handler for driver notifies */\
+ union acpi_operand_object *NotifyList[2]; /* Handlers for system/device notifies */\
union acpi_operand_object *Handler; /* Handler for Address space */
@@ -389,8 +388,10 @@
{
ACPI_OBJECT_COMMON_HEADER
ACPI_NAMESPACE_NODE *Node; /* Parent device */
- ACPI_NOTIFY_HANDLER Handler;
+ UINT32 HandlerType; /* Type: Device/System/Both */
+ ACPI_NOTIFY_HANDLER Handler; /* Handler address */
void *Context;
+ union acpi_operand_object *Next[2]; /* Device and System handler lists */
} ACPI_OBJECT_NOTIFY_HANDLER;
@@ -404,7 +405,7 @@
ACPI_NAMESPACE_NODE *Node; /* Parent device */
void *Context;
ACPI_ADR_SPACE_SETUP Setup;
- union acpi_operand_object *RegionList; /* regions using this handler */
+ union acpi_operand_object *RegionList; /* Regions using this handler */
union acpi_operand_object *Next;
} ACPI_OBJECT_ADDR_HANDLER;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/include/acoutput.h
--- a/head/sys/contrib/dev/acpica/include/acoutput.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/include/acoutput.h Wed Jul 25 16:45:04 2012 +0300
@@ -217,6 +217,8 @@
#define ACPI_WARNING(plist) AcpiWarning plist
#define ACPI_EXCEPTION(plist) AcpiException plist
#define ACPI_ERROR(plist) AcpiError plist
+#define ACPI_BIOS_WARNING(plist) AcpiBiosWarning plist
+#define ACPI_BIOS_ERROR(plist) AcpiBiosError plist
#define ACPI_DEBUG_OBJECT(obj,l,i) AcpiExDoDebugObject(obj,l,i)
#else
@@ -227,6 +229,8 @@
#define ACPI_WARNING(plist)
#define ACPI_EXCEPTION(plist)
#define ACPI_ERROR(plist)
+#define ACPI_BIOS_WARNING(plist)
+#define ACPI_BIOS_ERROR(plist)
#define ACPI_DEBUG_OBJECT(obj,l,i)
#endif /* ACPI_NO_ERROR_MESSAGES */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/include/acpiosxf.h
--- a/head/sys/contrib/dev/acpica/include/acpiosxf.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/include/acpiosxf.h Wed Jul 25 16:45:04 2012 +0300
@@ -275,7 +275,7 @@
void
AcpiOsWaitEventsComplete (
- void *Context);
+ void);
void
AcpiOsSleep (
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/include/acpixf.h
--- a/head/sys/contrib/dev/acpica/include/acpixf.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/include/acpixf.h Wed Jul 25 16:45:04 2012 +0300
@@ -48,7 +48,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
-#define ACPI_CA_VERSION 0x20120320
+#define ACPI_CA_VERSION 0x20120711
#include <contrib/dev/acpica/include/acconfig.h>
#include <contrib/dev/acpica/include/actypes.h>
@@ -201,6 +201,22 @@
/*
+ * ACPI table load/unload interfaces
+ */
+ACPI_STATUS
+AcpiLoadTable (
+ ACPI_TABLE_HEADER *Table);
+
+ACPI_STATUS
+AcpiUnloadParentTable (
+ ACPI_HANDLE Object);
+
+ACPI_STATUS
+AcpiLoadTables (
+ void);
+
+
+/*
* ACPI table manipulation interfaces
*/
ACPI_STATUS
@@ -212,10 +228,6 @@
ACPI_SIZE *RsdpAddress);
ACPI_STATUS
-AcpiLoadTables (
- void);
-
-ACPI_STATUS
AcpiGetTableHeader (
ACPI_STRING Signature,
UINT32 Instance,
@@ -757,6 +769,20 @@
const char *Format,
...) ACPI_PRINTF_LIKE(3);
+void ACPI_INTERNAL_VAR_XFACE
+AcpiBiosError (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ const char *Format,
+ ...) ACPI_PRINTF_LIKE(3);
+
+void ACPI_INTERNAL_VAR_XFACE
+AcpiBiosWarning (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ const char *Format,
+ ...) ACPI_PRINTF_LIKE(3);
+
/*
* Debug output
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/include/acpredef.h
--- a/head/sys/contrib/dev/acpica/include/acpredef.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/include/acpredef.h Wed Jul 25 16:45:04 2012 +0300
@@ -512,14 +512,14 @@
{{"_TMP", 0, ACPI_RTYPE_INTEGER}},
{{"_TPC", 0, ACPI_RTYPE_INTEGER}},
{{"_TPT", 1, 0}},
- {{"_TRT", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each 2Ref/6Int */
+ {{"_TRT", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each 2 Ref/6 Int */
{{{ACPI_PTYPE2, ACPI_RTYPE_REFERENCE, 2, ACPI_RTYPE_INTEGER}, 6, 0}},
- {{"_TSD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each 5Int with count */
+ {{"_TSD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each 5 Int with count */
{{{ACPI_PTYPE2_COUNT,ACPI_RTYPE_INTEGER, 5,0}, 0,0}},
{{"_TSP", 0, ACPI_RTYPE_INTEGER}},
- {{"_TSS", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each 5Int */
+ {{"_TSS", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each 5 Int */
{{{ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 5,0}, 0,0}},
{{"_TST", 0, ACPI_RTYPE_INTEGER}},
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/include/actbl1.h
--- a/head/sys/contrib/dev/acpica/include/actbl1.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/include/actbl1.h Wed Jul 25 16:45:04 2012 +0300
@@ -130,7 +130,7 @@
{
ACPI_TABLE_HEADER Header; /* Common ACPI table header */
UINT32 RegionLength; /* Length of the boot error region */
- UINT64 Address; /* Physical addresss of the error region */
+ UINT64 Address; /* Physical address of the error region */
} ACPI_TABLE_BERT;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/include/actypes.h
--- a/head/sys/contrib/dev/acpica/include/actypes.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/include/actypes.h Wed Jul 25 16:45:04 2012 +0300
@@ -708,10 +708,14 @@
#define ACPI_DEVICE_NOTIFY 0x2
#define ACPI_ALL_NOTIFY (ACPI_SYSTEM_NOTIFY | ACPI_DEVICE_NOTIFY)
#define ACPI_MAX_NOTIFY_HANDLER_TYPE 0x3
+#define ACPI_NUM_NOTIFY_TYPES 2
#define ACPI_MAX_SYS_NOTIFY 0x7F
#define ACPI_MAX_DEVICE_SPECIFIC_NOTIFY 0xBF
+#define ACPI_SYSTEM_HANDLER_LIST 0 /* Used as index, must be SYSTEM_NOTIFY -1 */
+#define ACPI_DEVICE_HANDLER_LIST 1 /* Used as index, must be DEVICE_NOTIFY -1 */
+
/* Address Space (Operation Region) Types */
@@ -727,8 +731,9 @@
#define ACPI_ADR_SPACE_IPMI (ACPI_ADR_SPACE_TYPE) 7
#define ACPI_ADR_SPACE_GPIO (ACPI_ADR_SPACE_TYPE) 8
#define ACPI_ADR_SPACE_GSBUS (ACPI_ADR_SPACE_TYPE) 9
+#define ACPI_ADR_SPACE_PLATFORM_COMM (ACPI_ADR_SPACE_TYPE) 10
-#define ACPI_NUM_PREDEFINED_REGIONS 10
+#define ACPI_NUM_PREDEFINED_REGIONS 11
/*
* Special Address Spaces
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/include/acutils.h
--- a/head/sys/contrib/dev/acpica/include/acutils.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/include/acutils.h Wed Jul 25 16:45:04 2012 +0300
@@ -429,7 +429,7 @@
UINT8 *Buffer,
UINT32 Count,
UINT32 Display,
- UINT32 componentId);
+ UINT32 ComponentId);
void
AcpiUtDumpBuffer2 (
@@ -703,6 +703,10 @@
/*
* utmisc
*/
+void
+UtConvertBackslashes (
+ char *Pathname);
+
const char *
AcpiUtValidateException (
ACPI_STATUS Status);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/include/platform/acenv.h
--- a/head/sys/contrib/dev/acpica/include/platform/acenv.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/include/platform/acenv.h Wed Jul 25 16:45:04 2012 +0300
@@ -108,9 +108,9 @@
#endif
#ifdef ACPI_HELP_APP
-#define ACPI_DEBUG_OUTPUT
#define ACPI_APPLICATION
#define ACPI_SINGLE_THREADED
+#define ACPI_NO_ERROR_MESSAGES
#endif
/* Linkable ACPICA library */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/acpica/os_specific/service_layers/osunixxf.c
--- a/head/sys/contrib/dev/acpica/os_specific/service_layers/osunixxf.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/dev/acpica/os_specific/service_layers/osunixxf.c Wed Jul 25 16:45:04 2012 +0300
@@ -1241,3 +1241,24 @@
}
#endif /* ACPI_SINGLE_THREADED */
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsWaitEventsComplete
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Wait for all asynchronous events to complete. This
+ * implementation does nothing.
+ *
+ *****************************************************************************/
+
+void
+AcpiOsWaitEventsComplete (
+ void)
+{
+ return;
+}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/iwn/iwlwifi-6000g2a-17.168.5.3.fw.uu
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/contrib/dev/iwn/iwlwifi-6000g2a-17.168.5.3.fw.uu Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,7833 @@
+Copyright (c) 2006-2011, Intel Corporation.
+All rights reserved.
+
+Redistribution. Redistribution and use in binary form, without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions must reproduce the above copyright notice and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+* Neither the name of Intel Corporation nor the names of its suppliers
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+* No reverse engineering, decompilation, or disassembly of this software
+ is permitted.
+
+Limited patent license. Intel Corporation grants a world-wide,
+royalty-free, non-exclusive license under patents it now or hereafter
+owns or controls to make, have made, use, import, offer to sell and
+sell ("Utilize") this software, but solely to the extent that any
+such patent is necessary to Utilize the software alone, or in
+combination with an operating system licensed under an approved Open
+Source license as listed by the Open Source Initiative at
+http://opensource.org/licenses. The patent license shall not apply to
+any other combinations which include this software. No hardware per
+se is licensed hereunder.
+
+DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER 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.
+begin-base64 644 iwlwifi-6000g2a.17.168.5.3.fw.uu
+AAAAAElXTAo2MDAwZzJhIGZ3IHYxNy4xNjguNS4zIGJ1aWxkIDQyMzAxCgAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAwWoET2lAAABAAAAAAAAAAEAAAAASAIAICCADwAAQABpIAAAaSBAAGkg
+AABpIEAAICCADwAA6ABpIAAAaSBAAGkgAABpIEAAICCADwAApPZpIAAAaSBAAGkgAABKIAAASiEA
+AEoiAABKIwAASiQAAEolAABKJgAASicAAEogABBKIQAQSiIAEEojABBKJAAQSiUAEEomABBKJwAQ
+SiAAIEohACBKIgAgSiMAIEokACBKJQAgSiYAIEonACBKIAAwSiEAMAokgD+BAABAQSycMEAsnDBC
+JBw0CiKAP4AAWG8KIwA3xgpAB0omAHBpIEAASiYAcEomAHBKJgBwSiYAcAAWAHCAAFQcQHggIECH
+AAAAAAAAAAAAAPwciLb8HEi2/BwItvwcyLX8HIi1/BxItfwcCLX8HMi0/ByItPwcSLT8HAi0/BzI
+s/wciLP8HEiz4H7geATcON018OB4BNw03TPw4HgE3DDdMfDgeATcLN0v8OB4BNwo3S3w4HgE3CTd
+K/DgeATcIN0p8OB4BNwc3Sfw4HgE3BjdJfDgeATcFN0j8OB4BNwQ3SHw4HgE3AzdH/DgeATcCN0c
+8OB4BNwE3RnwNBQaMDAUGTAsFBgwKBQXMCQUFjAgFBUwHBQUMBgUEzAUFBIwEBQRMAwUEDACxwHG
+sCRNM7AkHzPgfvHATg/P/89xoACsLxiBz3WgAMgfIN6auBihBdjQpUMdGBAA2DYI4BGNuNGljQfP
+//HAHg/P/89xoACsLxiBz3WgAMgfIN6zuLq4GKFk2NClQx0YEADYBgjgEY240aVdB8//4HjgfuB4
+4H7geOB+4HjgfuB4CiJAgADZ7gABAC8mAPBKJkAATgAGAE8AIACKJf8P4HgKIkCAANnOAAEAbAAk
+AC8mAPBcAAUAKwg1CEomQAAIcQDYAiG+gOAgxQdCeQHgAiG+gOAgxQdCeesH7/8B4C8tAQBAJUUA
+AiZ88QAAIAAAKEAB6CBiAy8gAIAvIUsAAiG+gMAghgHCIYYA4H4RACAASiAAEEogQBAOIkIALyAL
+Es4gRYCKJf8PCAAFAC8tAQBAJUUAAiZ88QAAIAAAKEABSiZAAOggIgMvIACALyFLAAIhvoDAIIYB
+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
+D/QhwQPhDyBAAAMUgTAD4Q8gQAACFIEwA+EPIEAACRSBMIHhDvQCFIEwCrlPIQIEAxSBMAy5JXoh
+wQ65RXkleCDBgeEI9AcUgTAiwga5CLpFeSV44H+jwKPB4cVCwQkUgTBDwoPhQcAA2Ar2gOHI9goU
+gTCA4cT2g+HD9gHYBxSCMAYUgzBQcwbyIsEwc8wiQoAD9AHYIcWB5RD0ChSBMCPDcHFK9gsUgjBQ
+ccwjqoCE9oDiyiBpAIHgDfSKIckPz3CAAEAHIKCB5f/ZyiEiACGgwcXgf6PA8cCGCc/+z3aAAMQH
+ABYFEEwlQII8AAYAz3eAAMxbAIahhgi4IIcFfTB1CfIQuYogSwVeCCAGpXmgpyCGz3CAAIBq8CBA
+AEB4gODr86EBz/4KIcAP63LPcAAAhidj220BIABKJIAA4HiiweHFQsFBKAICB3pBKAEER3nPcoAA
+kMXGuSpi57oS9AgUAzHPdYAAkMipcVZ5QIFQcAX0QpFwcgbyR4nnuvfzgNgD8AaJwcXgf6LA8cDW
+CO/+uHBKJEAAkODKIsoHyiCKDwAAzhvKI4oPAAD8APQAKgDKIcoPQC1DAcdzgAAQxsaLjCYCkADY
+DfLPcIAAkMgWII0DoIWgoSaLNngCkACyiHDtAM/+4HjgfuB48cAIyJW4CBoYMAnIm7gJGhgwC8iK
+uI24kLgLGhgwz3CAAMgdA4AYiIHgDPQLyM9xAABILqy4CxoYMAYMYAYP2GfYOg/gBYohCADRwOB+
+4HjxwOHFCHU+iM9wgADoE0CAQCUAFAO5NXlZYaIPYA0K2o4P7/+pcHUAz/7gePHA4cXPcoAATDmE
+EgAAgBIBAM91oADIHyR4LykBAM9wAwBADUUdGBDwIkAAQHiA2BUdGJA5AM/+8cClwUHAQsEMHAAx
+EBxAMc9xgAD8kjQZwA8wGQAPLBnADigZgA4kGUAOz3CAAPySIBhAC89wgAD8khwYAAvPcIAA/JIY
+GMAKz3CAAPySFBiACs9wgAD8khAYwAjPcIAA/JIMGIAIz3CAAPySCBhACM9xgACAkoAZAAh8GcAH
+eBmAB3QZQAdwGQAHbBkAB2gZgAZkGUAGYBkABlwZwAVYGYAFVBlABVAZAAVMGcAESBmABEQZQARA
+GQAE76HOoa2hjKEsGcACKBmAAiQZQAIgGQACHBnAARgZgAEUGUABEBkAAWOhaiAAA9gZAABqIMAC
+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
+1AEGANABAAB+ADwA4wA8AHgASQDdAEkAfwBaAOQAWgCqAD8AqwABAA8BPwAQAQEAeQBqAN4AagCo
+AAAADQEAAKYANwCnAAEACwE3AAwBAQAEAAgAnAHMAJ0BzADVAcwA1gHMALQAIAAZASAAMQIMADIC
+DAAzAr0ANgIMADcCDAA4Ar0AoACIAAUBiAChANUABgHVAKIABAAHAQQAjwCIAPQAiACQACIA9QAi
+AJEABAD2AAQAnwAMAPsADACUAAAAlQAAAJwAlQCdANAAmgCKAJgAEQCWADMAlwB3AJQAAQCVAAEA
+nACVAJ0A0ACaAIoAmAARAJYAMwCXAHcAlAACAJUAAwCcAJUAnQDQAJoAigCYABEAlgAzAJcAdwCU
+AAMAlQAHAJwAlQCdANAAmgCKAJgAEQCWADMAlwB3APoAAAD5AAAAAgGVAAMB0AAAAYoA/gARAPwA
+MwD9AHcA+gABAPkAAQACAZUAAwHQAAABigD+ABEA/AAzAP0AdwD6AAIA+QADAAIBlQADAdAAAAGK
+AP4AEQD8ADMA/QB3APoAAwD5AAcAAgGVAAMB0AAAAYoA/gARAPwAMwD9AHcAhQAAAIYAAACHAFUA
+iAAAAIkAqgCKAAAAiwDdAIwAAACFAAEAhgABAIcAVQCIAAAAiQCqAIoAAACLAN0AjAAAAIUAAgCG
+AAMAhwBVAIgAAACJAKoAigAAAIsA3QCMAAAAhQADAIYABwCHAFUAiAAAAIkAqgCKAAAAiwDdAIwA
+AADrAAAA6gAAAOwAVQDtAAAA7gCqAO8AAADwAN0A8QAAAOsAAQDqAAEA7ABVAO0AAADuAKoA7wAA
+APAA3QDxAAAA6wACAOoAAwDsAFUA7QAAAO4AqgDvAAAA8ADdAPEAAADrAAMA6gAHAOwAVQDtAAAA
+7gCqAO8AAADwAN0A8QAAAPv/AAAAAAIADdIS0hPSFNIM0hXSC9IC0hHSBEMAEBQQCRAREAFAG9Ic
+0gDSCgALAAQADgC1ABoBDwBCALwAwwAhASgBtgC3ALgAuQC9AL4AvwDAABsBHAEdAR4BIgEjASQB
+JQEKAAAACwAAAAwAAAC2AAAAtwAAALgAAAC5AAAAGwEAABwBAAAdAQAAHgEAALYAAAC3AAAAuAAA
+ALkAAAAbAQAAHAEAAB0BAAAeAQAAvQAAAL4AAAC/AAAAwAAAACIBAAAjAQAAJAEAACUBAAC9AAAA
+vgAAAL8AAADAAAAAIgEAACMBAAAkAQAAJQEAABLSAAAT0gAAFNIAAAAAAQACAAMALABkAHQAgACM
+AKEABwAAAAAAAQACAAMAAAAAALcTIgC4FCMAuRUkALsWJQC8FyYAvRgnAMAZKADEGikABxsAAAgc
+AQALHQIADB4DABAfBAAiIQUAJCIGACYjBwAoJAgAKiUJACwmCgAuJwsAMCgMADQpDQA4Kg4APCsP
+AEAsEABkLhEAaC8SAGwwEwBwMRQAdDIVAHgzFgB8NBcAgDUYAIQ2GQCINxoAjDgbAJE6HACVOx0A
+mTweAJ09HwChPiAApT8hACRJBgIsSgoCNEsNATxMDwFkTREBbE4TAXRPFQF8UBcBhFEZAZVSHQGd
+Ux8BAQQAAAIFAQADBgIABAcDAAUIBAAGCQUABwoGAAgLBwAJDAgACg0JAAsOCgAMDwsADRAMAA4R
+DQABQAAEAkEBBANCAgQEQwMEBUQEBAZFBQQHRgYECEcHBAlICAQAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAHCAAAAAAACyDMgA/////////wAB//8CA////wT//////////////////////wX/Bv8H
+/wj/Cf8K/wv/DP///w3///8O////D////xD/////////////////////////////////////////
+/////xH///8S////E////xT///8V////Fv///xf///8Y////Gf///xr///8b/////xz///8d////
+Hv///x////8g////If//////////////////////IiMk/yUmJ///KP///yn/////////////////
+/////////////////////////////////////////////////////////////5ilgABgwgEA9AaA
+AECmgAAYAAAAAKaAAAAAAAAAAAAAAAEBAQAAAAAAAQAAAAAAAAAAAAAAAAAAAwAAAAEAAAAAAAAA
+AwAAAMzfAQACAAAACP8BAAQAAADI3wEABQAAAJjfAQAGAAAAiJ0AABIAAACoJwAACAAAAPzNAAAJ
+AAAAdDYAAA0AAAAgKwAADgAAAPTtAAAPAAAARNYBABgAAABcFAEADAAAAHjGAAAWAAAANN0BABAA
+AABESAEAEQAAAFgCAgABAAAAmGoAABMAAADQ0wEAFAAAABzlAQAHAAAAXF4AABUAAAAEZQEAFwAA
+AMyPAQAZAAAAsPMAAAAUBQAAAAAAAAAAAAAAAAAAAAAA/wD/AAAAAAAABwAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMSWAADE
+lgAAxJYAAFh8AADElgAAxJYAALx8AADElgAAxJYAAMSWAADElgAAxJYAAMSWAADElgAAxJYAAMSW
+AABUiAAApIcAAJSHAAAkhwAAwIcAAOCGAADElgAAxJYAACSOAADokAAAOJIAAMSWAADElgAAxJYA
+ACyWAABgjQAAmI0AAASNAADElgAAxJYAAMSWAADolQAAxJYAAOSMAADElgAAxJYAAMSWAADElgAA
+xJYAAMSWAADElgAAxJYAAMh8AADElgAAxJYAAMSWAADElgAAxJYAAMSWAADElgAAxJYAAMSWAADE
+lgAAxJYAAMSWAADElgAAxJYAAMSWAADElgAAxJYAAMSWAADElgAAxJYAAMSWAADElgAAxJYAAASA
+AADElgAAxJYAAMSWAADElgAAxJYAAEiTAADElgAAxJYAAMSWAADElgAAxJYAAMSWAADElgAAxJYA
+AMSWAADElgAAxJYAAFB6AADElgAADHoAAMSWAADElgAAxJYAAMSWAADElgAAxJYAAMSWAADElgAA
+lHkAAMSWAADElgAAxJYAAMSWAADElgAAxJYAAMSWAADElgAAxJYAAMSWAADElgAAbIEAAOSAAADE
+lgAAiIEAAMSWAAAkgAAAkIUAAMSWAADElgAAdIgAAMSWAADElgAAxJYAAMSWAADElgAABIoAAKSI
+AADElgAAxJYAAMSWAADElgAAxJYAAMSWAADElgAAxJYAAMSWAADElgAAxJYAAFyDAADElgAAxJYA
+AMSWAADwkgAAxJYAANx+AADElgAAfJUAAMSWAADglQAAsJIAAMSWAADElgAATHgAAHCSAADElgAA
+xJYAAMSWAAAshwAAxJYAAMSWAAAYgwAAnHoAAMSWAADElgAAxJYAAKCNAABAhgAAxJYAAMSWAADE
+lgAAxJYAAMSWAADElgAA8IQAAMSWAADklwAAHJoAAEyZAAAkmgAARJkAADyZAAAsmgAA6JYAAMSW
+AADElgAAxJYAAMSWAADElgAAxJYAAMSWAADElgAAIIMAAMSWAADElgAAxJYAAMSWAADElgAAxJYA
+AMSWAADAmgAA1JsAAKx4AAAIeQAAxJYAAJR4AADElgAAxJYAAMSWAADElgAAxJYAAMSWAADElgAA
+xJYAAMSWAADElgAAxJYAAMSWAADElgAAxJYAAMSWAADElgAAxJYAAMSWAADElgAAxJYAAMSWAADE
+lgAAxJYAAMSWAADElgAAxJYAAMSWAADElgAAxJYAAMSWAADElgAAxJYAANB6AACkewAARHsAADSa
+AAAgeQAAMHwAAGB/AADElgAAxJYAAMSWAADElgAAtHwAALh8AADElgAAxJYAAFx8AAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA/////wAAAAD//////////wEAAACoDQAA
+4QMOHuEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQCwAAAP8DADAM
+AAAA/wUA1AsAAAD/LQCwCwAAAP89AEwLAAAA/wQAdAsAAAD/JQDcDAAAAP/dAPgLAAAQEEwAAAAA
+AAABAQA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PBUVFRU8PDw8FRUVFTw8PDwAAAAA
+AAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwVFRUVPDw8PBUVFRU8
+PDw8AAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8FRUVFTw8
+PDwVFRUVPDw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPQOAAAsFgAAbBIAANgPAAD0FwAAfBMAACAVAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD0
+BoAAQKaAABgAAAAApoAAAAAAAAAAAAAAAAAAAAAAAEwRAQA4sQAAECQAADixAAA4sQAAOLEAAKAG
+AABo+gEAGN8AADixAAA4sQAAFCwAABQsAAAULAAAFCwAABQsAAAULAAAFCwAADixAAA4sQAAOLEA
+ADixAAA4KQAAOLEAADixAAA4sQAAOLEAADixAAD83gAAOLEAADixAADc0QAAAAAAAOD3AADk9wAA
+FAIAAHA9AQBwPQEAcD0BAHg9AQDkAQAAdD0BAAAAAABUwQAAlMcBAHzBAADExwEAoMEAAPTHAQA0
+m4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAC
+AAIAAwAEAAQABQAGAAYABwAIAAgACQAKAAoACwAMAAwADQAOAA4ADwAmACcAKAApACoARgBGAEcA
+SABIAEkASgBKAEsATABoAGkAagBqAGsAbABsAG0AbgBuAG8AcABwAHEAcgByAHMAcwB0AHQAdAB0
+AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AAoAPwAAAAAAAAAAAAAAAAAAAAAAAQACAAIA
+AwAEAAQABQAGAAYABwAIAAgACQAKAAoACwAMAAwADQAOAA4ADwAmACcAKAApACoARgBGAEcASABI
+AEkASgBKAEsATABoAGkAagBqAGsAbABsAG0AbgBuAG8AcABwAHEAcgByAHMAcwB0AHQAdAB0AHQA
+dAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AAoAPwAAAAAA8CEAALghAABEp4AAAAIAAAAAAAAo
+CgEAJAoBAESpgABABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAoBACQ6AQDUr4AAVAAAAAAA
+AAAoCgEA+DgBAISugABQAQAAAAAAACgKAQAENwEAWAeAAAgAAAABAAAAKAoBABQIAQAAAAAAUAEA
+AAAAAAAoCgEAoDcBANwygAACAAAAAAAAACgKAQCMNgEAVAeAAAQAAAAAAAAAMAoBACQKAQAosIAA
+KgAAAAAAAAAoCgEAJAoBAHg9gAAEAAAAAAAAACgKAQDEygEAAAAAAAAAAAAAAAAAKAoBAITKAQBg
+B4AABAAAAAAAAABuAG4AaQDAAKAAUACAAL4AUAF9AD4AAAAAAAAAnAIEAOYBJQBVAwQA3AFjAAAA
+bgBuAGkAwACgAFAAgAC+AFABfQA+AAAAAAAAAJwCBADmASUAVQMEANwBYwAAAAAAAAABAQAAoA8B
+ABXSAAAAAAAA/wMAAKAPAQAM0gAAAAAAAP8BAACgDwEAFdIAAAoAAAAA/A8AoA8BAAzSAAAJAAAA
+AP4DAKAPAQAV0gAAFAAAAAAA8D+gDwEADNIAABIAAAAAAPwHoA8BAAbSAAAAAAAA/wEAAKAPAQAH
+0gAAAAAAAP8DAACgDwEABtIAAAkAAAAA/gMAoA8BAAfSAAAKAAAAAPwPAKAPAQAG0gAAEgAAAAAA
+/AegDwEAB9IAABQAAAAAAPA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAQAA
+XgEAAAEAAAABAAAAAQAAAAEAAAADAAAAAAAAAAAAAAAsHwEAxCEBAKwgAQDQJAEAeCMBAMAiAQB8
+IgEATCQBAJQeAQAAAAAAEAAAAACAAAAAAKAAECcAAOgDAADoAwAAAAAAAAMAAAACAAAAAwAAAAMA
+AAADAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAIAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAQIBAQACAQABAgICAAEBAAIBAgECAAIAAQIDgICAgICAgIABgAKAgICA
+gMAAkADQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAA4sQAAOLEAADixAAA4sQAAOLEAADixAAA4sQAAOLEAADixAAA4sQAAOLEAADixAAA4sQAAOLEA
+ADixAAA4sQAAOLEAADixAAA4sQAAOLEAADixAAA4sQAAOLEAADixAAA4sQAAOLEAADixAAA4sQAA
+OLEAADixAAA4sQAAsPMAAAAAAAD///9/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAAAAAACMCgAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHO4BABUAAADMWoAA
+AAAAAAAAAAAAAAAAoOcBAAYAAADsWoAAAAAAAAAAAAAAAAAAxO0BAAUAAADMWoAAAAAAAAAAAAAA
+AAAAuO0BAAoAAADMWoAAAAAAAAAAAAAAAAAAOOoBAAQAAADsWoAAAAAAAAAAAAAAAAAAOOoBAAQA
+AADsWoAAAAAAAAAAAAAAAAAAOOoBAAQAAADsWoAAAAAAAAAAAAAAAAAAOOoBAAQAAADsWoAAAAAA
+AAAAAAAAAAAAOOoBAAQAAADsWoAAAAAAAAAAAAAAAAAAROsBAAYAAADsWoAAAAAAAAAAAAAAAAAA
+fOsBAAQAAADsWoAAAAAAAAAAAAAAAAAAfOsBAAQAAADsWoAAAAAAAAAAAAAAAAAAfOsBAAQAAADs
+WoAAAAAAAAAAAAAAAAAAfOsBAAQAAADsWoAAAAAAAAAAAAAAAAAAROsBAAYAAADsWoAAAAAAAAAA
+AAAAAAAAROsBAAYAAADsWoAAAAAAAAAAAAAAAAAAROsBAAYAAADsWoAAAAAAAAAAAAAAAAAAfOsB
+AAQAAADsWoAAAAAAAAAAAAAAAAAAfOsBAAQAAADsWoAAAAAAAAAAAAAAAAAAtOgBAAoAAADsWoAA
+AAAAAAAAAAAAAAAANOoBAAoAAADsWoAAAAAAAAAAAAAAAAAANOoBAAoAAADsWoAAAAAAAAAAAAAA
+AAAANOoBAAoAAADsWoAAAAAAAAAAAAAAAAAANOoBAAoAAADsWoAAAAAAAAAAAAAAAAAANOoBAAoA
+AADsWoAAAAAAAAAAAAAAAAAANOoBAAoAAADsWoAAAAAAAAAAAAAAAAAANOoBAAoAAADsWoAAAAAA
+AAAAAAAAAAAANOoBAAoAAADsWoAAAAAAAAAAAAAAAAAANOoBAAoAAADsWoAAAAAAAAAAAAAAAAAA
+NOoBAAoAAADsWoAAAAAAAAAAAAAAAAAANOoBAAoAAADsWoAAAAAAAAAAAAAAAAAANOoBAAoAAADs
+WoAAAAAAAAAAAAAAAAAAFO8BAAYAAADsWoAAAAAAAAAAAAAAAAAAZO4BAAUAAADMWoAAAAAAAAAA
+AAAAAAAAxOcBAAoAAADsWoAAAAAAAAAAAAAAAAAAfOgBAAoAAADsWoAAAAAAAAAAAAAAAAAA/OgB
+AAoAAADsWoAAAAAAAAAAAAAAAAAA2OkBAAoAAADsWoAAAAAAAAAAAAAAAAAASOwBAAoAAADsWoAA
+AAAAAAAAAAAAAAAACO0BAAoAAADsWoAAAAAAAAAAAAAAAAAAGAYCAAYAAADsWoAAAAAAAAAAAAAA
+AAAAIO4BAAYAAADsWoAAAAAAAAAAAAAAAAAAMO4BAAYAAADsWoAAAAAAAAAAAAAAAAAAXO4BAAEA
+AADsWoAAAAAAAAAAAAAAAAAAVPABAAoAAAAMW4AAAAAAAAAAAAAAAAAAzO8BAAUAAAAMW4AAAAAA
+AAAAAAAAAAAA5PIBAAYAAAAMW4AAAAAAAAAAAAAAAAAATPMBAAYAAAAMW4AAAAAAAAAAAAAAAAAA
+ZPYBAAoAAAAMW4AAAAAAAAAAAAAAAAAAAAAAAMxagADMWoAArCCgAGwgoAAwAAAAz////wAAAAAA
+AAAA7FqAAOxagACkIKAAOCCgAAEAAAD8////AAAAAAAAAAAMW4AADFuAAKggoAA8IKAACAAAAPP/
+//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD06AEAFQAAAMxagAAAAAAAUAAAAAAAAAD0BoAAQKaA
+ABgAAAAApoAAAAAAAAAAAAD0BoAAQKaAABgAAAAApoAAAAAAAAAAAAAAAAAA9AaAAECmgAAYAAAA
+AKaAAAAAAAAAAAAAAAAAAH8AAAAAAAAAAH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAD/
+/wAAAQAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAECAwQEBAQEBQYHCAgICAgJCgsMDQAAbjtoO2I7
+XDtuOmg6YjpcOm45aDliOVw5bjhoOGI4XDhuN2g3YjdcN24paCliKVwpbihoKGIoXChuJ2gnYidc
+J24ZaBliGVwZbhhoGGIYXBhuF2gXYhdcF24WaBZiFlwWbhVoFWIVXBVuFGgUYhRcFG4TaBNiE1wT
+bhJoEmISXBJuEWgRYhFcEW4QaBBiEFwQbgJoAmICXAJuAWgBYgFcAW4AaABiAFwAVAAAAG47aDti
+O1w7bjpoOmI6XDpuOWg5YjlcOW4raCtiK1wrbipoKmIqXCpuKWgpYilcKW4oaChiKFwobidoJ2In
+XCduJmgmYiZcJm4laCViJVwlbiRoJGIkXCRuI2gjYiNcI24iaCJiIlwibiFoIWIhXCFuIGggYiBc
+IG4SaBJiElwSbhFoEWIRXBFuEGgQYhBcEFcQUhBNEEkQbgFoAWIBXAFuAGgAYgBcAFQAAAAAAAAA
+AAAAAB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfFwBAAgAAADM
+WoAARAiAAMQIgABECYAAxAmAAAoNERQKDREUGRkZGQoKAAAABQYHCA0ODxAVFhcYGQAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAChKcnBwk
+nJycnJyVnHCDQTUZjSsAAAAABgYMAgAXAAAFEAogMEAAAAcOFQBch56ePQAAABQPFBIAAAAMEBQY
+IAgEAAA8ODQwLCgkIBwYFBAMCAQACwcDADs3My8rJyMfGxcTDwsHAzE3OjM1OjU3AAAAAAEBAQEB
+AQEBAgICAgICAgIDAwMDAwMDAwECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAV9mP2sPb89kb3kPfY9x/4Zfip+O34L/lw+bD57vkr+mf6ovrc+hT7
+S/uB+7b76vsc/E38ffyr/Nn8Bf0w/Vn9gv2p/c/99P0X/jn+Wv56/pj+tv7S/u3+Bv8e/zX/S/9g
+/3P/hf+W/6b/tP/B/83/2P/h/+n/8P/2//r//f/////////9//r/9v/w/+n/4f/Y/83/wf+0/6b/
+lv+F/3P/YP9L/zX/Hv8G/+3+0v62/pj+ev5a/jn+F/70/c/9qf2C/Vn9MP0F/dn8q/x9/E38HPzq
++7b7gftL+xT73Pqi+mf6K/ru+bD5cPkv+e34qfhl+B/42PeQ90b3/Paw9mP2cLmDupa7qry+vdK+
+57/8wBHCJ8M9xFPFasaAx5fIr8nGyt7L9swPzifPQNBZ0XLSjNOm1L/V2tb01w7ZKdpE21/cet2W
+3rHfzeDp4QXjIeQ+5Vrmd+eT6LDpzerq6wftJO5C71/wffGa8rjz1fTz9RH3L/hM+Wr6iPum/MT9
+4v4AAB4BPAJaA3gElgW0BtEH7wgNCisLSAxmDYMOoQ++ENwR+RIWFDMVUBZtF4kYphnCGt8b+xwX
+HjMfTyBqIYYioSO8JNcl8iYMKCYpQSpaK3Qsji2nLsAv2TDxMQozIjQ6NVE2aTeAOJY5rTrDO9k8
+7z0EPxlALkFCQlZDakR9RQQEAAQEAQIDAAEBAgECAgMBAQEBAQEBAQICAgICAgICAwMDAwMDAwME
+BAQEBAQEBAECAgICAgIDAwMDAwMDAwMDAwMDAwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAMQ1
+AAAUNgAA1DcAAIA4AADwNQAAZDIAAIwxAAD4MQAArDYAAFQxAADQNgAAPDcAADoBAgHVAN8A2gCi
+AHUAfwCKBSoDOQGoAYoFygLZAEgBAQMPBwoUN25qARoB2QDoAAoBugB5AIgAygFKAeIA+QDKAeoA
+ggCZAHTRRRfooosuAAUHAQMEAAUBBQAAAAUGAAIEAAUABQAAAQIBAgMEAAAFBgcICQoAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiM0AALjQ
+AAAoywAAAAAAAAAAAAABAAAAAgAAAAMAAAAAAAAABAAAAAIAAAAFAAAABwcHBwcHBwcHBwcHBwcH
+BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBgYGBgYFBQUFBQQEBAQE
+AwMDAwMCAgICAgEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAACgAKAAwACwALAAoADwANABAADwAjABsAFgASAD0ALAAf/8HDx8/AQMwAAAA
+NgAAAAwAAAASAAAAGAAAACQAAAAGAAAACQAAAAUABwIDBAYGQAOABsAJAA2AEwAaQB2AIIAGAA2A
+EwAaACcANIA6AEHACYATQB0AJ4A6AE7AV4BhmQMzB9kKcw6mFeYcgCAZJDMHcw6mFeYcWSvMOQBB
+M0jZCqYVgCBZKwBBplaAYVlsndiJnU7sxE40SIM0J3ZiJxqkQRoTO7ETERiBEQ/8wA9O7MROJ3Zi
+JxqkQRoTO7ETDdIgDYmd2AkIjMAIB37gBzRIgzQapEEaERiBEQ3SIA0IjMAIBmmQBrCy1QUFVEAF
+J3ZiJxM7sRMN0iANiZ3YCQZpkAbETuwEBEZgBAM/8AOqqqqqGqRBGhM7sRMP/MAPERiBEQ3SIA0K
+qIAKEzuxEw/8wA8P/MAPDdIgDQu0QAsLtEALiZ3YCQ3SIA0KqIAKCqiACgiMwAgHeIAHB3iABwZp
+kAYP/MAPDdIgDQu0QAsN0iANC7RAC4md2AkIjMAIiZ3YCQiMwAgHfuAHB37gB8EsKQcKqIAKCIzA
+CAd4gAcIjMAIB3iABwZpkAawstUFBmmQBrCy1QUFVEAFBVRABdYdxgQBBw8fP3///2bmAAAFBgEC
+AwQAAFQAVABsAGAAXABUAIwAeAANDwUHCQsBAygAKAA0ADAALAAsAEQAPAAsACwAPAA0ADAALABU
+AEQAVVVVAUtoLwFVVVUF4ziOA6qqqgJxHMcBqqqqCsdxHAcABAAAZAAAAAAAAAAPAD8AAQAAAA8A
+PwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8AAgAAAA8APwABAAAAARAA
+AQAAAAKAAAFCBgIQAAIgAAADwAABQwYDEAACwAAAA8AAAUMGBBAAAkAAAAKAAAFEBgURAABAAAAD
+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
+AAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAQAAABAA
+AAAAAAAAAQAAAAEAAAAAAAAA/wAAAP8AAAAAAAAAAAAAADCnAAAAAAAAKgAAAA4AAAAAAAEBAAAA
+AAAAAAAAAQEAAAAAAgABAAICAwMD4O0BAOztAQD47QEABO4BAAzuAQAU7gEAAQEAAQIBAQEAAAAA
+AAAAAAEAAAABAAAAAQAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAP////8A
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEA
+AAABAAAAAAAAAAAAAAAAAAAAgA0AAAAgAACADQAAgA0AAAAgAACADQAAAAYAAAAEAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAPj9
+AQAgIIAPAABAAGkgAABpIEAAaSAAAGkgQAAgIIAPAADoAGkgAABpIEAAaSAAAGkgQAAgIIAPAACU
+4mkgAABpIEAAaSAAAEogAABKIQAASiIAAEojAABKJAAASiUAAEomAABKJwAASiAAEEohABBKIgAQ
+SiMAEEokABBKJQAQSiYAEEonABBKIAAgSiEAIEoiACBKIwAgSiQAIEolACBKJgAgSicAIEogADBK
+IQAwCiSAP4EAAEBBLJwwQCycMEIkHDQKIoA/gAAobwojADfqDoAGSiYAcGkgQABKJgBwSiYAcEom
+AHBKJgBwABYAcIAArB9AeCAgQIcAAAAAAAAAAAAA/ByItvwcSLb8HAi2/BzItfwciLX8HEi1/BwI
+tfwcyLT8HIi0/BxItPwcCLT8HMiz/ByIs/wcSLPgfuB4BNw43TXw4HgE3DTdM/DgeATcMN0x8OB4
+BNws3S/w4HgE3CjdLfDgeATcJN0r8OB4BNwg3Snw4HgE3BzdJ/DgeATcGN0l8OB4BNwU3SPw4HgE
+3BDdIfDgeATcDN0f8OB4BNwI3Rzw4HgE3ATdGfA0FBowMBQZMCwUGDAoFBcwJBQWMCAUFTAcFBQw
+GBQTMBQUEjAQFBEwDBQQMALHAcawJE0zsCQfM+B+8cBOD8//z3GgAKwvGIHPdaAAyB8g3pq4GKEF
+2NClQx0YEADYfgigD4240aWNB8//8cAeD8//z3GgAKwvGIHPdaAAyB8g3rO4urgYoWTY0KVDHRgQ
+ANhOCKAPjbjRpV0Hz//geOB+4HjgfuB44H7geOB+4HgKIkCAANnuAAEALyYA8EomQABOAAYATwAg
+AIol/w/geAoiQIAA2c4AAQBsACQALyYA8FwABQArCDUISiZAAAhxANgCIb6A4CDFB0J5AeACIb6A
+4CDFB0J56wfv/wHgLy0BAEAlRQACJnzxAAAgAAAoQAHoIGIDLyAAgC8hSwACIb6AwCCGAcIhhgDg
+fhEAIABKIAAQSiBAEA4iQgAvIAsSziBFgIol/w8IAAUALy0BAEAlRQACJnzxAAAgAAAoQAFKJkAA
+6CAiAy8gAIAvIUsAAiG+gMAghgHCIYYASiYAAEIg/pDOIIIBRCB+kM4hggHgfrkAAADgeAokgPAF
+IEQA4CDBB0Qk/oBBKsQAhAACAC8kAvFCIQEBQiADAeggogQEEQQCBBEFAgQRBgIEEQcCBBsIAQQb
+SAEEG4gBBBvIASwAJQBEIj6BPAAiAEQi/IBAIcEA4CDBB0AjwwCoIIABARGEAgEbCgEgIMAHBBEE
+AgQRBQIEGwgB1Afh/wQbSAFEIvyABBEEAskH7/8EGwgBQiFBAEIgQwCoIIABARGEAgEbCgEgIMAH
+CiYA8Iogvw/KIGQA4H8vIAMA4H+KIP8P/ByIsfwcSLH8HAix4cPhwuHB4cAHwBwcwDHhwOB/AcBT
+IkKB4HxOIgOIFgAMAAEozAAAKYEAACiAAOB/hXlOIwMAACjBAOB/AnjgeFMiQoHgfE4iA4gWAAwA
+ACnMAAEpgQABKIAA4H+FeE4jAwABKcAA4H8ieeB4CHQA2AUqfgAvcQUqPgMAIECOASHBDgUrPgPg
+fydx4HgzACAASiQAAAchxAAvJkDwSiUAABAAJgAvJAQBDiBAgQMlQQCA4w4AAwAOIkKBAyXDAAUj
+hYAwAQEAeXNIdAhyKHMKJcCCSiIAEBoABADAIiEYyiUBgy8vQQHAImMQwCLDEUonAAAKJcCAwCch
+CBYABADKJYGALyhBAcAnYwDAJwMADieHgsonJABAJ0cACiXAAUwnAIgA2RAAJAAA2EhxaHIA20In
+B4gKJEBxKAABAE4nCoh+AAEAACmAAgEpwQEAKoUCoHEBKsIBACuFAgErwwGgckwiAJhqAAkAqCCA
+BQAgAIABIUGAASKCgAEjwwACIgKDAyPDggwABgAAIgKDASPDgsAgZgBCJD6ASiUAACAAAQAMAAoA
+DiJCgQMlwwAvJACBDAADAA4gQIEDJUEA4H4ocEhxaHIA2yAggA8AAIQFqCCAAwAgAIABIUGAASKC
+gJFywiIGA8UgZgAgIIAPAAC4BQDaCWoA2y8hAgAgIIAPAADgBeB4UyJCgeB8TiIDiBYADAAAKcwA
+AimBAAEogADgf4V4TiMDAAIpwADgf0IpwQfxwOHFz3CAANwgTYDPdYAAmKEghbe6uLoEIYEPAwAA
+AAe5RXktoKYJYA8A2ACFz3GAAEzLUSCAgs9wgACMvEyIFWrHcIAATMhggFZ5QYEG8pW7YKCrugXw
+tbtgoIu6C41BoaO47QLv/wut4HjhxeHGwIBhgKCBAYEAJY2TASDAAKCiAaLBxuB/wcXgeKLB8cBK
+Cs//RcHPdYAA3CAnhRUIQQAwlRQUDjEJDkEQWR2CEM9xgAAwJjGBHQhBAM9xgABAJjyRFBQNMQ0N
+QRDPcYAAqCZJqYvqz3WAAEwHwY2A5gDZyiBBACTyIa0LCpEDAdge8EEoDQIHfUEoAQSnec93gABM
+B6CPUyVFER8NMgTGuQohwA/rcs9wAADNG5/bZQEgAYokgw8PDZ4RANgM3BcCz//PdoAAzMoWJk0R
+p42gr8l1FiVNEQClFBQAMUatx3GAAMzHArUAiQetABlCAQAbQgHH8QjIz3KgAMgfDhoYgAnIDxoY
+gArIEBoYgAsSATYCyCR4ERoYgAzILRoYgOB+n+HMIO6HzCBOgAb3AnlBaQsKEQiKIf8PBvAA2Q8h
+gQBhuRh54H8ocPHADgnv/4ogDwqCJAI6mnF6clpziHWodwohgCEKIMAh1ghgAJ7BinDOCGAAi3GC
+xmpwxghgAMlxSnC+CGAAhMGpcLYIYACGwYjF6XCqCGAAqXEqcKIIYACKwQpwmghgAIzBqXCKwUoI
+IAGQwotwyXE+CCABksLJcITBNgggAZTChsCpcSoIIAGWwpjGkMCSwY4NoADJcprHlMCWwYINoADp
+cslw6XEKCCABnMKcwJ7BPgsgAI7Cn8UuDaAPBG2OwDIJIAAkbbcIEACGwIrB6g3v/0AlAhOLcITB
+3g3v/0AlAhWUwEAlARM2DaAAyXKQwEAlARUqDaAA6XLJcOlxsg/gAJzCjMCcwRYNoADJcjINoADJ
+cMlwjsHWCiAAQCUCF5LAQCUBE/oMoADJcpbAQCUBFe4MoADpcslw6XFyD+AAnMKMwJzB2gygAMly
+yXCOwZ4KIABAJQIZqg8gAEAlABfPcYAA9AcQoZoPIABAJQAZz3GAAPQHEaEH8ADZz3CAAPQHMKAx
+oN0Hr/+AJAI64HjPcYAA7G7gfwhh4HjxwIYPr//YcCh2SHGIdTIO7//JcAh3qXAmDu//qHEIcQAu
+gAMEfyZ/ACtAAyR4wQev/+V48cCCDUAFz3GAAHAb8CEAAEB4gNnPcKAA0BswoNHA4H5ggECBAYAh
+gVBzzCBBgOEgwQfKICEAMHCG9gT2CQrFAOB/AdiKIP8P4H7geIDhyiRNcOggbQLPcaAAUAwlgQEY
+UgDgfvHA7g6P/89wgADcIAOAGBCFABsNEQEKIcAP63KKIE0DXNt1BuAASiQAAIogBw4GCmAGANnP
+doAARK0tjgTpDI4ZCEIA7glgBooghw2KIIcN4glgBiyOYPDPcKAAsB8bgM93gADongKniiBJBsYJ
+YAZu2YogCQa+CWAGIodMjg2Oz3GAAEzQaJFAp891gAAEuhsI4gABpwixANlNHUIQAdkspTWFBwkF
+ABWlEI4EpRGOAugE6gDYCvDPcIAA3CADgAmA9QiegAHYAqWKIEkGZglgBo7ZiiAJBloJYAYihwKF
+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
+L3nKDuAAD9gA2K0Db/2twPHA4cWhwYtxRghgCgHaz3WAAGSWABQEMM9wgAAUDqlxEtp6DeAAANsA
+FAQwz3CAABIOViVBEgHaYg3gAALbz3CAADgOVSXBFBzaZg3gAADDANhVA2/9ocDxwL4Kb/0D2qPB
+unDqDyAKi3EBwc9wgAAIDwDf9CBNAALBz3CAACAPgOX0IFQAz3CAAJgI4KDhoMwlopDKJsITAvQA
+3oHlzCXikMomYRAODs//qnDPcq3e774qCWACqXHmDu//qnDrCNAAAMCA4MwgooFP9IDlzCVikEv0
+AsCTCBEAz3CAACwT1XhacOCgz3CAADgT1Xh6cOCgz3CAAFwT1XgacOCgz3CAAGgT1Xg6cOCgz3CA
+AEQT1XjgoM9wgABQE9V44KCqcKlxz3Ot3u++sghgAslyGgvv/6pwcwjQAADBABIAIIbhAdnAeQO5
+1XnHcYAA2LAAoQATACAEoQAQACAbeAihABEAIBt4DKGqcMlxqXIKJIAPrd7vvmYIYAKKc/oPr/+q
+cCcI0AAAwM9xgACYCECBBL0GuLhgFSAABcdwgAAUsSGBQrAjsADYwQFv/aPA8cCGCW/9BNqkwZoO
+IAqLcQDAAcEEuDV4z3aAAHwOEGbuDOAAAsEAwAHBBLjPdYAAvA41eBBl2gzgAAPBAMABwQS4NXgA
+ZgbgEHjGDOAAANkAwAHBBLg1eABlBuAQeLIM4AAA2QDYjQFv/aTA8cChwfYLYAKLcgDAocDRwOB+
+4HjxwOoIT/2uwbpwmnF6clpzCiEAIQogQCGCxa4NIA2pcITGpg0gDclwng0gDYbAmg0gDYjAkg0g
+DYrAjMeKDSAN6XCqcBfZOgggCotyinAX2S4IIAqBwgDAfgjv/alxAcB2CO/9yXGpcKlxlg0v/qly
+yXDJcYoNL/7JcqlwyXEaDm/9hsJqcBfZ9g/gCYtySnAX2e4P4AmBwgDAPgjv/alxAcA2CO/9yXGp
+cKlxUg0v/qlyyXDJcUoNL/7JcqlwyXHWDW/9iMIqcA4I7/2KwYjAisEuDS/+6XLpcAvZXg9v/uly
+hsDuCK/96XGA4AHYGPYKcOYPr/2KwYjAisECDS/+6XLpcAvZNg9v/ulyhsDGCK/96XGA4ALYyiAq
+AB0Ab/2uwOB48cDiDy/9AtqiwQh28gwgCotxAMAA3alxBNpIc0okQAE6CK/9SiXAAQhxQgvgAEvY
+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
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQKiAAAh5AAAgrYAA
+AAAAACCtgAAAAAAA3wAAABkBAABiAQAAvgEAADICAADDAgAAewMAAGIEAACEBQAA8gYAAL4IAAAC
+CwAAAQAAAAAAAAAwgAAAAAAAADGAAACIiDMzMoAAAACqqoozgAAAAAAAADSAAAAAAAAANYAAAAAA
+AAA2gAAAAAAAADeAAAAAAAAAOIAAAAAAAAA5gAAAAAAAADqAAAAAAAAAO4AAAAAAAAA8gAAAAAAA
+AD2AAACqqgoAPoAAAFOFiIg/gAAAAAAAMDCAAAAAAAAAMYAAAJqZWFUygAAAAKqqqjOAAAAAAAAA
+NIAAAAAAAAA1gAAAAAAAADaAAAAAAAAAN4AAAAAAAAA4gAAAAAAAADmAAAAAAAAAOoAAAAAAAAA7
+gAAAAAAAADyAAAAAAAAAPYAAAKqqCgA+gAAAVZiZqj+AAAAAAABQMIAAAAAAAAAxgAAAAAAAADKA
+AAAAAAAAM4AAAAAAAAA0gAAAAAAAADWAAAAAAAAANoAAAAAAAAA3gAAAAAAAADiAAAAAAAAAOYAA
+AAAAAAA6gAAAAAAAADuAAAAAAAAAPIAAAAAAAAA9gAAAAAAAAD6AAAAAAAAAP4AAAAAAAAAwgAAA
+AAAAADGAAAAAAAAAMoAAAAAAAAAzgAAAAAAAADSAAACaeQAANYAAAKqqqqo2gAAAAAAAADeAAAAA
+AAAAOIAAAAAAAAA5gAAAAAAAADqAAACqqqoKO4AAAABwmao8gAAAAAAAAD2AAAAAAAAAPoAAAAAA
+AAA/gAAAAAAAAP//AAClAQEAuQHfALEAGwAWARsArwAbABQBGwBsAKAA0QCgAG8AgwBxAIMAdgCD
+AHMAMwBuADMAcAAzAHIAMwDXADMA1AEGANABAAB+ADwA4wA8AHgASQDdAEkAfwBaAOQAWgCqAD8A
+qwABAA8BPwAQAQEAeQBqAN4AagCoAAAADQEAAKYANwCnAAEACwE3AAwBAQAEAAgAnAHMAJ0BzADV
+AcwA1gHMALQAIAAZASAAMQIMADICDAAzAr0ANgIMADcCDAA4Ar0AoACIAAUBiAChANUABgHVAKIA
+BAAHAQQAjwCIAPQAiACQACIA9QAiAJEABAD2AAQAnwAMAPsADACUAAAAlQAAAJwAlQCdANAAmgCK
+AJgAEQCWADMAlwB3AJQAAQCVAAEAnACVAJ0A0ACaAIoAmAARAJYAMwCXAHcAlAACAJUAAwCcAJUA
+nQDQAJoAigCYABEAlgAzAJcAdwCUAAMAlQAHAJwAlQCdANAAmgCKAJgAEQCWADMAlwB3APoAAAD5
+AAAAAgGVAAMB0AAAAYoA/gARAPwAMwD9AHcA+gABAPkAAQACAZUAAwHQAAABigD+ABEA/AAzAP0A
+dwD6AAIA+QADAAIBlQADAdAAAAGKAP4AEQD8ADMA/QB3APoAAwD5AAcAAgGVAAMB0AAAAYoA/gAR
+APwAMwD9AHcAhQAAAIYAAACHAFUAiAAAAIkAqgCKAAAAiwDdAIwAAACFAAEAhgABAIcAVQCIAAAA
+iQCqAIoAAACLAN0AjAAAAIUAAgCGAAMAhwBVAIgAAACJAKoAigAAAIsA3QCMAAAAhQADAIYABwCH
+AFUAiAAAAIkAqgCKAAAAiwDdAIwAAADrAAAA6gAAAOwAVQDtAAAA7gCqAO8AAADwAN0A8QAAAOsA
+AQDqAAEA7ABVAO0AAADuAKoA7wAAAPAA3QDxAAAA6wACAOoAAwDsAFUA7QAAAO4AqgDvAAAA8ADd
+APEAAADrAAMA6gAHAOwAVQDtAAAA7gCqAO8AAADwAN0A8QAAAPv/AAAAAAIADdIS0hPSFNIM0hXS
+C9IC0hHSBEMAEBQQCRAREAFAG9Ic0gDSCgALAAQADgC1ABoBDwBCALwAwwAhASgBtgC3ALgAuQC9
+AL4AvwDAABsBHAEdAR4BIgEjASQBJQEKAAAACwAAAAwAAAC2AAAAtwAAALgAAAC5AAAAGwEAABwB
+AAAdAQAAHgEAALYAAAC3AAAAuAAAALkAAAAbAQAAHAEAAB0BAAAeAQAAvQAAAL4AAAC/AAAAwAAA
+ACIBAAAjAQAAJAEAACUBAAC9AAAAvgAAAL8AAADAAAAAIgEAACMBAAAkAQAAJQEAABLSAAAT0gAA
+FNIAAAAAAQACAAMALABkAHQAgACMAKEABwAAAAAAAQACAAMAAAAAAAAAAAAAAAAAAAAAAAEAAAAB
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAcAAAAAAAAAAwAAAAQAAAADAAAAAAAAAP8D
+AAADAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAACwAAQAAAAEAAQABAAAAAAAAAAAAAQAB
+AAIAAgACAAMAAwAEAAQABQAFAAYABgAHAAcACAAIAAkACQAKAAoACwALAAwADAANAA0ADgAOAA8A
+AAABAAIAAAAL0g7SDdII0gnSCtIS0hPSFNIR0hDSAtIB0gPSAIAF0gRDG9Ic0gTSAEUw0jHSAAC1
+ABoBgQEFAAQADwAQAAoACwAMAE4AAAAAAAEAAgAAAA3SEdIQ0gLSAdID0hvSC9IAgAXSEtIT0hTS
+BEMI0gnSCtIc0gbSB9Jw0gAAtQAaAYEBBAAPAIMA6ABOAZIA9wBdAQYACAAJAAoACwAMAAUAAAAA
+AAAAAAAKAAAAAQAAAAAAAAAAAAAAAAAAAAMAAAAEAAAAAwAAAAAAAAADAAAAAAAAAAAAAAAAAAAA
+AAAAAP8DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAABAAAAAAAAAAAAAAAA
+AAAAAAAAAAEAAQABAAAABNIN0hHSENIC0gHSA9Ib0gCABdIL0hLSE9IU0gRDcNIAAAAAAQAAAAEA
+AAABAAAAAQAAAAMAAAACAAAAAwAAAAMAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAP8DAAAAAAAAtQAa
+AYEBBAAPAAYACAAJAAoACwAMAAAAAAAAAAAALAABABUAFQAVAAEAAQABAAAAAAABAAIAAAAc0g3S
+EdIQ0gLSAdID0hvSC9IAgAXSEtIT0hTSBEMG0gfSBNJw0gAAtQAaAYEBBQAEAAYACAAJAAoACwAM
+AIMAkgDoAPcATgFdAQ8AAAAAALcTIgC4FCMAuRUkALsWJQC8FyYAvRgnAMAZKADEGikABxsAAAgc
+AQALHQIADB4DABAfBAAiIQUAJCIGACYjBwAoJAgAKiUJACwmCgAuJwsAMCgMADQpDQA4Kg4APCsP
+AEAsEABkLhEAaC8SAGwwEwBwMRQAdDIVAHgzFgB8NBcAgDUYAIQ2GQCINxoAjDgbAJE6HACVOx0A
+mTweAJ09HwChPiAApT8hACRJBgIsSgoCNEsNATxMDwFkTREBbE4TAXRPFQF8UBcBhFEZAZVSHQGd
+Ux8BAQQAAAIFAQADBgIABAcDAAUIBAAGCQUABwoGAAgLBwAJDAgACg0JAAsOCgAMDwsADRAMAA4R
+DQABQAAEAkEBBANCAgQEQwMEBUQEBAZFBQQHRgYECEcHBAlICAQAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAHCAAAAAAACyDMgA/////////wAB//8CA////wT//////////////////////wX/Bv8H
+/wj/Cf8K/wv/DP///w3///8O////D////xD/////////////////////////////////////////
+/////xH///8S////E////xT///8V////Fv///xf///8Y////Gf///xr///8b/////xz///8d////
+Hv///x////8g////If//////////////////////IiMk/yUmJ///KP///yn/////////////////
+/////////////////////////////////////////////////////////////wABAQEAAAAAAAEA
+AAAAAAAAAAAAAAAAAAMAAAABAAAAAAAAAAMAAAD8pAEAAgAAAPi4AQAEAAAA+KQBAAUAAADIpAEA
+BgAAADyYAAASAAAAfCcAAAgAAABcwQAACQAAALgvAAANAAAAhCoAAA4AAAAM2gAADwAAAAibAQAY
+AAAAkPwAAAwAAADAvAAAFgAAAJyiAQAQAAAAyC0BABEAAAA8vAEAAQAAANhwAAATAAAA/JoBABQA
+AABEqgEABwAAAIRMAAAVAAAADEoBABcAAAD8cgEAGQAAALTfAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArJQAAKyUAACslAAA
+ZH8AAKyUAACslAAAyH8AAKyUAACslAAArJQAAKyUAACslAAArJQAAKyUAACslAAArJQAALiKAAAM
+igAA/IkAAJCJAAAoigAATIkAAKyUAACslAAAkIwAAECPAACMkAAArJQAAKyUAACslAAAFJQAANCL
+AAAIjAAAdIsAAKyUAACslAAArJQAANCTAACslAAAVIsAAKyUAACslAAArJQAAKyUAACslAAArJQA
+AKyUAACslAAA1H8AAKyUAACslAAArJQAAKyUAACslAAArJQAAKyUAACslAAArJQAAKyUAACslAAA
+rJQAAKyUAACslAAArJQAAKyUAACslAAArJQAAKyUAACslAAArJQAAKyUAACslAAAkIIAAKyUAACs
+lAAArJQAAKyUAACslAAASJEAAKyUAACslAAArJQAAKyUAACslAAArJQAAKyUAACslAAArJQAAKyU
+AACslAAAaH0AAKyUAAAkfQAArJQAAKyUAACslAAArJQAAKyUAACslAAArJQAAKyUAACsfAAArJQA
+AKyUAACslAAArJQAAKyUAACslAAArJQAAKyUAACslAAArJQAAKyUAAD0gwAAbIMAAKyUAAAQhAAA
+rJQAALCCAAAEiAAArJQAAKyUAADYigAArJQAAKyUAACslAAArJQAAKyUAAAkiwAACIsAAKyUAACs
+lAAArJQAAKyUAACslAAArJQAAKyUAACslAAArJQAAKyUAACslAAA3IUAAKyUAACslAAArJQAAESR
+AACslAAA6IEAAKyUAABokwAArJQAAMiTAAAEkQAArJQAAKyUAACUewAAxJAAAKyUAACslAAArJQA
+AJiJAACslAAArJQAAJiFAAC0fQAArJQAAKyUAACslAAAEIwAALCIAACslAAArJQAAKyUAACslAAA
+rJQAAKyUAABshwAArJQAANSUAADklAAA4JQAAOiUAADclAAA2JQAAOyUAADQlAAArJQAAKyUAACs
+lAAArJQAAKyUAACslAAArJQAAKyUAACghQAArJQAAKyUAACslAAArJQAAKyUAACslAAArJQAAHyV
+AACIlgAAxHsAACB8AACslAAArHsAAKyUAACslAAArJQAAKyUAACslAAArJQAAKyUAACslAAArJQA
+AKyUAACslAAArJQAAKyUAACslAAArJQAAKyUAACslAAArJQAAKyUAACslAAArJQAAKyUAACslAAA
+rJQAAKyUAACslAAArJQAAKyUAACslAAArJQAAKyUAACslAAA5H0AALR+AABUfgAA8JQAADh8AAA8
+fwAA7IEAAKyUAACslAAArJQAAKyUAADAfwAAxH8AAKyUAACslAAAaH8AAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAD/////AAAAAP//////////AQAAADAQAADhAw4e4QAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgDgAAAP8DAMAOAAAA/wUAZA4AAAD/LQBADgAA
+AP89ANwNAAAA/wQABA4AAAD/JQBoDwAAAP/dAIgOAAAQEEwAAAAAAAABAQA8PDw8PDw8PDw8PDw8
+PDw8PDw8PDw8PDw8PDw8PDw8PBUVFRU8PDw8FRUVFTw8PDwAAAAAAAAAAAAAAAAAAAAAPDw8PDw8
+PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwVFRUVPDw8PBUVFRU8PDw8AAAAAAAAAAAAAAAAAAAA
+ADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8FRUVFTw8PDwVFRUVPDw8PAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAP8AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAIgRAACYGAAA7BQAAGgSAABYGgAA9BUAAJQXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4BoAAyK2AABgAAACIrYAAAAAA
+AAAAAAAAAAAAAAAAAJz5AAD8qgAA4CQAAPyqAAD8qgAA/KoAANwJAABktAEAZMsAAPyqAAD8qgAA
+dCsAAHQrAAB0KwAAdCsAAHQrAAB0KwAAdCsAAPyqAAD8qgAA/KoAAPyqAACAKAAA/KoAAPyqAAD8
+qgAA/KoAAPyqAABIywAA/KoAAPyqAABkwQAAAAAAAMTjAADI4wAAFAIAAAgjAQAIIwEACCMBABAj
+AQDkAQAADCMBAGi4AAAAlQEAkLgAADCVAQC0uAAAYJUBALyigAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQACAAIAAwAEAAQABQAGAAYABwAIAAgACQAKAAoACwAMAAwA
+DQAOAA4ADwAmACcAKAApACoARgBGAEcASABIAEkASgBKAEsATABoAGkAagBqAGsAbABsAG0AbgBu
+AG8AcABwAHEAcgByAHMAcwB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AAoA
+PwAAAAAAAAAAAAAAAAAAAAAAAQACAAIAAwAEAAQABQAGAAYABwAIAAgACQAKAAoACwAMAAwADQAO
+AA4ADwAmACcAKAApACoARgBGAEcASABIAEkASgBKAEsATABoAGkAagBqAGsAbABsAG0AbgBuAG8A
+cABwAHEAcgByAHMAcwB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AAoAPwAA
+AAAAzCIAAJQiAADYsIAAAAIAAAAAAACQ8gAAjPIAANiygABABQAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAlPIAAMwfAQBouYAAVAAAAAAAAACQ8gAAoB4BABi4gABQAQAAAAAAAJDyAACwHAEAWAeA
+AAgAAAABAAAAkPIAAIDwAAAAAAAAUAEAAAAAAACQ8gAATB0BAOAzgAACAAAAAAAAAJDyAAA4HAEA
+VAeAAAQAAAAAAAAAmPIAAIzyAAC8uYAAKgAAAAAAAACQ8gAAjPIAAGg9gAAEAAAAAAAAAJDyAAAs
+mAEAAAAAAAAAAAAAAAAAkPIAAOyXAQBgB4AABAAAAAAAAABuAG4AaQDAAKAAUACAAL4AUAF9AD4A
+AAAAAAAAnAIEAOYBJQBVAwQA3AFjAAAAbgBuAGkAwACgAFAAgAC+AFABfQA+AAAAAAAAAJwCBADm
+ASUAVQMEANwBYwAAAAAAAAABAQAA9PcAABXSAAAAAAAA/wMAAPT3AAAM0gAAAAAAAP8BAAD09wAA
+FdIAAAoAAAAA/A8A9PcAAAzSAAAJAAAAAP4DAPT3AAAV0gAAFAAAAAAA8D/09wAADNIAABIAAAAA
+APwH9PcAAAbSAAAAAAAA/wEAAPT3AAAH0gAAAAAAAP8DAAD09wAABtIAAAkAAAAA/gMA9PcAAAfS
+AAAKAAAAAPwPAPT3AAAG0gAAEgAAAAAA/Af09wAAB9IAABQAAAAAAPA/AAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAsAQAAXgEAAAEAAAABAAAAAQAAAAEAAAADAAAAAAAAAAAAAAAc
+BwEAqAkBAJQIAQCcDAEATAsBAJgKAQBYCgEAHAwBAIQGAQAAAAAAEAAAAACAAAAAAKAAECcAAOgD
+AADoAwAAAAAAAAMAAAACAAAAAwAAAAMAAAADAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAADAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIBAQACAQABAgICAAEBAAIB
+AgECAAIAAQIDgICAgICAgIABgAKAgICAgMAAkADQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPyqAAD8
+qgAA/KoAAPyqAAD8qgAA/KoAAPyqAAD8qgAA/KoAAPyqAAD8qgAA/KoAAPyqAAD8qgAA/KoAAPyq
+AAD8qgAA/KoAAPyqAAD8qgAA/KoAAPyqAAD8qgAA/KoAAPyqAAD8qgAA/KoAAPyqAAD8qgAA/KoA
+APyqAAC03wAAAAAAAP///38BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAA/wAAAAAAAACMCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAACAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAD4sAEAFQAAAHhYgAAAAAAAAAAAAAAAAACgsAEABQAAAHhYgAAAAAAA
+AAAAAAAAAACUsAEACgAAAHhYgAAAAAAAAAAAAAAAAACsrQEACgAAAJhYgAAAAAAAAAAAAAAAAAAk
+rwEACgAAAJhYgAAAAAAAAAAAAAAAAAAkrwEACgAAAJhYgAAAAAAAAAAAAAAAAAAkrwEACgAAAJhY
+gAAAAAAAAAAAAAAAAAAkrwEACgAAAJhYgAAAAAAAAAAAAAAAAAAkrwEACgAAAJhYgAAAAAAAAAAA
+AAAAAAAkrwEACgAAAJhYgAAAAAAAAAAAAAAAAAAkrwEACgAAAJhYgAAAAAAAAAAAAAAAAAAkrwEA
+CgAAAJhYgAAAAAAAAAAAAAAAAAAkrwEACgAAAJhYgAAAAAAAAAAAAAAAAAAkrwEACgAAAJhYgAAA
+AAAAAAAAAAAAAAAkrwEACgAAAJhYgAAAAAAAAAAAAAAAAAAkrwEACgAAAJhYgAAAAAAAAAAAAAAA
+AACosQEABgAAAJhYgAAAAAAAAAAAAAAAAAD8sAEABQAAAHhYgAAAAAAAAAAAAAAAAAC8rAEACgAA
+AJhYgAAAAAAAAAAAAAAAAAB0rQEACgAAAJhYgAAAAAAAAAAAAAAAAAD0rQEACgAAAJhYgAAAAAAA
+AAAAAAAAAADMrgEACgAAAJhYgAAAAAAAAAAAAAAAAAAorwEACgAAAJhYgAAAAAAAAAAAAAAAAADk
+rwEACgAAAJhYgAAAAAAAAAAAAAAAAADkvwEABgAAAJhYgAAAAAAAAAAAAAAAAAAAAAAAeFiAAHhY
+gACsIKAAbCCgADAAAADP////AAAAAAAAAACYWIAAmFiAAKQgoAA4IKAAAQAAAPz///8AAAAAAAAA
+ALhYgAC4WIAAqCCgADwgoAAIAAAA8////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOytAQAVAAAA
+eFiAAAAAAAAAAAAAAAAAAPgGgADIrYAAGAAAAIitgAAAAAAAAAAAAAAAAAB/AAAAAAAAAAB/AAAA
+AAAAAAAAAAAAAAAAAAAAAAAAADgAAABoAAAAdAAAAIAAAACMAAAAnQAAAAcAAAAAAAAA/////wAA
+AAAtAQAA3QEAAFoCAAC6AgAACgMAAE0DAACHAwAAugMAAOgDAAARBAAANwQAAFkEAAB6BAAAmAQA
+ALQEAADOBAAA5wQAAP4EAAAVBQAAKgUAAD4FAABRBQAAZAUAAHUFAACGBQAAlwUAAKcFAAC2BQAA
+xQUAANMFAADhBQAA7gUAAPsFAAAIBgAAFAYAACAGAAArBgAANwYAAEIGAABMBgAAVwYAAGEGAABr
+BgAAdQYAAH4GAACIBgAAkQYAAJoGAACiBgAAqwYAALQGAAC8BgAAxAYAAMwGAADUBgAA2wYAAOMG
+AADqBgAA8gYAAPkGAAAABwAABwcAAA4HAAAUBwAAGwcAACIHAAAoBwAALgcAADUHAAA7BwAAQQcA
+AEcHAABNBwAAUwcAAFgHAABeBwAAZAcAAGkHAABvBwAAdAcAAHkHAAB/BwAAhAcAAIkHAACOBwAA
+kwcAAJgHAACdBwAAogcAAKcHAACrBwAAsAcAALUHAAC5BwAAvgcAAMIHAADHBwAAywcAANAHAADU
+BwAA2AcAANwHAADhBwAA5QcAAOkHAADtBwAA8QcAAPUHAAD5BwAA/QcAAAEIAAAFCAAACAgAAAwI
+AAAQCAAAFAgAABcIAAAbCAAAHwgAACIIAAAmCAAAKQgAAC0IAAAwCAAANAgAADcIAAA7CAAAPggA
+AEEIAABFCAAASAgAAEsIAABPCAAAUggAAFUIAABYCAAAWwgAAF8IAABiCAAAZQgAAGgIAABrCAAA
+bggAAHEIAAB0CAAAdwgAAHoIAAB9CAAAgAgAAIIIAACFCAAAiAgAAIsIAACOCAAAkQgAAJMIAACW
+CAAAmQgAAAAAAAABAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAQIDBAQEBAQFBgcICAgICAkKCwwN
+AABuO2g7YjtcO246aDpiOlw6bjloOWI5XDluOGg4YjhcOG43aDdiN1w3biloKWIpXCluKGgoYihc
+KG4naCdiJ1wnbhloGWIZXBluGGgYYhhcGG4XaBdiF1wXbhZoFmIWXBZuFWgVYhVcFW4UaBRiFFwU
+bhNoE2ITXBNuEmgSYhJcEm4RaBFiEVwRbhBoEGIQXBBuAmgCYgJcAm4BaAFiAVwBbgBoAGIAXABU
+AAAAbjtoO2I7XDtuOmg6YjpcOm45aDliOVw5bitoK2IrXCtuKmgqYipcKm4paCliKVwpbihoKGIo
+XChuJ2gnYidcJ24maCZiJlwmbiVoJWIlXCVuJGgkYiRcJG4jaCNiI1wjbiJoImIiXCJuIWghYiFc
+IW4gaCBiIFwgbhJoEmISXBJuEWgRYhFcEW4QaBBiEFwQVxBSEE0QSRBuAWgBYgFcAW4AaABiAFwA
+VAAAAAAAAAAAAAAAHQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMAAACSAAAAgwAAAJIAAADo
+AAAA9wAAAOgAAAD3AAAAAAAAAAkAAAAAAAAACgAAADgAAABoAAAAdAAAAIAAAACMAAAAnQAAAAcA
+AAAAAAAABwAAAAcAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAMxBAQAIAAAAeFiAAAwJgACMCYAADAqA
+AIwKgAAKDREUCg0RFBkZGRkKCgAAAAUGBwgNDg8QFRYXGBkAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAChKcnBwknJycnJyVnHCD
+QTUZjSsAAAAABgYMAgAXAAAFEAogMEAAABMOExEAAAAMEBQYIAgEAAA8ODQwLCgkIBwYFBAMCAQA
+CwcDADs3My8rJyMfGxcTDwsHAzE3OjMzOjU0AAAAAAEBAQEBAQEBAgICAgICAgIDAwMDAwMDAwEC
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABQAA
+AAAAAAAKAAAAEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAV9mP2sPb8
+9kb3kPfY9x/4Zfip+O34L/lw+bD57vkr+mf6ovrc+hT7S/uB+7b76vsc/E38ffyr/Nn8Bf0w/Vn9
+gv2p/c/99P0X/jn+Wv56/pj+tv7S/u3+Bv8e/zX/S/9g/3P/hf+W/6b/tP/B/83/2P/h/+n/8P/2
+//r//f/////////9//r/9v/w/+n/4f/Y/83/wf+0/6b/lv+F/3P/YP9L/zX/Hv8G/+3+0v62/pj+
+ev5a/jn+F/70/c/9qf2C/Vn9MP0F/dn8q/x9/E38HPzq+7b7gftL+xT73Pqi+mf6K/ru+bD5cPkv
++e34qfhl+B/42PeQ90b3/Paw9mP2cLmDupa7qry+vdK+57/8wBHCJ8M9xFPFasaAx5fIr8nGyt7L
+9swPzifPQNBZ0XLSjNOm1L/V2tb01w7ZKdpE21/cet2W3rHfzeDp4QXjIeQ+5Vrmd+eT6LDpzerq
+6wftJO5C71/wffGa8rjz1fTz9RH3L/hM+Wr6iPum/MT94v4AAB4BPAJaA3gElgW0BtEH7wgNCisL
+SAxmDYMOoQ++ENwR+RIWFDMVUBZtF4kYphnCGt8b+xwXHjMfTyBqIYYioSO8JNcl8iYMKCYpQSpa
+K3Qsji2nLsAv2TDxMQozIjQ6NVE2aTeAOJY5rTrDO9k87z0EPxlALkFCQlZDakR9RQQEAAQEAQID
+AAEBAgECAgMBAQEBAQEBAQICAgICAgICAwMDAwMDAwMEBAQEBAQEBAECAgICAgIDAwMDAwMDAwMD
+AwMDAwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAADoBAgHVAN8A2gCiAHUAfwCKBSoDOQGoAYoF
+ygLZAEgBAQMPBwoUN25qARoB2QDoAAoBugB5AIgAygFKAeIA+QDKAeoAggCZAHTRRRfooosuAAUH
+AQMEAAUBBQAAAAUGAAIEAAUABQAAAQIBAgMEAAAFBgcICQoAAAkAAAAAAAAAAQAAAAIAAAADAAAA
+AAAAAAQAAAACAAAABQAAAAcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcH
+BwcHBwcHBwcHBwcHBwcHBwYGBgYGBQUFBQUEBAQEBAMDAwMDAgICAgIBAQEBAQAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoACgAMAAsACwAKAA8
+ADQAQAA8AIwAbABYAEgA9ACwAH//Bw8fPwEDMAAAADYAAAAMAAAAEgAAABgAAAAkAAAABgAAAAkA
+AAAFAAcCAwQGBkADgAbACQANgBMAGkAdgCCABgANgBMAGgAnADSAOgBBwAmAE0AdACeAOgBOwFeA
+YZkDMwfZCnMOphXmHIAgGSQzB3MOphXmHFkrzDkAQTNI2QqmFYAgWSsAQaZWgGFZbJ3YiZ1O7MRO
+NEiDNCd2YicapEEaEzuxExEYgREP/MAPTuzETid2YicapEEaEzuxEw3SIA2JndgJCIzACAd+4Ac0
+SIM0GqRBGhEYgREN0iANCIzACAZpkAawstUFBVRABSd2YicTO7ETDdIgDYmd2AkGaZAGxE7sBARG
+YAQDP/ADqqqqqhqkQRoTO7ETD/zADxEYgREN0iANCqiAChM7sRMP/MAPD/zADw3SIA0LtEALC7RA
+C4md2AkN0iANCqiACgqogAoIjMAIB3iABwd4gAcGaZAGD/zADw3SIA0LtEALDdIgDQu0QAuJndgJ
+CIzACImd2AkIjMAIB37gBwd+4AfBLCkHCqiACgiMwAgHeIAHCIzACAd4gAcGaZAGsLLVBQZpkAaw
+stUFBVRABQVUQAXWHcYEAQcPHz9///9m5gAABQYBAgMEAABUAFQAbABgAFwAVACMAHgADQ8FBwkL
+AQMoACgANAAwACwALABEADwALAAsADwANAAwACwAVABEAFVVVQFLaC8BVVVVBeM4jgOqqqoCcRzH
+AaqqqgrHcRwHAAQAAGQAAAAAAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8A
+AQAAAA8APwABAAAADwA/AAIAAAAPAD8AAQAAAAEQAAEAAAACgAABQgYCEAACIAAAA8AAAUMGAxAA
+AsAAAAPAAAFDBgQQAAJAAAACgAABRAYFEQAAQAAAA8AAAUUGBhEAAOAAAAPAAAFFBgcRAAEAAAAC
+gAABRgYIEQACIAAAA8AAAUcGCREAAsAAAAPAAAFHBgoRAAJAAAACgAABSAYLEgAAQAAAA8AAAUkG
+DBIAAOAAAAPAAAFJBg0SAAEAAAACgAABSgYOEgACAAAAAoAAAUwGAAAiFgAAgAAAAwAAAVkAJBYA
+AQAAAAMAAAFaACYWAAIAAAAEAAABWgAoFgACAAAAAwAAAVsAKhYAAoAAAAMAAAFcACwXAAAAAAAE
+AAABXAAuFwAAgAAAAwAAAV0AMBcAAQAAAAMAAAFeADQXAAIAAAADAAABXwA2FwACgAAAAwAAAWAA
+OBgAAAAAAAQAAAFgADwYAAEAAAADAAABYgA+GAACAAAABAAAAWIAQBgAAgAAAAMAAAFjAGQbAAIA
+AAADAAABbwFmGwACgAAAAwAAAXABaBwAAAAAAAQAAAFwAWwcAAEAAAADAAABcgFuHAACAAAABAAA
+AXIBcBwAAgAAAAMAAAFzAnQdAAAAAAAEAAABdAJ2HQAAgAAAAwAAAXUCeB0AAQAAAAMAAAF2Anwd
+AAIAAAADAAABdwN+HQACgAAAAwAAAXgDgB4AAAAAAAQAAAF4A4QeAAEAAAADAAABegOGHgACAAAA
+BAAAAXoEiB4AAgAAAAMAAAF7BIwfAAAAAAAEAAABfASRHwABQAAAAwAAAX4ElR8AAwAAAAQAAAF/
+BZcfAALAAAADAAABgAWZIAAAQAAAAwAAAYEFnSAAAUAAAAMAAAGCBZ8gAAHAAAADAAABgwWhIAAD
+AAAABAAAAYMFpSEAAEAAAAMAAAGFBQAA9FkBAAAAAAD0WQEAAAAAAPRZAQAAAAAA9FkBAAAAAAD0
+WQEAAAAAAPRZAQAAAAAA9FkBAAAAAAD0WQEAAAAAAOBTAQAYAAAApFUBACAAAABcWwEAFAAAAFBc
+AQAUAAAAWFkBAA4AAAA8WAEADgAAACxZAQAUAAAALFkBABQAAABAI0AlISEhIUBAQEBABQQEAQFA
+QEBABQVAQAwMQA0MDAEBAQVAQAUFAAQABEBAAARAQEAFQEBAQEAFQEBABQUFAQEBAUAFBQUBBQEB
+QAUFBUAFQAUFBQUFAAAAAAAAAABkAAAAAJABAAoAAAAEAAAAHBEAABwyAAAcMwAABAAAABwVAAAc
+AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAClxoT4me6N9g3/vdax3lSRUGADAqnO
+fVYZ52K15k2a7EWPnR9AiYf6Fe/rssmOC/vsQWez/V/qRb8j91OW5FubwnUc4a49akxabEF+AvVP
+g1xo9FE00Qj5k+Jzq1NiPyoMCFKVZUZenSgwoTcPCrUvCQ42JJsbPd8mzWlOzX+f6hsSnh10WC40
+LTay3O60+1v2pE12YbfOfXtSPt1xXpcT9aZouQAALMFgQB/jyHnttr7URo3ZZ0ty3pTUmOiwSoVr
+uyrF5U8W7cWG15pVZpQRz4oQ6QYEgf7woER4uiXjS/Oi/l3AgIoFrT+8IUhwBPHfY8F3da9jQjAg
+GuUO/W2/TIEUGDUmL8PhvqI1zIg5LleT8lWC/Ed6rMjnuisyleagwJgZ0Z5/o2ZEflSrO4MLyowp
+x9NrPCh5p+K8HRZ2rTvbVmROdB4U25IKDGxI5Lhdn26970OmxKg5pDE304vyMtVDi1lut9qMAWSx
+0pzgSbTY+qwH8yXPr8qO9OlHGBDVb4jwb0pyXCQ48VfHc1GXI8t8oZzoIT7dltxhhg2FD5DgQnzE
+carM2JAFBgH3Ehyjwl9q+a7QaZEXWJknOrknONkT67MrMyK70nCpiQenM7YtIjySFSDJSYf/qnhQ
+eqWPA/hZgAkXGtplMdfGhLjQw4KwKXdaER7Le/yo1m06LAABAgQEAAAABAwMCAQMBARAAAAAgAAA
+AAABAAAAAgAAQAAAAAAEAABAAAAAQAAAAADwYQAAAQECAQICAwAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAQAAAAAAAAAAEA
+AAABAAAAAAAAAP8AAAD/AAAAAAAAAAAAAABEoQAAAAAAACoAAAAOAAAAAAABAQAAAAAAAAAAAAEB
+AAAAAAIAAQACAgMDA7ywAQDIsAEA1LABAOCwAQDosAEA8LABAAEBAAECAQEBAAAAAAAAAAD/////
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB
+AAAAAQAAAAAAAAAAAAAAAAAAAIANAAAAIAAAgA0AAIANAAAAIAAAgA0AAAAGAAAABAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAEAAAALAEAAAcA
+AAAAAAAACAAAAAQAAAAQPoAACQAAAAQAAAAQGAAACgAAAAQAAAB8PYAACwAAAAQAAAAAPoAADAAA
+AAQAAAAQGAAADQAAAAQAAABsPYAADgAAAAAAAAAPAAAABAAAABMAAAA=
+====
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/iwn/iwlwifi-6000g2b-18.168.6.1.fw.uu
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/contrib/dev/iwn/iwlwifi-6000g2b-18.168.6.1.fw.uu Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,11961 @@
+Copyright (c) 2006-2012, Intel Corporation.
+All rights reserved.
+
+Redistribution. Redistribution and use in binary form, without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions must reproduce the above copyright notice and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+* Neither the name of Intel Corporation nor the names of its suppliers
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+* No reverse engineering, decompilation, or disassembly of this software
+ is permitted.
+
+Limited patent license. Intel Corporation grants a world-wide,
+royalty-free, non-exclusive license under patents it now or hereafter
+owns or controls to make, have made, use, import, offer to sell and
+sell ("Utilize") this software, but solely to the extent that any
+such patent is necessary to Utilize the software alone, or in
+combination with an operating system licensed under an approved Open
+Source license as listed by the Open Source Initiative at
+http://opensource.org/licenses. The patent license shall not apply to
+any other combinations which include this software. No hardware per
+se is licensed hereunder.
+
+DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER 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.
+begin-base64 644 iwlwifi-6000g2b-18.168.6.1.fw.uu
+AAAAAElXTAo2MDAwZzJiIGZ3IHYxOC4xNjguNi4xIGJ1aWxkIDAKAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAQaoEgAAAAABAAAAAAAAAAEAAAC8cAIAICCADwAAQABpIAAAaSBAAGkg
+AABpIEAAICCADwAA6ABpIAAAaSBAAGkgAABpIEAAICCADwEA6ARpIAAAaSBAAGkgAABKIAAASiEA
+AEoiAABKIwAASiQAAEolAABKJgAASicAAEogABBKIQAQSiIAEEojABBKJAAQSiUAEEomABBKJwAQ
+SiAAIEohACBKIgAgSiMAIEokACBKJQAgSiYAIEonACBKIAAwSiEAMAokgD+BAABAQSycMEAsnDBC
+JBw0CiKAP4AAIHMKIwA3DguAB0omAHBpIEAASiYAcEomAHBKJgBwSiYAcAAWAHCAAMgzQHggIECH
+AAAAAAAAAAAAAPwciLb8HEi2/BwItvwcyLX8HIi1/BxItfwcCLX8HMi0/ByItPwcSLT8HAi0/BzI
+s/wciLP8HEiz4H7geATcON018OB4BNw03TPw4HgE3DDdMfDgeATcLN0v8OB4BNwo3S3w4HgE3CTd
+K/DgeATcIN0p8OB4BNwc3Sfw4HgE3BjdJfDgeATcFN0j8OB4BNwQ3SHw4HgE3AzdH/DgeATcCN0c
+8OB4BNwE3RnwNBQaMDAUGTAsFBgwKBQXMCQUFjAgFBUwHBQUMBgUEzAUFBIwEBQRMAwUEDACxwHG
+sCRNM7AkHzPgfuB44HjgeOB44HjgeAokgPAFIEQA4CDBB0Qk/oBBKsQAhAACAC8kAvFCIQEBQiAD
+AeggogQEEQQCBBEFAgQRBgIEEQcCBBsIAQQbSAEEG4gBBBvIASwAJQBEIj6BPAAiAEQi/IBAIcEA
+4CDBB0AjwwCoIIABARGEAgEbCgEgIMAHBBEEAgQRBQIEGwgB1Afh/wQbSAFEIvyABBEEAskH7/8E
+GwgBQiFBAEIgQwCoIIABARGEAgEbCgEgIMAHz3GgAKwvGIGauBih4QXgEgXY4HjPcaAArC8YgbO4
+urgYoc0F4BJk2AoiQIAA2e4AAQAvJgDwSiZAAE4ABgBPACAAiiX/D+B4CiJAgADZzgABAGwAJAAv
+JgDwXAAFACsINQhKJkAACHEA2AIhvoDgIMUHQnkB4AIhvoDgIMUHQnnrB+//AeAvLQEAQCVFAAIm
+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
+TyECBAMUgTAMuSV6IcEOuUV5JXggwYHhCPQHFIEwIsIGuQi6RXkleOB/o8CjweHFQsEJFIEwQ8KD
+4UHAANgK9oDhyPYKFIEwgOHE9oPhw/YB2AcUgjAGFIMwUHMG8iLBMHPMIkKAA/QB2CHFgeUQ9AoU
+gTAjw3BxSvYLFIIwUHHMI6qAhPaA4sogaQCB4A30iiHJD89wgACICiCggeX/2cohIgAhoMHF4H+j
+wPHAQg3P/s91gABoCwAVBRBMJUCCWffPdoAA+FrPd4AACG4E8AAVBRABhUAtAQIleCCGMHAC8gCm
+8CdAEUB4gODy82kFz/4KIcAP63LPcAAAhidj2/EAIABKJIAAosHhxULBQSgCAgd6QSgBBEd5z3KA
+AJDWxrkqYue6EvQIFAMxz3WAANDZqXFWeUCBUHAF9EKRcHIG8keJ57r384DYA/AGicHF4H+iwPHA
+z3KAABrXMmg2eTFiosFAwUHAi3AI2Z7aHtvaDuANGLuiwNHA4H7gfuB48cAIyJW4CBoYMAnIm7gJ
+GhgwC8iKuI24kLgLGhgwz3CAAKQ1A4AYiIHgDPQLyM9xAAB8Kay4CxoYMN4N4AYP2NHA4H7xwOHF
+CHU+iM9wgABEH0CAQCUAFAO5NXlZYYYK4A4K2poP7/+pcH0Ez/7gePHApcFBwELBDBwAMRAcQDHP
+cYAAfJY0GcAPMBkADywZwA4oGYAOJBlADs9wgAB8liAYQAvPcIAAfJYcGAALz3CAAHyWGBjACs9w
+gAB8lhQYgArPcIAAfJYQGMAIz3CAAHyWDBiACM9wgAB8lggYQAjPcYAAAJaAGQAIfBnAB3gZgAd0
+GUAHcBkAB2wZAAdoGYAGZBlABmAZAAZcGcAFWBmABVQZQAVQGQAFTBnABEgZgAREGUAEQBkABO+h
+zqGtoYyhLBnAAigZgAIkGUACIBkAAhwZwAEYGYABFBlAARAZAAFjoWogAAPYGQAAaiDAAtQZAABq
+IIAC0BkAAGogQAHIGQAAaiAAAcQZAABqIMAAwBkAAGoggAC8GQAAaiBAALgZAABqIAAAtBkAAGog
+gAHMGQAAQMMBwALBUyfNNQwUBjBTJcQ1UybFNde6qXO6CGAGEBQHMJoKIA4A2HoPwAPPcAAArd6W
+D8AACNgA2dII4AaZuf0HwA7xwIoKz/7PcoAApDyA4c91gADcXg7yAKIAhYDgE/QyDGABD9jyCCAI
+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
+gAmAgQAaGygPGw4imAmAgQAAQBYBABsmAABAFwAIgIEPGhsiAAAbJQIAG0AAABtxAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAEgAC4AYAAAAAA
+AAAAAAAoAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMqYAADAYAAAypgADI1gAA
+CQ0RFAoNExcZGRkZCQkAACSkgABEgQAADKmAAAAAAAAMqYAAAAAAACjFgABkgQAAMIAAAAAAAAAx
+gAAAiIgzMzKAAAAAqqqKM4AAAAAAAAA0gAAAAAAAADWAAAAAAAAANoAAAAAAAAA3gAAAAAAAADiA
+AAAAAAAAOYAAAAAAAAA6gAAAAAAAADuAAAAAAAAAPIAAAAAAAAA9gAAAqqoKAD6AAABThYiIP4AA
+AAAAADAwgAAAAAAAADGAAACamVhVMoAAAACqqqozgAAAAAAAADSAAAAAAAAANYAAAAAAAAA2gAAA
+AAAAADeAAAAAAAAAOIAAAAAAAAA5gAAAAAAAADqAAAAAAAAAO4AAAAAAAAA8gAAAAAAAAD2AAACq
+qgoAPoAAAFWYmao/gAAAAAAAUDCAAAAAAAAAMYAAAAAAAAAygAAAAAAAADOAAAAAAAAANIAAAAAA
+AAA1gAAAAAAAADaAAAAAAAAAN4AAAAAAAAA4gAAAAAAAADmAAAAAAAAAOoAAAAAAAAA7gAAAAAAA
+ADyAAAAAAAAAPYAAAAAAAAA+gAAAAAAAAD+AAAAAAAAAMIAAAAAAAAAxgAAAAAAAADKAAAAAAAAA
+M4AAAAAAAAA0gAAAmnkAADWAAACqqqqqNoAAAAAAAAA3gAAAAAAAADiAAAAAAAAAOYAAAAAAAAA6
+gAAAqqqqCjuAAAAAcJmqPIAAAAAAAAA9gAAAAAAAAD6AAAAAAAAAP4AAAAAAAAD//wAApQEBALkB
+3wA7Ai0AsQAbABYBGwCvABsAFAEbAGwAoADRAKAAbwCDAHEAgwBzADMA1AEGANABAAB4AEkAeQBq
+AN4AagCoAAAADQEAAKYAPwCnAAEACwE/AAwBAQAEAAgAnAHMAJ0BzADVAcwA1gHMALQAIAAZASAA
+jwCIAPQAiACQACIA9QAiAJEABAD2AAQAhQAAAIYAAACHAFUAiAAAAIkAqgCKAAAAiwDdAIwAAACF
+AAEAhgABAIcAVQCIAAAAiQCqAIoAAACLAN0AjAAAAIUAAgCGAAMAhwBVAIgAAACJAKoAigAAAIsA
+3QCMAAAAhQADAIYABwCHAFUAiAAAAIkAqgCKAAAAiwDdAIwAAAD7/wAA//8AALkB3wA7Ai0AsQAb
+ABYBGwCvABsAFAEbAGwAoADRAKAAbwCDAHEAgwBzADMA1AEGANABAAB4AEkAeQBqAN4AagCoAAAA
+DQEAAKYAPwCnAAEACwE/AAwBAQAEAAgAnAHMAJ0BzADVAcwA1gHMALQAIAAZASAAjwCIAPQAiACQ
+ACIA9QAiAJEABAD2AAQAqAAMAA0BDACFAAAAhgAAAIcAmQCIAAAAiQCqAIoAAACLAN0AjAAAAIUA
+AQCGAAEAhwCZAIgAAACJAKoAigAAAIsA3QCMAAAAhQACAIYAAwCHAJkAiAAAAIkAqgCKAAAAiwDd
+AIwAAACFAAMAhgAHAIcAmQCIAAAAiQCqAIoAAACLAN0AjAAAAPv/AAD//wAAuQHfALEAGwAWARsA
+rwAbABQBGwBsAKAA0QCgAG8AgwBxAIMAdgCDAHMAMwBuADMAcAAzAHIAMwDXADMA1AEGANABAAB+
+ADwA4wA8AHgASQDdAEkAfwBaAOQAWgCqAD8AqwABAA8BPwAQAQEAeQBqAN4AagCoAAAADQEAAKYA
+NwCnAAEACwE3AAwBAQAEAAgAnAHMAJ0BzADVAcwA1gHMALQAIAAZASAAMQIMADICDAAzAr0ANgIM
+ADcCDAA4Ar0AoACIAAUBiAChANUABgHVAKIABAAHAQQAjwCIAPQAiACQACIA9QAiAJEABAD2AAQA
+nwAMAPsADACUAAAAlQAAAJwAlwCdANAAmgCNAJgAEQCWADMAlwB3AJQAAQCVAAEAnACXAJ0A0ACa
+AI0AmAARAJYAMwCXAHcAlAACAJUAAwCcAJcAnQDQAJoAjQCYABEAlgAzAJcAdwCUAAMAlQAHAJwA
+lwCdANAAmgCNAJgAEQCWADMAlwB3APoAAAD5AAAAAgGXAAMB0AAAAY0A/gARAPwAMwD9AHcA+gAB
+APkAAQACAZcAAwHQAAABjQD+ABEA/AAzAP0AdwD6AAIA+QADAAIBlwADAdAAAAGNAP4AEQD8ADMA
+/QB3APoAAwD5AAcAAgGXAAMB0AAAAY0A/gARAPwAMwD9AHcAhQAAAIYAAACHAFUAiAAAAIkApwCK
+AAAAiwDeAIwAAACFAAEAhgABAIcAVQCIAAAAiQCnAIoAAACLAN4AjAAAAIUAAgCGAAMAhwBVAIgA
+AACJAKcAigAAAIsA3gCMAAAAhQADAIYABwCHAFUAiAAAAIkApwCKAAAAiwDeAIwAAADrAAAA6gAA
+AOwAVQDtAAAA7gCnAO8AAADwAN4A8QAAAOsAAQDqAAEA7ABVAO0AAADuAKcA7wAAAPAA3gDxAAAA
+6wACAOoAAwDsAFUA7QAAAO4ApwDvAAAA8ADeAPEAAADrAAMA6gAHAOwAVQDtAAAA7gCnAO8AAADw
+AN4A8QAAAKQBgAChAUAA+/8AAP//AAClAQEAuQHfALEAGwAWARsArwAbABQBGwBsAKAA0QCgAG8A
+gwBxAIMAdgCDAHMAMwBuADMAcAAzAHIAMwDXADMA1AEGANABAAB+ADwA4wA8AHgASQDdAEkAfwBa
+AOQAWgCqAD8AqwABAA8BPwAQAQEAeQBqAN4AagCoAAAADQEAAKYANwCnAAEACwE3AAwBAQAEAAgA
+nAHMAJ0BzADVAcwA1gHMALQAIAAZASAAMQIMADICDAAzAr0ANgIMADcCDAA4Ar0AoACIAAUBiACh
+ANUABgHVAKIABAAHAQQAjwCIAPQAiACQACIA9QAiAJEABAD2AAQAnwAMAPsADACUAAAAlQAAAJwA
+lwCdANAAmgCNAJgAEQCWADMAlwB3AJQAAQCVAAEAnACXAJ0A0ACaAI0AmAARAJYAMwCXAHcAlAAC
+AJUAAwCcAJcAnQDQAJoAjQCYABEAlgAzAJcAdwCUAAMAlQAHAJwAlwCdANAAmgCNAJgAEQCWADMA
+lwB3APoAAAD5AAAAAgGXAAMB0AAAAY0A/gARAPwAMwD9AHcA+gABAPkAAQACAZcAAwHQAAABjQD+
+ABEA/AAzAP0AdwD6AAIA+QADAAIBlwADAdAAAAGNAP4AEQD8ADMA/QB3APoAAwD5AAcAAgGXAAMB
+0AAAAY0A/gARAPwAMwD9AHcAhQAAAIYAAACHAFUAiAAAAIkApwCKAAAAiwDeAIwAAACFAAEAhgAB
+AIcAVQCIAAAAiQCnAIoAAACLAN4AjAAAAIUAAgCGAAMAhwBVAIgAAACJAKcAigAAAIsA3gCMAAAA
+hQADAIYABwCHAFUAiAAAAIkApwCKAAAAiwDeAIwAAADrAAAA6gAAAOwAVQDtAAAA7gCnAO8AAADw
+AN4A8QAAAOsAAQDqAAEA7ABVAO0AAADuAKcA7wAAAPAA3gDxAAAA6wACAOoAAwDsAFUA7QAAAO4A
+pwDvAAAA8ADeAPEAAADrAAMA6gAHAOwAVQDtAAAA7gCnAO8AAADwAN4A8QAAAKQBgAChAUAA+/8A
+AAAAAAAAAAAAAQAAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAAAAAAAAQAAAQEAAAAAAQEAAAAA
+AAAAAAAAAAABAQEBAgAAAA3SEtIT0hTSDNIV0gvSAtIR0gRDABAUEAkQERABQBvSHNIA0goACwAE
+AA4AtQAaAQ8AQgC8AMMAIQEoAbYAtwC4ALkAvQC+AL8AwAAbARwBHQEeASIBIwEkASUBCgAAAAsA
+AAC2AAAAtwAAALgAAAC5AAAAGwEAABwBAAAdAQAAHgEAAL0AAAC+AAAAvwAAAMAAAAAiAQAAIwEA
+ACQBAAAlAQAAEtIAABPSAAAAAAEAAgADACwAZAB0AIAAjAChAAcAAAAAAAEAAgADAAAAAAC3EyIA
+uBQjALkVJAC7FiUAvBcmAL0YJwDAGSgAxBopAAcbAAAIHAEACx0CAAweAwAQHwQAIiEFACQiBgAm
+IwcAKCQIAColCQAsJgoALicLADAoDAA0KQ0AOCoOADwrDwBALBAAZC4RAGgvEgBsMBMAcDEUAHQy
+FQB4MxYAfDQXAIA1GACENhkAiDcaAIw4GwCROhwAlTsdAJk8HgCdPR8AoT4gAKU/IQAkSQYCLEoK
+AjRLDQE8TA8BZE0RAWxOEwF0TxUBfFAXAYRRGQGVUh0BnVMfAQEEAAACBQEAAwYCAAQHAwAFCAQA
+BgkFAAcKBgAICwcACQwIAAoNCQALDgoADA8LAA0QDAAOEQ0AAUAABAJBAQQDQgIEBEMDBAVEBAQG
+RQUEB0YGBAhHBwQJSAgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAIAAgADAAQABAAFAAYABgAHAAgACAAJ
+AAoACgALAAwADAANAA4ADgAPACYAJwAoACkAKgBGAEYARwBIAEgASQBKAEoASwBMAGgAaQBqAGoA
+awBsAGwAbQBuAG4AbwBwAHAAcQByAHIAcwBzAHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0
+AHQAdAB0AHQACgA/AAAAAAAAAAAAAAAAAAAAAAABAAEAAgADAAMABAAFAAUABgAHAAcACAAJAAkA
+CgALAAsADAAMAA0ADgAjACQAJQAmACcAKAApAEQARQBGAEYARwBHAEgASABJAEkASgBLAGgAaABp
+AGoAawBsAG0AbQBuAG8AbwBwAHEAcQByAHIAcwBzAHMAcwBzAHMAcwBzAHMAcwBzAHMAcwBzAHMA
+cwBzAHMACgA/AAAAAAAAAAAAAAAAAAAAAAABAAIAAgADAAQABAAFAAYABgAHAAgACAAJAAoACgAL
+AAwADAANAA4ADgAPACYAJwAoACkAKgBGAEYARwBIAEgASQBKAEoASwBMAGgAaQBqAGoAawBsAGwA
+bQBuAG4AbwBwAHAAcQByAHIAcwBzAHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0
+AHQACgA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQACAAMAAwAEAAUABQAGAAcABwAIAAkA
+CQAKAAoACwAkACUAJQAmACcAKAAoAEQARQBGAEYARwBIAEgASQBKAEoASwBMAGgAaABpAGoAawBs
+AG0AbQBuAG8AbwBwAHEAcQByAHIAcgByAHIAcgByAHIAcgByAHIAcgByAHIAcgByAHIAcgByAHIA
+CgA/AIBzgAAAAAAAsgzIAP////////8AAf//AgP///8E//////////////////////8F/wb/B/8I
+/wn/Cv8L/wz///8N////Dv///w////8Q////////////////////////////////////////////
+//8R////Ev///xP///8U////Ff///xb///8X////GP///xn///8a////G/////8c////Hf///x7/
+//8f////IP///yH//////////////////////yIjJP8lJif//yj///8p////////////////////
+//////////////////////////////////////////////////////////8AAQABAQAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAQAAAAAAAACYRgEAAAAA
+AGR4AAABAAAARAcCAAIAAAC0BgIAAwAAAGBpAgAEAAAAmEYBAAUAAADALwEABgAAAGQDAQAHAAAA
+UDABAAgAAAAIOAAACQAAAPRqAAAKAAAAANkAAAsAAAD0MQAADAAAAGRpAgANAAAABPYAAA4AAAC4
+9gAADwAAAJD1AAAQAAAAlPYAABEAAAAoXwEAEgAAAHQnAgATAAAA7CMAABQAAABEiQEAFQAAAExz
+AQAWAAAAvIIBABcAAADwBQIAGAAAAMS0AQAZAAAA9CEBABoAAACURgEAGwAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAABGgAAASAAAAUgAS4JIgEyDyAHMBMiCzIZIBEwHSIVMiMgGzAnIh8xLSAAADEfAAA3GQAA
+OxUAAAAAAAAAAAAAVJ8AAFSfAABUnwAARIgAAFSfAABUnwAAqIgAAFSfAABUnwAAVJ8AAFSfAABU
+nwAAVJ8AAFSfAABUnwAAVJ8AACiQAABsjwAAXI8AANCOAACUjwAAjI4AAFSfAABUnwAAEJYAAPyY
+AACsmgAAVJ8AAFSfAABUnwAAvJ4AACiVAABglQAAzJQAAFSfAABUnwAAVJ8AAHieAABUnwAArJQA
+AFSfAABUnwAAVJ8AAFSfAABUnwAAVJ8AAFSfAABUnwAAVJ8AAFSfAABUnwAAVJ8AAFSfAABUnwAA
+VJ8AAFSfAABUnwAAVJ8AAFSfAABUnwAAVJ8AAFSfAABUnwAAVJ8AAFSfAABUnwAAVJ8AAFSfAABU
+nwAAVJ8AAFSfAABUnwAAaIkAAFSfAABUnwAAVJ8AAFSfAABUnwAAyJsAAFSfAABUnwAAVJ8AAFSf
+AABUnwAAUIwAAFSfAABgjAAAXIwAAFSMAABYjAAAJIYAAFSfAAD4hQAAVJ8AAFSfAABUnwAAVJ8A
+AFSfAABUnwAAVJ8AAFSfAACEhQAAVJ8AAFSfAABUnwAAVJ8AAFSfAABUnwAAVJ8AAFSfAABUnwAA
+VJ8AAFSfAACgigAAPIoAAFSfAAC8igAAVJ8AAIiJAABQjgAAVJ8AAFSfAABIkAAAVJ8AAFSfAABU
+nwAAVJ8AAFSfAACckQAAeJAAAFSfAABUnwAAVJ8AAFSfAABUnwAAVJ8AAFSfAABUnwAAVJ8AAFSf
+AABUnwAAZIwAAFSfAABUnwAAVJ8AAGybAABUnwAAVJ8AAFSfAAAMngAAVJ8AAHCeAAAImwAAVJ8A
+AFSfAACkhAAAyJoAAFSfAABUnwAA2I4AAPCOAABUnwAAVJ8AAAyMAABohgAAVJ8AAFSfAABUnwAA
+aJUAAHSOAABUnwAAVJ8AAFSfAABUnwAAVJ8AAFSfAACsjQAAVJ8AADigAAB4ogAArKEAAICiAACk
+oQAAnKEAAIiiAAB4nwAAVJ8AAFSfAABUnwAAVJ8AAFSfAABUnwAAVJ8AAFSfAAAUjAAAVJ8AAFSf
+AABUnwAAVJ8AAFSfAABUnwAAVJ8AAByjAAAwpAAAxIQAAOSEAABUnwAAVJ8AAFSfAABUnwAAVJ8A
+AJyGAABUnwAAVJ8AAFSfAABUnwAAVJ8AAFSfAABUnwAAVJ8AAFSfAABUnwAAVJ8AAFSfAABUnwAA
+VJ8AAFSfAABUnwAAVJ8AAFSfAABUnwAAVJ8AAFSfAABUnwAAVJ8AAFSfAABUnwAAVJ8AAFSfAABU
+nwAAoIYAAJCHAAAwhwAAkKIAABCFAAAciAAAtIgAAFSfAABUnwAAVJ8AAFSfAACgiAAApIgAAFSf
+AABUnwAASIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPCxAAA4sAAAXLMAAGSyAABwtAAAAAABAP////8AAAAA
+//////////8BAAAAIA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAADQ/gAAAAAA
+AAAAAAAAABggoAAgIKAAQCGgAEghoAAcIKAAJCCgAEQhoABMIaAAKCCgADAgoABoIaAAcCGgACwg
+oAA0IKAAbCGgAHQhoAA4IKAAPCCgAHghoAB8IaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA
+AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADUDAAAAP8DAHQNAAAA/wUA
+GA0AAAD/LQD0DAAAAP89AJAMAAAA/wQAuAwAAAD/JQCY3AAAAP/dADwNAAAQEEwAAAAAAAAAAAAA
+AQEAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwVFRUVPDw8PBUVFRU8PDw8AAAAAAAA
+AAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8FRUVFTw8PDwVFRUVPDw8
+PAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PBUVFRU8PDw8
+FRUVFTw8PDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGgPAAAUFgAAxBIAAEQQAADUFwAAvBMAABAVAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AABsCoAAtKmAABgAAAB0qYAAAAAAAAAAAAAAAAAAAAAAAFgfAQCAvwAAdCAAAIC/AACAvwAAgL8A
+AAgHAACAHwIAOOoAAIC/AACAvwAAYCcAAGAnAABgJwAAYCcAAGAnAABgJwAAYCcAAIC/AACAvwAA
+gL8AAIC/AABsUgAAgL8AAIC/AACAvwAAgL8AAIC/AAAc6gAAgL8AAIC/AADU2wAAAAAAALwGAQDA
+BgEAtAIAAKACAAA8XgEAAAAAAHDOAAAA6gEAmM4AACjqAQC8zgAAUOoBAEhMgACgnoAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAALB4AAPQdAAC4qoAAAAIAAAAAAACgFQEAcBUBALisgABABQAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApBUBAAhbAQBIs4AAVAAAAAAAAACgFQEA3FkBAPixgABQ
+AQAAAAAAAKAVAQDQVAEAvAqAAAgAAAABAAAAoBUBAGwUAQAAAAAAUAEAAAAAAACgFQEAXFUBANxE
+gAACAAAAAAAAAKAVAQBoVAEAuAqAAAQAAAAAAAAAqBUBAHAVAQCcs4AAKgAAAAAAAACgFQEAcBUB
+ADxTgAAEAAAAAAAAAAAAAAB4FQEAAAAAAAAAAAABAAAAAAAAAIwVAQAAAAAAAAAAAAAAAAAAAAAA
+dBUBAAAAAAAAAAAAAAAAAKAVAQCA7AEAAAAAAAAAAAAAAAAAoBUBAEDsAQDECoAABAAAAAAAAABu
+AG4AaQDAAKAAUACAAL4AUAF9AD4AAAAAAAAAnAIEAOYBJQBVAwQA3AFjAAAAbgBuAGkAwACgAFAA
+gAC+AFABfQA+AAAAAAAAAJwCBADmASUAVQMEANwBYwAAAAAAAAABAQAAoB4BABXSAAAAAAAA/wMA
+AKAeAQAM0gAAAAAAAP8BAACgHgEAFdIAAAoAAAAA/A8AoB4BAAzSAAAJAAAAAP4DAKAeAQAV0gAA
+FAAAAAAA8D+gHgEADNIAABIAAAAAAPwHoB4BAAbSAAAAAAAA/wEAAKAeAQAH0gAAAAAAAP8DAACg
+HgEABtIAAAkAAAAA/gMAoB4BAAfSAAAKAAAAAPwPAKAeAQAG0gAAEgAAAAAA/AegHgEAB9IAABQA
+AAAAAPA/AAAAAAAAAAAAAAAAAQAAAAEAAAAKAAAABQAAAAUAAAAGAAAACgAAAAoAAAAGAAAABAAA
+AAUAAAAGAAAABQAAAAUAAAAGAAAABgAAAAYAAAAGAAAABwAAAAcAAAAHAAAACAAAAAgAAAAIAAAA
+BAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAEAAAACAAAAAQAAAAEAAAADAAAAAwAAAAIAAAAB
+AAAABAAAAAAAAAAAAAAAAgAAAAEAAAABAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAEAAAAAAAAALAEAAF4BAAABAAAAAQAAAAEAAAABAAAAAwAAAAAAAAAAAAAA
+vCkBAEQuAQAwLQEAsC4BAEAuAQBsLAEArC4BAPAqAQDsKgEAYOMWACDWEwAAAAAAEAAAAACAAAAA
+AKAAECcAAOgDAADoAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAgAAAAEAAAABAAAAAgAA
+AAUAAAACAAAAAgAAAAUAAAACAAAAAgAAAAEAAAABAAAABQAAAAUAAAACAAAABQAAAAUAAAAAAAAA
+BQAAAAIAAAACAAAAAAAAAAAAAAAAAAAABQAAAAUAAAAAAAAABQAAAAIAAAACAAAABQAAAAUAAAAF
+AAAAAAAAAAUAAAACAAAABQAAAAEAAAABAAAAAgAAAAIAAAACAAAABQAAAAUAAAACAAAABQAAAAEA
+AAABAAAAAgAAAAIAAAACAAAABQAAAAUAAAACAAAAAgAAAAUAAAABAAAAAgAAAAUAAAACAAAABQAA
+AAUAAAAEAAAABQAAAAUAAAABAAAABQAAAAUAAAAFAAAAAgAAAAIAAAAFAAAABQAAAAUAAAABAAAA
+BQAAAAUAAAAFAAAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAA
+AAAAAAAACAAAAAAAAAABEAABAAAAAoAAAUIABgIQAAIgAAADwAABQwAGAxAAAsAAAAPAAAFDAAYE
+EAACQAAAAoAAAUQABgURAABAAAADwAABRQAGBhEAAOAAAAPAAAFFAAYHEQABAAAAAoAAAUYABggR
+AAIgAAADwAABRwAGCREAAsAAAAPAAAFHAAYKEQACQAAAAoAAAUgABgsSAABAAAADwAABSQAGDBIA
+AOAAAAPAAAFJAAYNEgABAAAAAoAAAUoABg4SAAIAAAACgAABTAAGAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AQIBAQACAQABAgICAAEBAAIBAgECAAIAAQIDgICAgICAgIABgAKAgICAgMAAkADQAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbgAAAG4AAgBuAG4AbgACAGkAaQBuAAEA
+wADAAOgAAQCgAKAANgEDAFAAUAD1AAEAgACAAOgAAQC+AL4AvgABAFABUAFQAQEAfQB9AK8AAwA+
+AD4APgABAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAABAJwCnAKcAgEABAAEAAQAAQDmAeYB5gEBACUA
+JQAlAAEAVQNVA1UDAQAEAAQABAABANwB3AHcAQEAYwBjAGMAAQAAAAAAAAAAADIABQAyAAUAAgAI
+AGQAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAjAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACE
+EwIAFQAAAAMAAAC4WYAAAAAAAAAAAAAAAAAAmA4CAAYAAAAAAAAA2FmAAAAAAAAAAAAAAAAAACgT
+AgAFAAAAAwAAALhZgAAAAAAAAAAAAAAAAAAkVgAAFQAAAAMAAAC4WYAAAAAAAAAAAAAAAAAAEBMC
+AAoAAAADAAAAuFmAAAAAAAAAAAAAAAAAAMQQAgAEAAAAAAAAANhZgAAAAAAAAAAAAAAAAADEEAIA
+BAAAAAAAAADYWYAAAAAAAAAAAAAAAAAAxBACAAQAAAAAAAAA2FmAAAAAAAAAAAAAAAAAAMQQAgAE
+AAAAAAAAANhZgAAAAAAAAAAAAAAAAADEEAIABAAAAAAAAADYWYAAAAAAAAAAAAAAAAAAaBECAAYA
+AAAAAAAA2FmAAAAAAAAAAAAAAAAAAJARAgAEAAAAAAAAANhZgAAAAAAAAAAAAAAAAACQEQIABAAA
+AAAAAADYWYAAAAAAAAAAAAAAAAAAkBECAAQAAAAAAAAA2FmAAAAAAAAAAAAAAAAAAJARAgAEAAAA
+AAAAANhZgAAAAAAAAAAAAAAAAABoEQIABgAAAAAAAADYWYAAAAAAAAAAAAAAAAAAaBECAAYAAAAA
+AAAA2FmAAAAAAAAAAAAAAAAAAGgRAgAGAAAAAAAAANhZgAAAAAAAAAAAAAAAAACQEQIABAAAAAAA
+AADYWYAAAAAAAAAAAAAAAAAAkBECAAQAAAAAAAAA2FmAAAAAAAAAAAAAAAAAAGgPAgAKAAAAAAAA
+ANhZgAAAAAAAAAAAAAAAAADAEAIACgAAAAAAAADYWYAAAAAAAAAAAAAAAAAAwBACAAoAAAAAAAAA
+2FmAAAAAAAAAAAAAAAAAAMAQAgAKAAAAAAAAANhZgAAAAAAAAAAAAAAAAADAEAIACgAAAAAAAADY
+WYAAAAAAAAAAAAAAAAAAwBACAAoAAAAAAAAA2FmAAAAAAAAAAAAAAAAAAMAQAgAKAAAAAAAAANhZ
+gAAAAAAAAAAAAAAAAADAEAIACgAAAAAAAADYWYAAAAAAAAAAAAAAAAAAwBACAAoAAAAAAAAA2FmA
+AAAAAAAAAAAAAAAAAMAQAgAKAAAAAAAAANhZgAAAAAAAAAAAAAAAAADAEAIACgAAAAAAAADYWYAA
+AAAAAAAAAAAAAAAAwBACAAoAAAAAAAAA2FmAAAAAAAAAAAAAAAAAAMAQAgAKAAAAAAAAANhZgAAA
+AAAAAAAAAAAAAAD4FAIABgAAAAAAAADYWYAAAAAAAAAAAAAAAAAAXBQCAAUAAAADAAAAuFmAAAAA
+AAAAAAAAAAAAAMAOAgAKAAAAAAAAANhZgAAAAAAAAAAAAAAAAAAwDwIACgAAAAAAAADYWYAAAAAA
+AAAAAAAAAAAAHCYCAAoAAAADAAAAuFmAAAAAAAAAAAAAAAAAAIQPAgAKAAAAAAAAANhZgAAAAAAA
+AAAAAAAAAAA8EAIACgAAAAAAAADYWYAAAAAAAAAAAAAAAAAAKBICAAoAAAAAAAAA2FmAAAAAAAAA
+AAAAAAAAALASAgAKAAAAAAAAANhZgAAAAAAAAAAAAAAAAACIEwIACgAAAAAAAADYWYAAAAAAAAAA
+AAAAAAAABBQCAAoAAAAAAAAA2FmAAAAAAAAAAAAAAAAAADAUAgAGAAAAAAAAANhZgAAAAAAAAAAA
+AAAAAABAFAIABgAAAAAAAADYWYAAAAAAAAAAAAAAAAAAVBQCAAEAAAAAAAAA2FmAAAAAAAAAAAAA
+AAAAABgWAgAKAAAAAQAAAPhZgAAAAAAAAAAAAAAAAACMFQIABQAAAAEAAAD4WYAAAAAAAAAAAAAA
+AAAADBkCAAYAAAABAAAA+FmAAAAAAAAAAAAAAAAAAGAZAgAGAAAAAQAAAPhZgAAAAAAAAAAAAAAA
+AADgGwIACgAAAAEAAAD4WYAAAAAAAAAAAAAAAAAAAAAAALhZgAC4WYAAuCCgAGwgoAAAgAEA/3/8
+/wAAAAAAAAAA2FmAANhZgACkIKAAOCCgAAEAAAD8////AAAAAAAAAAD4WYAA+FmAAKggoAA8IKAA
+EAAAAMf///8AAAAAAAAAABhagAAYWoAArCCgAHghoABAAQAAP/7//wAAAAAAAAAAOFqAADhagACw
+IKAAfCGgAAAMAAD/8f//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfA8CABUAAAADAAAAuFmAAAAA
+AABQAAAAAAAAAGwKgAC0qYAAGAAAAHSpgAAAAAAAAAAAAGwKgAC0qYAAGAAAAHSpgAAAAAAAAAAA
+AAAAAABsCoAAtKmAABgAAAB0qYAAAAAAAAAAAAAAAAAAfwAAAAAAAAAAfwAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAA/wAA//8AAAEAAAAAAAAABwAAAAAAAAAAAAAAAAAAAAxLAQD8SQEAAAAAAAAAAAAA
+AAAAAAAAAORMAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAORMAQCwSwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxLAQD8SQEA
+AAAAAMxJAQAAAAAA2EkBAORMAQCwSwEAAAAAAAAAAAAAAAAAiEsBAMxJAQC8SQEAAAAAAAxLAQD8
+SQEAeEoBACRKAQAAAAAA2EkBAORMAQCwSwEAzEkBALxJAQAQSwEAAAAAAMxJAQC8SQEABwAAAAAA
+AAAGAAAAAgAAAAIAAAACAAAAAgAAAAYAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAA
+AAEAAAAGAAAABwAAAAcAAAAHAAAABwAAAAEAAAAGAAAAAQAAAAEAAAAAAAAAAQAAAAEAAAABAAAA
+BwAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAAC
+AAAABwAAAAMAAAADAAAABwAAAAQAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMA
+AAADAAAABwAAAAQAAAAEAAAABAAAAAQAAAAHAAAAAwAAAAQAAAAEAAAABAAAAAQAAAADAAAABAAA
+AAQAAAAEAAAAAAAAAAABAgMEBAQEBAUGBwgICAgICQoLDA0AAG47aDtiO1w7bjpoOmI6XDpuOWg5
+YjlcOW44aDhiOFw4bjdoN2I3XDduKWgpYilcKW4oaChiKFwobidoJ2InXCduGWgZYhlcGW4YaBhi
+GFwYbhdoF2IXXBduFmgWYhZcFm4VaBViFVwVbhRoFGIUXBRuE2gTYhNcE24SaBJiElwSbhFoEWIR
+XBFuEGgQYhBcEG4CaAJiAlwCbgFoAWIBXAFuAGgAYgBcAFQAAABuO2g7YjtcO246aDpiOlw6bjlo
+OWI5XDluK2grYitcK24qaCpiKlwqbiloKWIpXCluKGgoYihcKG4naCdiJ1wnbiZoJmImXCZuJWgl
+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
+qqqqqqqqqq6qqqqqKP8AzKqqAACqqgDMqqoAAABAAMAAAAAAAFAA8ABAAPCqqqqqqqqqqqqqqqqq
+qqqqqqqqqqqqqqqqqqqqqqqqqgAAAAAAAAAAAAAAAAAAAAD///8A////Af8CA////wQF/wn/BwoG
+CAsAAQECAQICAwEBAQEBAQEBAgICAgICAgIDAwMDAwMDAwQEBAQEBAQEAQICAgICAgMDAwMDAwMD
+AwMDAwMDBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAATDEAAEQzAADMLQAAzCwAAEwtAAAYMgAA
+lCwAAEAyAADAMgAAOgECAdUA3wDaAKIAdQB/AIoFKgM5AagBigXKAtkASAEBAw8HChQ3bmoBGgHZ
+AOgACgG6AHkAiADKAUoB4gD5AMoB6gCCAJkAdNFFF+iiiy4ABQcBAwQABQEFAAAABQYAAgQABQAF
+AAABAgECAwQAAAUGBwgJCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAADA2AAAUNsAAKTWAAABAAAAAAAAAAEAAAACAAAAAwAAAAAAAAAEAAAA
+AgAAAAUAAAAHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcH
+BwcHBwcHBwcGBgYGBgUFBQUFBAQEBAQDAwMDAwICAgICAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAoADAALAAsACgAPAA0AEAAPACM
+AGwAWABIAPQAsAB//wcPHz8BAzAAAAA2AAAADAAAABIAAAAYAAAAJAAAAAYAAAAJAAAABQAHAgME
+BgZAA4AGwAkADYATABpAHYAggAYADYATABoAJwA0gDoAQcAJgBNAHQAngDoATsBXgGGZAzMH2Qpz
+DqYV5hyAIBkkMwdzDqYV5hxZK8w5AEEzSNkKphWAIFkrAEGmVoBhWWyd2ImdTuzETjRIgzQndmIn
+GqRBGhM7sRMRGIERD/zAD07sxE4ndmInGqRBGhM7sRMN0iANiZ3YCQiMwAgHfuAHNEiDNBqkQRoR
+GIERDdIgDQiMwAgGaZAGsLLVBQVUQAUndmInEzuxEw3SIA2JndgJBmmQBsRO7AQERmAEAz/wA6qq
+qqoapEEaEzuxEw/8wA8RGIERDdIgDQqogAoTO7ETD/zADw/8wA8N0iANC7RACwu0QAuJndgJDdIg
+DQqogAoKqIAKCIzACAd4gAcHeIAHBmmQBg/8wA8N0iANC7RACw3SIA0LtEALiZ3YCQiMwAiJndgJ
+CIzACAd+4AcHfuAHwSwpBwqogAoIjMAIB3iABwiMwAgHeIAHBmmQBrCy1QUGaZAGsLLVBQVUQAUF
+VEAF1h3GBAEHDx8/f///ZuYAAAUGAQIDBAAAVABUAGwAYABcAFQAjAB4AA0PBQcJCwEDKAAoADQA
+MAAsACwARAA8ACwALAA8ADQAMAAsAFQARABVVVUBS2gvAVVVVQXjOI4DqqqqAnEcxwGqqqoKx3Ec
+BwAEAABkAAAAAAAAAA8APwABAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8A
+AQAAAA8APwACAAAADwA/AAEAAAAiFgAAgAAAAwAAAVkAACQWAAEAAAADAAABWgAAJhYAAgAAAAQA
+AAFaAAAoFgACAAAAAwAAAVsAACoWAAKAAAADAAABXAAALBcAAAAAAAQAAAFcAAAuFwAAgAAAAwAA
+AV0AADAXAAEAAAADAAABXgAANBcAAgAAAAMAAAFfAAA2FwACgAAAAwAAAWAAADgYAAAAAAAEAAAB
+YAAAPBgAAQAAAAMAAAFiAAA+GAACAAAABAAAAWIAAEAYAAIAAAADAAABYwAAZBsAAgAAAAMAAAFv
+AAFmGwACgAAAAwAAAXAAAWgcAAAAAAAEAAABcAABbBwAAQAAAAMAAAFyAAFuHAACAAAABAAAAXIA
+AXAcAAIAAAADAAABcwACdB0AAAAAAAQAAAF0AAJ2HQAAgAAAAwAAAXUAAngdAAEAAAADAAABdgAC
+fB0AAgAAAAMAAAF3AAN+HQACgAAAAwAAAXgAA4AeAAAAAAAEAAABeAADhB4AAQAAAAMAAAF6AAOG
+HgACAAAABAAAAXoABIgeAAIAAAADAAABewAEjB8AAAAAAAQAAAF8AASRHwABQAAAAwAAAX4ABJUf
+AAMAAAAEAAABfwAFlx8AAsAAAAMAAAGAAAWZIAAAQAAAAwAAAYEABZ0gAAFAAAADAAABggAFnyAA
+AcAAAAMAAAGDAAWhIAADAAAABAAAAYMABaUhAABAAAADAAABhQAFMJkBAAAAAAAwmQEAAAAAADCZ
+AQAAAAAAMJkBAAAAAAAwmQEAAAAAADCZAQAAAAAAMJkBAAAAAAAwmQEAAAAAAAyTAQAYAAAA1JQB
+ACAAAADsmgEAFAAAAOibAQAUAAAAlJgBAA4AAABglwEADgAAAGSYAQAUAAAAZJgBABQAAABAI0Al
+ISEhIUBAQEBABQQEAQFAQEBABQVAQAwMQA0MDAEBAQVAQAUFAAQABEBAAARAQEAFQEBAQEAFQEBA
+BQUFAQEBAUAFBQUBBQEBQAUFBUAFQAUFBQUFAAAAAAAAAABkAAAAAJABAAoAAACEzgEAPNIBADDQ
+AQAAzAEAGNYBAHjYAQDo0wEAXNEBAEjVAQAEAAAAHBEAABwyAAAcMwAABAAAABwVAAAcAgAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAClxoT4me6N9g3/vdax3lSRUGAD
+AqnOfVYZ52K15k2a7EWPnR9AiYf6Fe/rssmOC/vsQWez/V/qRb8j91OW5FubwnUc4a49akxabEF+
+AvVPg1xo9FE00Qj5k+Jzq1NiPyoMCFKVZUZenSgwoTcPCrUvCQ42JJsbPd8mzWlOzX+f6hsSnh10
+WC40LTay3O60+1v2pE12YbfOfXtSPt1xXpcT9aZouQAALMFgQB/jyHnttr7URo3ZZ0ty3pTUmOiw
+SoVruyrF5U8W7cWG15pVZpQRz4oQ6QYEgf7woER4uiXjS/Oi/l3AgIoFrT+8IUhwBPHfY8F3da9j
+QjAgGuUO/W2/TIEUGDUmL8PhvqI1zIg5LleT8lWC/Ed6rMjnuisyleagwJgZ0Z5/o2ZEflSrO4ML
+yowpx9NrPCh5p+K8HRZ2rTvbVmROdB4U25IKDGxI5Lhdn26970OmxKg5pDE304vyMtVDi1lut9qM
+AWSx0pzgSbTY+qwH8yXPr8qO9OlHGBDVb4jwb0pyXCQ48VfHc1GXI8t8oZzoIT7dltxhhg2FD5Dg
+QnzEcarM2JAFBgH3Ehyjwl9q+a7QaZEXWJknOrknONkT67MrMyK70nCpiQenM7YtIjySFSDJSYf/
+qnhQeqWPA/hZgAkXGtplMdfGhLjQw4KwKXdaER7Le/yo1m06LAABAgQEAAAABAwMCAQMBARAAAAA
+gAAAAAABAAAAAgAAQAAAAAAEAABAAAAAQAAAAADwYQAAAQECAQICAwAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAGQAAAAqAAAADgAAAAAAAQEAAAAAAAAAAAABAQAAAAACAAEAAgIDAwNIEwIAVBMC
+AGATAgBsEwIAdBMCAHwTAgABAQABAgEBAQAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAA
+AQAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAA/////wAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA0AAAAgAACADQAAgA0AAAAg
+AACADQAAAAYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAJgvAgAg
+IIAPAABAAGkgAABpIEAAaSAAAGkgQAAgIIAPAADoAGkgAABpIEAAaSAAAGkgQAAgIIAPAAAw5mkg
+AABpIEAAaSAAAEogAABKIQAASiIAAEojAABKJAAASiUAAEomAABKJwAASiAAEEohABBKIgAQSiMA
+EEokABBKJQAQSiYAEEonABBKIAAgSiEAIEoiACBKIwAgSiQAIEolACBKJgAgSicAIEogADBKIQAw
+CiSAP4EAAEBBLJwwQCycMEIkHDQKIoA/gAAgXwojADduCcAGSiYAcGkgQABKJgBwSiYAcEomAHBK
+JgBwABYAcIAA4CZAeCAgQIcAAAAAAAAAAAAA/ByItvwcSLb8HAi2/BzItfwciLX8HEi1/BwItfwc
+yLT8HIi0/BxItPwcCLT8HMiz/ByIs/wcSLPgfuB4BNw43TXw4HgE3DTdM/DgeATcMN0x8OB4BNws
+3S/w4HgE3CjdLfDgeATcJN0r8OB4BNwg3Snw4HgE3BzdJ/DgeATcGN0l8OB4BNwU3SPw4HgE3BDd
+IfDgeATcDN0f8OB4BNwI3Rzw4HgE3ATdGfA0FBowMBQZMCwUGDAoFBcwJBQWMCAUFTAcFBQwGBQT
+MBQUEjAQFBEwDBQQMALHAcawJE0zsCQfM+B+4HjgeOB44HjgeOB4CiSA8AUgRADgIMEHRCT+gEEq
+xACEAAIALyQC8UIhAQFCIAMB6CCiBAQRBAIEEQUCBBEGAgQRBwIEGwgBBBtIAQQbiAEEG8gBLAAl
+AEQiPoE8ACIARCL8gEAhwQDgIMEHQCPDAKgggAEBEYQCARsKASAgwAcEEQQCBBEFAgQbCAHUB+H/
+BBtIAUQi/IAEEQQCyQfv/wQbCAFCIUEAQiBDAKgggAEBEYQCARsKASAgwAfPcaAArC8YgZq4GKEd
+BaAQBdjgeM9xoACsLxiBs7i6uBihCQWgEGTYCiJAgADZ7gABAC8mAPBKJkAATgAGAE8AIACKJf8P
+4HgKIkCAANnOAAEAbAAkAC8mAPBcAAUAKwg1CEomQAAIcQDYAiG+gOAgxQdCeQHgAiG+gOAgxQdC
+eesH7/8B4C8tAQBAJUUAAiZ88QAAIAAAKEAB6CBiAy8gAIAvIUsAAiG+gMAghgHCIYYA4H4RACAA
+SiAAEEogQBAOIkIALyALEs4gRYCKJf8PCAAFAC8tAQBAJUUAAiZ88QAAIAAAKEABSiZAAOggIgMv
+IACALyFLAAIhvoDAIIYBwiGGAEomAABCIP6QziCCAUQgfpDOIYIB4H4JAAAA4HgKJgDwiiC/D8og
+ZADgfy8gAwDgf4og/w/8HIix/BxIsfwcCLHhw+HC4cHhwAfAHBzAMeHA4H8BwPHAFg3P/wh2WnIB
+iUCJELgYugd6AokIuEd4Q4kHegCG4oYHIIcARYkEiRC6GLhHeEaJCLpHeEeJB3oBhqOGByCIAAiJ
+SYkYuBC6B3oKiQi4B3oLiUd4TYkHfwyJELoYuEd4TokIui+JR3gneAd9SiNAIV7wQgygBQDZCHfq
+cDoMoAUB2Qd/6HAuDKAFAtkHfwlwJgygBQPZIIbneAchBwBBKwAGEgygBQDZCHMpcAoMoAUB2Qd7
+SXD+C6AFAtkHe2lw9gugBQPZIYZneAchCABBLgAm4gugBQDZCHMKcNoLoAUB2Qd7KnDOC6AFAtkH
+e4hwxgugBQPZ4oZneAd/QS0AFrYLoAUA2QhzinCqC6AFAdkHe8hwogugBQLZB3uqcJYLoAUD2aOG
+Z3gHfUEvAAaGC6AFANkIc0EtABQPeHoLoAUB2Qd7QS8AEg94agugBQLZB3svIAcCXgugBQPZJIZn
+eAchBQBBKAAWTgugBQDZCHNBLwAED3g+C6AFAdkHe0EtABIPeDILoAUC2Qd773gmC6AFA9lneGWG
+B3tBLwAWFgugBQDZmHBBKAAUD3gKC6AFAdkHJAQAQS8AAg94+gqgBQLZByQEAK947gqgBQPZJoYH
+IAABByEWAEEtABbaCqAFANkIdUEvABQPeMoKoAUB2Qd9QSgAEg94vgqgBQLZB30vIMcBsgqgBQPZ
+p3inhkIjU6BBLQkEQSsQBAd9IOZBLRcUQS4AIi8gxxBBLQoSLyOHFUEtAQIvJEcDQS4UJEErAgIv
+JUchLyfHJS8nBwAvIUcSLyKHEi8gByQvIUcgLyQHJS8mhwBBLQAGBPVKCqAFBNkEII8PAP8AAOpw
+OgqgBQTZ/9kQuSR4B3/ocCoKoAUE2f/ZCLkkeAd/CXAaCqAFBNkPeCCG53gneEEoAQYAGkIgQSgB
+BAEaQiBBKAECAxoCIAIaQiBBKwAG6gmgBQTZBCCDDwD/AAApcNoJoAUE2f/ZELkkeAd7SXDKCaAF
+BNn/2Qi5JHgHe2lwugmgBQTZD3ghhmd4J3hBKAEGBBpCIEEoAQQFGkIgQSgBAgcaAiAGGkIgQS4A
+Jo4JoAUE2QQggw8A/wAACnB+CaAFBNn/2RC5JHgHeypwbgmgBQTZ/9kIuSR4B3uIcF4JoAUE2Q94
+IoZneCd4QSgBBggaQiBBKAEECRpCIEEoAQILGgIgChpCIEEtABYuCaAFBNkEIIMPAP8AAIpwHgmg
+BQTZ/9kQuSR4B3vIcA4JoAUE2f/ZCLkkeAd7qnD+CKAFBNkPeCOGZ3gneEEoAQYMGkIgQSgBBA0a
+QiBBKAECDhpCIIEB7/8PGgIg4HjxwE4Jz/+eCSAACHUA2SjYFSVCEBUlAxDAg+CCwKLgo8GD4YLB
+ouGjwoPigsKi4qPDg+OCBOFkuMOi2QkigOOjCdsEhRDlOLjCCKAFBNkPeH4IoAUA2Qh2AIUwuA94
+rgigBQTZD3hqCKAFAdkHfgCFKLgPeJYIoAUE2Q94UgigBQLZB34AjYYIoAUE2Q94QgigBQPZx3gA
+pQGFOLhuCKAFBNkPeCoIoAUA2Qh2AYUwuA94WgigBQTZD3gWCKAFAdkHfgGFKLgPeEIIoAUE2Q94
+/g9gBQLZB34EjTIIoAUE2Q947g9gBQPZx3gBpQKFOLgaCKAFBNkPeNYPYAUA2Qh2AoUwuA94Bgig
+BQTZD3jCD2AFAdkHfgKFKLgPeO4PYAUE2Q94qg9gBQLZB34Ijd4PYAUE2Q94mg9gBQPZx3gCpQOF
+OLjGD2AFBNkPeIIPYAUA2Qh2A4UwuA94sg9gBQTZD3huD2AFAdkHfgOFKLgPeJoPYAUE2Q94Vg9g
+BQLZB34MjYoPYAUE2Q94Rg9gBQPZYbuA48d4rgbt/wOlGQDP//HArg+P/2GJQIkQuxi6Z3piiQi7
+Z3pjiQDfZ3pAoESJZYkYuhC7R3tGiQi6R3tHiWd6QaBIiWmJGLoQu0d7SokIukd7S4lnekKgbYlM
+iRC7GLpnem6JCLsviWd6Ct0nekOgw4AIc0EuABQPeP4OYAUE2SCDBCCADwD/AAAHIQQAQS4AEg94
+5g5gBQTZBCCAD/8AAAAHJAQAz3jSDmAFBNkEIIAPAAAA/wckBABBLgAWug5gBQTZD3jPcYAA2F7w
+IcEDByAAASd4IYMEoyd4IoMFoyd4I4MGo2G9J3gHo0AjAASDDXWQAectB4//4cUIdRHw4HjgeOB4
+4HjgeOB44HjgeOB44HjgeOB44HjgeOB44HhhvYwl/5/t9eB/wcXgePHA4cXPcIAAnChNgM91gAAw
+mSCFt7q4ugQhgQ8DAAAAB7lFeS2gtgpgEADYAIXPcYAADNRRIICCTInPcIEACBgyajZ5x3GBAMgU
+YIFWeEGABfKVu2Chq7oE8LW7YKGLukGgC42juKEGr/8LraLB8cAeDo//RcHPdYAAnCgnhRUIQQAw
+lRQUDjEJDkEQWR2CENAVARYdCEEAz3GAAKgrPJEUFA0xDQ1BEM9xgAAALFmpi+rPdYAAIArBjYDm
+ANnKIEEAJPIhrQsKkQMB2B7wQSgNAgd9QSgBBKd5z3eAACAKoI9TJUURHw0yBMa5CiHAD+tyz3AA
+AM0bn9vlBiABiiSDDw8NnhEA2Azc7wWP/892gQCIFxYmTRGnjaCvyXUWJU0RAKUUFAAxRq3HcYEA
+SBQCtQCJB60AGUIBABtCAcfx8cBKDY//CMjPcqAAyB8OGhiACcgPGhiACsgQGhiACxIBNgLIJHgR
+GhiADMjPcYAAsDstGhiAAIEB4AChw7hXCFEDC8h/2Qq5JHgvKAEATiCCBwDYDyCAAAQhAYBCIo0C
+GfILI0DAF/TPcKAAiCDwIFADz3aAAIw4AIbPd4AAkDgNDQEQAIcScLANAQagpgAfABQdBY//4HjP
+cYAAnF7gfwhh4HjxwBIKQAXPcYAAbCLwIQAAQHiA2c9woADQGzCg0cDgfoDhyiRNcOggbQLPcaAA
+UAwlgQEYUgDgfvHAbgyP/89wgACcKAOAGIilwUogACAdCBEBCiHAD+tyiiCMDWTbCiQABJkFIAG4
+c891gACcNs9wgACAQa4IoA4kHQAUz3CAAJxBogiADs9wgABEQpYIgA7PcIAAYEKOCIAOz3eAAGCg
+bY+A457yTI9QczgBDADPcIAAECcEgCCAz3CAAICWQKBhoCKgz3CBADAdCJApCwIAz3CBADAdz3GA
+AHjRaLAB3s9wgABg0cyhI4ANCeUAARgCBGOgEI+A4MogYgADpRGPE+iT6s9wgACcKAOACYAbCJ4A
+vghgAgfYAdgBpc9woAAsIBCAAKXPcIAAFDMAgB0IUQDPcIEAMB3PcQAAECcKDa//BYAQeAPwANjP
+cYAACNEHsQOFDBkEBGMIUQAAgYLgzCDigAP0AdgAoUwVgBBPCFEAz3CgACwg0IDPcAEAQBRAwAHY
+QcAIHAA0EdhDwADYjLhEwADYENkE2ghzmHC4cAAmhx8AAAB9OgugBNhwSxWAEAHgD3hLHQIQDI+F
+6AGFgOAMDMEEz3CAAPBBVg9ADgHZz3CAAFQfIKD2DyACBtgpA6//pcDgeKLB8cC+Cq//mHJFwUEo
+AQIHeUEoAgQnesa6z3WBAEgUSWVdZScJ3wEUFA4xz3OBAIgXaHI2euCCCwjBA+KSEw+AEyeKp2rv
+Cd6BANgn8MaKhu6A389wgAAgCuGoz3eAAPAoBY8LDgEQgNgFrwnwz3eAAAAsGY8LDgEQgNgZr8aK
+NnsAHIADB4qHuQCtz3CAACAKQIggqAHYR6sM3I8Cj/+hwfHAAxICN9dyAAAAQAHawiKKABe6x3IA
+DgAAg7rsc0Cj7HIAoooMIAQocNHA4H+hwOB4peAt8hH2YwiQCITgJfIH9i/oZwjRAOB/ANg3CFAB
+WwgRCOB/C9iMIEOHG/LM4BvyreAR8gf2NwiQCT8IEQrgfwrYMwgQDDMIUQ/gfwPY4H8B2OB/Atjg
+fwTY4H8F2OB/BtjgfwfY4H8I2OB/CdjgfwzY4H8N2A7Y4H7gePHA4cXPdYAANDGpcEAlgRvWCOAN
+LtoB2NEBr/9hHQIQ8cBKCY//Hwi0AAh1CiHAD+ty/diLuHPbSiQAAIUCIAG4c893gAA0MTeHACWQ
+H4AAiDEPDUEQDBCAIIDgjPJCDWAHBdg6cEQtvhsAJ0AeQJAhkADeCLpFec9ypAC4PZsaWAAikAwY
+giPKGlgAI5C3p8saWAAkkMQaWAAlkMYaWAAmkMcaWAAnkMIaWAAokMMaWAApkMUaWAAKkKMaGADP
+cIAAsC8ggGB5yXA3CBADz3CAALAvIIBgeclwJwgQBM9wgACwLyCAYHnJcBcIUATPcIAAsC8ggGB5
+yXAJCJEEAN3PcIAAnCgDgAiAz3GkALRFIQgeAEQtvhsAJ0AebJBLkHt7ZXpTGZiADZBUGRiABvBT
+GZiDVBmYg0Qtvhsndw6XVhkYgA+XWBkYgBCXVRkYgBGXVxkYgBKXWhkYgBOXXBkYgBSXWRkYgBWX
+WxkYgD4JYAcqcFUAj/+G4PHAANgP9M9wgAB8oGYL7/8G2c9xgADwowCBgrgAoQHY0cDgfuB48cCD
+4OHFANgY9M91gABgoEAlABU2C+//A9nPcIAAnCgDgBSQNY0TCQAAz3GAAIDTH4GNuB+hAdgRAI//
+8cCB4OHFANgJ9M9wgAB3oAHd/grv/6lxqXD1B0//4HjxwJbg4cUA2Iz3z3WAADCZqXDeCu//BNkL
+jYO4C60B2M0HT//xwJrg4cUA2Iz3z3WAADCZBG26Cu//BNkLjYK4C60B2KkHT//xwDIPT/+jwc92
+gACYtyaOQCYNEgK5NHmO4D1lANgl9Itwhgrv/wzZAhSAMJzoENnPcIAAXAogsASOJG0ArSDAAa0D
+FIAwAq2BwA4PoA0C2kaOAeJPeieORiLAAMG6Rq4leAeuAdg5B2//o8DxwKTBkOAA2cogQgAT9Itw
+Kgrv/xDZABQAMYTgzCBigQj0z3CAAIDTH4AJCF4FTHAB2KTA0cDgfoHgANnKIEIAFPTPcKAAUAwl
+gM9zgACggwGTL3kTCQAAz3KAAFwKAJIhs4G4ALIB2OB+4HjxwE4OT/+G4ADYKfTPcIAAECcEgM93
+gACYt1YnERIAgFIXDREPp4PlyiUmEL5l1H4AIZAjCnCaCe//BtkidgGWCugAEIAgCOjPcYAAXAoA
+kYa4ALFSH0QTAdhVBk//4HiA4ADYCPTPcYAAXAoAkYK4ALEB2OB+4HjxwNoNT/8Id89wgACcKAOA
+GIgacY0IEAGE5wDdhgAlAMogRQPPdoAAYKBAJgATKgnv/wTZLo6wrlMhAAARrkEowCCguV0IZAAC
+IEIAY79VCsUDD+rPcaAA0A8QEQCGYbpYYBAZGIAlEQCGD3gC8A+OANlTIIIgDyGBACR4LyYH8M9x
+nwC4/xCuGIHPIOIH0CDhBxihGIGeuBihGIG+uBihAdidBU//4HjhxPwcyL78HEi+4cDhweHC4cP8
+HAix/BxIsfwciLH8HMix/BwIsvwcSLL8HIiy/BzIsvwcCL9qJIAQ4cRqJMAQ4cTxwM9woADQGxSA
+z3GAABAJBCCAj89RBOEAoRHyLykBAA8IngUvKYEPQAAAAM9wgAAUL/AgQABAeHIPj//RwMHEayTA
+EMHEaySAEMHEn3QEFAs0BBQKNAQUCTQEFAg0BBQHNAQUBjQEFAU0BBQENMHDwcLBwcHAwcRFLH4Q
+CiZAfsHEaySAFMHEICBAh+B4jCBcggHY4H/CIAsA8cBeDG//SiRAAM91gACcKBUlAxAAg0AlDhXR
+cMIkAgHwJQ0RyBUFFkQlvoEJ8gohwA/rco7YjbhxBeAAdNvIEA0GpXnIGFgAoIMG2UZ5yBUAFiR4
+yB0YEACDyBAABoYgf45IDgEQZQRP/+B48cDuC2//gNoIdyh2BIFAJg0WI7hTIEEBOGUBGJIATiHC
+Dx0KNQIA2Z4NAAHJcGoIIACpcalwANk42gPwaLqKDQABBIYUpgWGFabJcEoIIACpcclw6XEOC6AN
+ENrJcADZZg0gAQTa8QNP/+B4z3FFZwEjIKDPcc3viashoM9xupj+3CKgz3EyEHZUI6AA2SSg4H8l
+oPHAWgtv/5hwYIAMEAYAQoChgOKBByaAAKR4ByCOAQCBx3cgJNtwAiCAD5UoiFvYYBtjF2s5u2V4
+ByJDA7hgBHsHI44AYYECI4MPOBeqSH5mwHZALgMTNL7FewclDhAbY2R+p37+ZtpiQCpOBOOBL7rF
+egcjDgB6YkR+B34CJ48fQj4SMf5m3WVALY4VKr3kgcV9ByOOAF1lpH5nfgInjx+DClHw/mbYYNdo
+5YE5uMV4ByJOA7hgBH5Hfsd3h0cqxv5m22NAKw4D5oE0u8V7ByUOEBtjZH6nfgInjx/PV+25/mba
+YkAqTgTngS+6xXoHIw4AemJEfgd+AiePH7kC/2r+Zt1lQC2OFSq96IHFfQcjjgBdZaR+Z37Hd4Bp
+2Jj+Zthg12jpgTm4xXgHIk4DuGAEfkd+AiePH7t0UQj+ZttjQCsOAzS76oHFewclDhAbY2R+p34C
+J48fAABPpP5m2mJAKk4EL7rrgcV6ByMOAHpiRH4HfgInjx+jdkIo/mbdZUAtjhUqveyBpX4HI40A
+XmbEfWd9x3eQayIR/WW4YLdoObjtgaV4ByKNA9hgBH1HfQInjx9nAm2O/WW7Y0ArDQM0u+6BpXsH
+Jg0QG2Nkfcd9AiePH4ZZcrz9ZbpiQCpNBC+6RX19ZQcjAgCkejwRBQAHIg8AACWCD7RJIQj6Ytpi
+QCqOBSq6xXrhgbpiByWOEGR+p34CJ48f4Qme2v5m2GDVaDu4BX7mgV5mByKAA6R4R3gCJ48fvz/A
+TPhgeGBAKEMCN7gFe+uB22MHI4ADRHjHeMd3XiZRWvhguGBAKI0DMrgFfeCBfWUHI0ADxHhneAIn
+jx9JFlY4+GBYYEAoAgUsuEV45YG4YAclAhBkeqd6AiePH9Apo+/6Ytpi1Wo7usV66oEaYgcgjgCk
+fgd+x3dEAlMU/mbbY0ArTgI3u2V+XmYHJoMQBHsHI48AAiWDD14nfxn7Y31lQC2DEzK9ZX3kgd1l
+ByZDE0R7x3sCJ48fLBg4BPtjeGBAKAMFLLgFe+mBu2MHJcAQxHineMd34SHmzfhgWGBVaDu4BXp6
+YgcjgACkeDgRBwAHIM8AAieAD8g8Kvj4YNhgQChOAje4xXjjgVhgByCOAGR+R34CJ48fKgt58v5m
+3WVALY4T6IEyvaV+HmYHII0DRH0Hfcd3WkXtFP1lu2NAKw0FLLtlfe2B3WUHJkMTBHvHewInjx8c
+VvsW+2N6YnVq4oE7umV6umIHJYMQxHunewInjx8QAwhc+2N4YEAoQwI3uAV754FbYwcjgACkeEd4
+x3dvZ9kC+GDYYEAojgMyuAV+7IF+ZgcjgANEeGd4AiePH9VydrP4YLhgQCgNBSy45YGleNhgByYN
+EGd9AiePHwUAvsb9ZbpitGrogTy6pXoaYgcgjQDHfQInjx+OeH8J/WW7Y0ArzQLrgTW7ZX1dZQcl
+gxAHe8d3nW0iYftj22NAKw4EMLvFe7tjByXPEEd/AieODxoC9Mf+ZthgQCjOBSm44YHFeHhgByMO
+AKd+AiePH0FbvBXfZ/pi1GrkgTy6RX4eZgcgggNnesd33kupz/piumJAKs0C54E1ukV93WUHJYIT
+B3oCJ48fRAmgtF9n+2NAKwIE6oEwu0V7u2MHJcIQx3oCJ48fQEGQQ19n+GBAKMIFKbjtgQV6emIH
+I4AAp3jHd5soxn74YNhg1Gg8uOCBBX5eZgcigANneAInjx9eFQbY+GC4YEAozQI1uOOBBX3dZQcl
+gBNHeAInjx8QK3vP+GB4YEAoAwTmgTC4ZXi4YAclAxDHe8d3iAQFHftjemJAKsMF6YEpukV7G2MH
+IMIAp3oCJ48fKybHL/pi2mLUauyBPLrFenpiByOOAAd+AiePHyQZG2b+Zt1lQC3OEjW9xX1dZQcl
+jxBnfwAljg+iH/h8/mbYYEAoDgQwuOKBBX6+ZgclgBNHeAInjx9TO5up+GB4YEAowwXggSm4ZXiy
+e9hgBXvHewInjx/WC7zd+2N6YnZq54E6ukV7G2PSemV6B3rHdypDl//6YrpiQCqNAu6BNrpFfRJ6
+fWWlemd6AiePH2tUWdz6YtpiQCrOA+WBMbrFenJ+umJFfqd+AiePH2wDx1/+ZthgQChOBSu47IHF
+eFhgsn4Ffkd+x3dbZcNZ/mbbY9ZrOrvjgWV+UnseZsV7B3sCJ48f83BuM/tju2NAK40C6oE2u2V9
+EnvdZaV7x3sCJ48fEACDC/tjemJAKsMD4YExumV60nu6YkV7p3sCJ48fe3ovon9n+GBAKEMFK7jo
+gQV7snhbY2V4R3jHd6hvT374YNhg1mg6uAV+Unh+ZsV4Z3gCJY8P0wEgGR9n/WVALYAS5oE2vaV4
+2GByfQV9x30CJ48f/lzsvL9n+mJAKs0D7YExuqV60n0aYkV9B33HdwhOoRG/Z/tj5IFAK00FK7tl
+fRJ7XWWle0d7AiePH6wIfoH7Y35m64F2bjq+xXtSfrtjZX6nfgInjx/FQssN32f4YEAojgI2uOKB
+BX6yeCmBfmbFeGd4x3fXKrvSH2f6YkAqwAMxugV6cnjaYkV4AiGBD3kUbyzHeBlhuWFAKUAFK7kF
+eQAUDQBZYbtjABzAAAQUAwB5YQQcQAAIFAEAWWEIHEAAACaBAw0EL/8MHEAA4HjxwJILD/8Idkh1
+RIAodxYiQQMkoAsJpQAFgAHgBaZBLUEXOGBBKsEAUyFBgQWmQCYQFh/yQNwOIRED6XA9DWQUAnHO
+CmANKnLJcPoPr/8KcSJ3AiVNFA3wtgpgDUDayXDiD6//QCYBFkDngiUBEMDl6XBAJgEWcveWCmAN
+qXJ1Aw//4HjxwM9wgAAELwCAG+jPcIAAlC8AgJnoTgkADYnoC8gFIIAPAAAAPAsaGDA+CQANiegL
+yAUggA8AAADUCxoYMAvIkLgLGhgwvguABdHA4H7gePHAxgov/2d6z3WAAGAKoIUVJU0RwIVEeWd5
+QyjABkMuDxIEJ48fAP8A/0MuDhYEJo4f/wD/AOV+wKXZYcdxglqZee0CL/84YPHAfgov/5hwQCVN
+A892gABgCsCGw73wJk8TQCUNAsO98CZNE+d9QCWPAMO/8CbPE1MlwAAVfgCG531nekR5p3hDKMAH
+AKZneRlhx3GCWpl5QyzABpECL/84YOB48cAiCi//mHBAJU0Dz3aAAGAKwIbDvUAlDwLDv/AmzxPw
+Jk0T531AJY8Aw7/wJs8TUyXAABV+AIbnfUd5Z3kHfUMtwBcAphlhx3HZbqHrQyzABjkCL/84YPHA
+ygkv/5hwQCVNA892gABgCsCGw71AJQ8Cw7/wJk0T8CbPE1MlwACnf0AljQDDvfAmTRMVfgCG532n
+eAUiTQBEeaR7QyjAB2V5GWEApgIhgQ/kcCRDQyzABtkBL/84YPHAagkv/5hwQCVNA892gABgCsCG
+w71AJQ8Cw7/wJs8T8CZNE+d9QCWPAMO/8CbPE1MlwAAVfgCG531HeWd5B31DLcAXAKYZYQIhgQ+d
+NSo+QyzABn0BL/84YOB44cUB289ygACMCH6y4HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB4
+4HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeAa4RSDNAM9woADsJ6agCoAA2wCxfrLg
+f8HF4HjxwJILgAKGDoAPOgyAD4DZz3CgANAbMKDRwOB+8cB+CA//GnAB3wAQEgET8Fp1EfAVIMAj
+oJACEBEBAefXdQAA+//wf3T2GQqALwAA///PcAAA+//dCIGEnQAP/892gAAIJwCGAeAAphUIUQAB
+2c9woADIHDGgzg6gDyhwBr2BvUApACSleM9xoADsJwahAIZCIECAAKbd9c9xoADIHADYEaHX8fHA
+z3CAAPAvAICB4Mohwg/KIsIHyiCCDwAArxPKI4IPAADzAcokIgAoAaIAyiUCARoIAADRwOB+8cBm
+DQAP8grADNHA4H7gePHAng/P/s9wgACcKAOAz3MPAAD8KIDPcIAA3LrAuTZ4RIAggAq6ZHrJuSV6
+z3GnABRITaFFgAGACrrJuGR6RXgOoc9xgABw8A6JhiD/AVtoz3CAAHSTTKhPiTCJQCATA4Yi/wFD
+uoYh/wFNqEO5lg2gBi6o2nDPcIAACCcAgAHgz3GAAAgnAKEVCFEAAdnPcKAAyBwxoMINoA8ocM9x
+CACHEM9woADsJyagA9gA2TIjVSA6cY0NMyJacEokACAa8EAlgQEweQa5gbkQvyV/z3GgAOwn5qFA
+JoEBMHkGuYG5ELgleM9xoADsJwahQCRUIM9wgAC4LyCAYHkG2O8MBSDtDQ6lqnCuDaAEinEacKpw
+2gugBIpxmHBAKEAhEHgQuIG4h7iMuM9xoADsJwahTQwQIC0MUSCKJcQGiiaECCLwCiHAD+tyz3AA
+ALATiiPFDQokQAW1B2AASiUAAAohwA/rcs9wAACuKIojRgZKJAAAmQdgAAolAAWKJYINiiZCDwDf
+BNufc+lwqCAADGG7QC6CIUAsAQFZYXV5ACNNAcdxgAAYu0KRsH0GvYG9XHoQukV9z3KgAOwnpqJC
+kcC6eHrlelB/Q5EAI40BsH0GvVx6gb0QuqV6z3agAOwnRqYjkcC5eHkleBB4bPFCIkAggOC+Bu3/
+QCFBIM9xCACGEM9woADsJyagz3CAAAgnAIDPcYAACCdCIECAAKEH9M9xoADIHADYEaHFBc/+4Hjx
+wADYjbiqCOALBhoYMAzMhiD/igjyz3CAAIQ4AIiA4HgPwgPRwOB+8cDPcQMAQA3PcKAAqCAtoM9x
+oACsLxmB8LgZgQvyBCCADwgAAADXcAgAAAAB2MB4BvCGIH8PguAB2MB4z3KAAMwKIIJhaYzoz3CA
+ABQJAYiG6GCiEgvgBUjYA/Bgos9ygACIPwaCA4AggMdxAACIE94J4A1IcNHA4H7gePHA3gzP/s9x
+gAAsSCGBo8FCwc9xgACcKBUhEAAAEAAgwBAOBi8ogQNOII0Hrw4QEBJtFngAIJIPgQDIFAYSgCDP
+cYEAiBcWeQCBIpGO5QgcRDDKIGEABvKLctIJb/8CwTboANjPcYAA7AlAgQ8gQAMvIQogBCGAoACh
+B/SA4tAKIgfKICIIr3jqDuADENkA3wQaxCOKIQgAABpAIKlw6XG2DSAGD9oAEAIgwBIABgQgQATA
+GhgAz3CBAAgYtnjgoOGgz3CBACgUtHjgsBAmTpMvKIEDTiCNB6z1YQTv/qPA8cDhxQh1BPB6CMAN
+2gjgDalw/OhtBM/+o8FAwEHBBRSBMADYgeFCwg3yguEH8oPhDfQhwQDYDyBAAAMUgTAPIEAAAhSB
+MA8gQAAGFIEwIQlQABMJkAAjCdEAIcED4Q8gQAADFIEwA+EPIEAAAhSBMAPhDyBAAAkUgTAhCVEA
+AhSBMAq5TyECBAMUgTAMuSV6IcEOuUV5JXggwRUJUQAHFIEwIsIGuQi6RXkleOB/o8CjweHFQsEJ
+FIEwQ8JBwBkJMwEA2BEJUgAKFIEwCQlSAAcJEgEB2AcUgjAGFIMwEQuAACLBMHPMIkKAA/QB2CHF
+IQ1REAoUgTAjwxkJwwALFIIwUHHMI6qAhPaA4sogaQAbCFEAiiHJD89wgACcCSCggeX/2cohIgAh
+oMHF4H+jwPHAzgrP/r7BOnFacoh2CiBAIeh1l8fpcF4JoADQ2QPYYcAFHII0CwoRIAndPvAlClAg
+UwqQIAohwA/rcs9wAACxDcvbCiSABOEDYABKJQAAlBQAMQYcgjNAKIEhCxxCMwccAjBIuGLAQCmA
+IIG4JXgQeQkcAjBIuQocQjBIvWPF1fGcFIAwQCkBIwu4BXkweEi4BxwCMJgUADEGHEIwBt1iwEi4
+CRwCMHYUgTCIxslwuWEweWYJoAAA2kTHRcaBwEbAHBxEM14LoACEwF0C7/6+wOB48cDhxaPBAN1A
+xUHCQsMC2qlzmHW4ddh1Fg/v//h1YQLv/qPA8cDiCe/+QCEDBaLBCHcodUokAHIA2agggASE4W8g
+CwDwIwIAUyFOAE4mwBADuBl6ACRAMECoAeHPdoAAfEapcMlxBPCpcCJubglgAAHaBYWGIPgBjCAH
+gPb1i3apcMlxVglgAAjaSiQAdQDYqCDAA0EogQDwJUEQUyBDAE4jwgADull5HGcgrAHgqXAA2S4L
+oAAE2slwANkiC6AACNqtAe/+osDPcUVnASMgoM9xze+JqyGgz3G6mP7cIqDPcTIQdlQjoM9x0sPw
+4SSgANkmoOB/JaDxwA4J7/4ZcM9wgABgCiCgABAOEAQQDxAIEAcQDBAGEMlwEBAEEOlx6HLIcx4O
+r/9KJQAAACANAUMviRCpcMlxKXLocwokgAECDq//SiVAAMBw2HBDLooQqXFJcilzCiTAAeoNr/9K
+JYAAACDOAUMthxDJcMhx6HJJcwokQALODa//SiXAAAAgTwJDLokA6XDJcSly6HMKJIACsg2v/0ol
+AAFBcNhwQy6KEOlxSXIpcwokwAGWDa//SiVAAQAgzQFDL4cQqXDIcehySXMKJEACeg2v/0olgAEA
+IE4CQy6JAMlwqXEpcuhzCiSAAl4Nr/9KJcABQXDYcEMtihDJcUlyKXMKJMABRg2v/0olAAIAIM8B
+Qy6HEOlwyHHocklzCiRAAioNr/9KJUACACBNAkMuiQCpcOlxKXLocwokgAIODa//SiWAAkFw2HBD
+L4oQqXFJcilzCiTAAfIMr/9KJcACACDOAUMthxDJcMhx6HJJcwokQALWDK//SiUAAwAgTQJDLokA
+qXDJcSly6HMKJIACugyv/0olQANBcNhwQy6KEKlxSXIpcwokwAGiDK//SiWAAwAgzwFDLYcQ6XDI
+cehySXMKJEAChgyv/0olwAMAIE0CQy6JAKlw6XEpcuhzCiSAArIMr/9KJQAEQXDYcEMvihCpcUly
+KXMKJMABlgyv/0olQAQAIM4BQy2HEMlwyHHocklzCiRAAnoMr/9KJYAEACBNAkMuiQCpcMlxKXLo
+cwokgAJeDK//SiXABEFw2HBDLooQqXFJcilzCiTAAaIMr/9KJQAFACDPAUMthxDpcMhx6HJJcwok
+QAKGDK//SiVABQAgTQJDLokAqXDpcSly6HMKJIACagyv/0olgAVBcNhwQy+KEKlxSXIpcwokwAFO
+DK//SiXABQAgzgFDLYcQyXDIcehySXMKJEACMgyv/0olAAYAIE0CQy6JAKlwyXEpcuhzCiSAAhYM
+r/9KJUAGQXDYcEMuihCpcUlyKXMKJMAB/guv/0olgAYAIM8BQy2HEOlwyHHocklzCiRAAuILr/9K
+JcAGACBNAkMuiQCpcOlxKXLocwokgALGC6//SiUAB0Fw2HBDL4oQqXFJcilzCiTAAaoLr/9KJUAH
+ACDOAUMthxDJcMhx6HJJcwokQAKOC6//SiWABwAgTQJDLokAqXDJcSly6HMKJIACcguv/0olwAdB
+cNhwQy6KEKlxSXIpcwokwAFaC6//SiUACAAgzwFDLYcQ6XDIcehySXMKJEACPguv/0olQAgAIE0C
+Qy6JAKlw6XEpcuhzCiSAAiILr/9KJYAIQXDYcEMvihCpcUlyKXMKJMABBguv/0olwAgAIM4BQy2H
+EMlwyHHocklzCiRAAuoKr/9KJQAJACBNAkMuiQCpcMlxKXLocwokgALOCq//SiVACUFw2HBDLooQ
+qXFJcilzCiTAAbYKr/9KJYAJACDPAUMthxDpcMhx6HJJcwokQAKaCq//SiXACQAgTQJDLokAqXDp
+cSly6HMKJIAC1gqv/0olAApBcNhwQy+KEKlxSXIpcwokwAG6Cq//SiVACgAgzgFDLYcQyXDIcehy
+SXMKJEACngqv/0olgAoAIE0CQy6JAKlwyXEpcuhzCiSAAoIKr/9KJcAKQXDYcEMuihCpcUlyKXMK
+JMABagqv/0olAAsAIM8BQy2HEOlwyHHocklzCiRAAk4Kr/9KJUALACBNAkMuiQCpcOlxKXLocwok
+gAIyCq//SiWAC0Fw2HBDL4oQqXFJcilzCiTAARYKr/9KJcALACDOAUMthxDJcMhx6HJJcwokQAL6
+Ca//SiUADAAgTQJDLokAqXDJcSly6HMKJIAC3gmv/0olQAxBcNhwQy6KEKlxSXIpcwokwAHGCa//
+SiWADAAgzwFDLYcQ6XDIcehySXMKJEACqgmv/0olwAwAIE0CQy6JAKlw6XEpcuhzCiSAAo4Jr/9K
+JQANQXDYcEMvihCpcUlyKXMKJMABcgmv/0olQA0AIM4BQy2HEMlwyHHocklzCiRAAlYJr/9KJYAN
+ACBNAkMuiQCpcMlxKXLocwokgAI6Ca//SiXADUFw2HBDLooQqXFJcilzCiTAASIJr/9KJQAOACDP
+AUMthxDpcMhx6HJJcwokQAIGCa//SiVADgAgTQJDLokAqXDpcSly6HMKJIAC6giv/0olgA5BcNhw
+Qy+KEKlxSXIpcwokwAHOCK//SiXADgAgzgFDLYcQyXDIcehySXMKJEACEgmv/0olAA8AIE0CQy6J
+AKlwyXEpcuhzCiSAAvYIr/9KJUAPQXDYcEMuihCpcUlyKXMKJMAB3giv/0olgA8AIM8BQy2HEOlw
+yHHocklzCiRAAsIIr/9KJcAPACBNAkMuiQCpcOlxKXLocwokgAKmCK//iiUBAEFw2HBDL4oQqXFJ
+cilzCiTAAYoIr/+KJUEAACDOAUMthxDJcMhx6HJJcwokQAJuCK//iiWBAAAgTQJDLokAqXDJcSly
+6HMKJIACUgiv/4olwQBBcNhwQy6KEKlxSXIpcwokwAE6CK//iiUBAQAgzwFDLYcQ6XDIcehySXMK
+JEACHgiv/4olQQEAIE0CQy6JAKlw6XEpcuhzCiSAAgIIr/+KJYEBQXDYcEMvihCpcUlyKXMKJMAB
+5g9v/4olwQEAIM4BQy2HEMlwyHHocklzCiRAAsoPb/+KJQECACBNAkMuiQCpcMlxKXLocwokgAKu
+D2//iiVBAkFw2HBDLooQqXFJcilzCiTAAZYPb/+KJYECACDPAUMtixDpcMhxaXJJcwokQAJ6D2//
+iiXBAgAgTQJDLoYAqXDpcchyaXMKJIACXg9v/4olAQNBcPhwQy+JEKlxKXLIcwokwAJCD2//iiVB
+AwAgzgJDLY0QyXDocalyKXMKJIABJg9v/4olgQMAJgYAQy+PAMhwyXHpcqlzCiRAAgoPb/+KJcED
+ABABECFwQy6CEBlhBBAAEMBwBBgAEAgQABBYYAgYABAMEAAQABhAEB9nEBAAEAwYwBMdZZ0Ar/4Q
+GEAT8cAmCI/+CHY6cSWASHdzb0EpwgD2ecW6JaANCeUABoAB4AamQS9BFzhgBqb4Yr/gPAAOAEAm
+EBdA3A4iDQMqcAAggSBeD6AMqXLJcNYOr/8KcQjwyXDODq//ACVBFEDlQCXAH/EIxIMA2gPwAN1A
+JgEXACVAFFlhKg+gDAInQhMFAI/+8cCqD0/+z3WAAKQKABUFEDMNVQLPdoAA7EPPd4AAyFoD8AAV
+BRABhUAtAQIleCCGBwhAAACm8CdAEUB4c+jVB0/+CiHAD+tyz3AAAIYnY9upACAASiSAAKLB4cVC
+wUEoAgIHekEoAQRHec9ygQBIFMa5KmIlCt8BCBQDMc91gQCIF6lxVnlAgQsIgQBCkREKwABHie8K
+3oGA2APwBonBxeB/osDgfuB44H7geAjIlbgIGhgwCcibuAkaGDALyIq4jbiQuAsaGDDgfuB48cDh
+xQh1PojPcIAAKB5AgEAlABQDuTV5WWHuDqAMCtq+D+//qXAxB0/+4HjxwKXBQcBCwQwcADEQHEAx
+z3GAALCRNBnADzAZAA8sGcAOKBmADiQZQA7PcIAAsJEgGEALz3CAALCRHBgAC89wgACwkRgYwArP
+cIAAsJEUGIAKz3CAALCREBjACM9wgACwkQwYgAjPcIAAsJEIGEAIz3GAADSRgBkACHwZwAd4GYAH
+dBlAB3AZAAdsGQAHaBmABmQZQAZgGQAGXBnABVgZgAVUGUAFUBkABUwZwARIGYAERBlABEAZAATv
+oc6hraGMoSwZwAIoGYACJBlAAiAZAAIcGcABGBmAARQZQAEQGQABY6FqIAAD2BkAAGogwALUGQAA
+aiCAAtAZAABqIEAByBkAAGogAAHEGQAAaiDAAMAZAABqIIAAvBkAAGogQAC4GQAAaiAAALQZAABq
+IIABzBkAAEDDAcACwVMnzTUMFAYwUyXENVMmxTXXuqlz/gkgBRAUBzCmCGAMANguCAADz3AAAK3e
+Mg+AAMIL4A0A2M91oACsLxmFibgZpc9wgAAcCQCAgODKICECyiEhACQLYQXPIWEGz3CAACAJAYAp
+CF4AQNnPcIAAcIQmsDC5J7AZhfC4GYUF8o64GaUH8Iq4GaUF8D4IoAYA2DkEwAzgeADbYKghqEKo
+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
+EQoAAChwAiWBHwAAAAwF8ChwQiWBFx4PgADPcIAAYELb8cYJT/jPcYAADEIR6M9wgADkK0yQz3CA
+AJwoHpATCgAAKHACJYEfAAAADATwKHBCJQEV3g6AAM9wgAAoQgAlgR8AAIgTzg6AAApwybjPcYAA
+gJYDoQaGgbgxAu/xBqbxwOHFz3WAALhBOg6gAKlwz3CAAHg2IIDPcIAAfDYAgAkhAQDPcIAACNEI
+gAkhAgDPcKAALCAwgKlweg6gAFlhAQLP8fHAz3CAAICWAYAPCFEAz3CAACw2B4DPcYAADEIggUIh
+AYDKIWIAkOnPcYAAeNEsgYrpz3GAAGDR6g9v9yOBCg7v/wLZ0cDgfvHAQgnP8c9wgAAQJwSAoIDP
+cIAAgEEAgEIgAIDKIGIANr2H6M9wgACcQY4NgADPcIAAYNEhiM9wgADUQc92gACAlorpIIBCIQGA
+yiFiAATpIIat6WINgADPcIAA8EFaDYAAAYZ2D2/3CHEhhg94HQkFAAohwA/rcoogDQPX20okAAAN
+Am/zuHPPcYAADEIggUIhAYDKIWIABukdZSOGyb0LDUAQWg3v/wDZBQHP8eB44cXhxqsKEABAIsMD
+JLvDugLwANqVChUEMyaCcIAAtEZAJ41yVH0gfcCIARmSAwHgARCCBAEZkgABEIIEARmSAAEQggQB
+GZIAARCCBAEZkgABEIIEARmSAAEQggQBGZIAARCCBAEZkgABEIIEARmSAAEQggQBGZIAARCCBAEZ
+kgABEIIEARmSAAEQggQBGZIAARCCBAEZkgABEIIEARmSAAEQggQBGZIAQiNDgLP1wcbgf8HF4cXh
+xiPqY2oiu8G6AvAA2jUKFQEzJoJwgACgRkAnjXJUfSB9wIAEGZADBOAEEAIEBBmQAAQQAgQEGZAA
+BBACBAQZkABCI0OA4/XBxuB/wcXhxeHGqwoQAEAiwwMku8O6AvAA2pUKFQQzJoJwgACkRkAnjXJU
+fSB9wJACGZQDAuACEAIFAhmUAAIQAgUCGZQAAhACBQIZlAACEAIFAhmUAAIQAgUCGZQAAhACBQIZ
+lAACEAIFAhmUAAIQAgUCGZQAAhACBQIZlAACEAIFAhmUAAIQAgUCGZQAAhACBQIZlAACEAIFAhmU
+AAIQAgUCGZQAAhACBQIZlABCI0OAs/XBxuB/wcXxwNoOr/FTIUIATiINAc9yoAAUBMmCANsOJoIf
+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
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQ0R
+FAoNExcZGRkZCQkAADyggAAAAAAAPKCAAAAAAABY1YAAvHEAADCAAAAAAAAAMYAAAIiIMzMygAAA
+AKqqijOAAAAAAAAANIAAAAAAAAA1gAAAAAAAADaAAAAAAAAAN4AAAAAAAAA4gAAAAAAAADmAAAAA
+AAAAOoAAAAAAAAA7gAAAAAAAADyAAAAAAAAAPYAAAKqqCgA+gAAAU4WIiD+AAAAAAAAwMIAAAAAA
+AAAxgAAAmplYVTKAAAAAqqqqM4AAAAAAAAA0gAAAAAAAADWAAAAAAAAANoAAAAAAAAA3gAAAAAAA
+ADiAAAAAAAAAOYAAAAAAAAA6gAAAAAAAADuAAAAAAAAAPIAAAAAAAAA9gAAAqqoKAD6AAABVmJmq
+P4AAAAAAAFAwgAAAAAAAADGAAAAAAAAAMoAAAAAAAAAzgAAAAAAAADSAAAAAAAAANYAAAAAAAAA2
+gAAAAAAAADeAAAAAAAAAOIAAAAAAAAA5gAAAAAAAADqAAAAAAAAAO4AAAAAAAAA8gAAAAAAAAD2A
+AAAAAAAAPoAAAAAAAAA/gAAAAAAAADCAAAAAAAAAMYAAAAAAAAAygAAAAAAAADOAAAAAAAAANIAA
+AJp5AAA1gAAAqqqqqjaAAAAAAAAAN4AAAAAAAAA4gAAAAAAAADmAAAAAAAAAOoAAAKqqqgo7gAAA
+AHCZqjyAAAAAAAAAPYAAAAAAAAA+gAAAAAAAAD+AAAAAAAAA//8AAKUBAQC5Ad8AOwItALEAGwAW
+ARsArwAbABQBGwBsAKAA0QCgAG8AgwBxAIMAcwAzANQBBgDQAQAAeABJAHkAagDeAGoAqAAAAA0B
+AACmAD8ApwABAAsBPwAMAQEABAAIAJwBzACdAcwA1QHMANYBzAC0ACAAGQEgAI8AiAD0AIgAkAAi
+APUAIgCRAAQA9gAEAIUAAACGAAAAhwBVAIgAAACJAKoAigAAAIsA3QCMAAAAhQABAIYAAQCHAFUA
+iAAAAIkAqgCKAAAAiwDdAIwAAACFAAIAhgADAIcAVQCIAAAAiQCqAIoAAACLAN0AjAAAAIUAAwCG
+AAcAhwBVAIgAAACJAKoAigAAAIsA3QCMAAAA+/8AAP//AAC5Ad8AOwItALEAGwAWARsArwAbABQB
+GwBsAKAA0QCgAG8AgwBxAIMAcwAzANQBBgDQAQAAeABJAHkAagDeAGoAqAAAAA0BAACmAD8ApwAB
+AAsBPwAMAQEABAAIAJwBzACdAcwA1QHMANYBzAC0ACAAGQEgAI8AiAD0AIgAkAAiAPUAIgCRAAQA
+9gAEAKgADAANAQwAhQAAAIYAAACHAJkAiAAAAIkAqgCKAAAAiwDdAIwAAACFAAEAhgABAIcAmQCI
+AAAAiQCqAIoAAACLAN0AjAAAAIUAAgCGAAMAhwCZAIgAAACJAKoAigAAAIsA3QCMAAAAhQADAIYA
+BwCHAJkAiAAAAIkAqgCKAAAAiwDdAIwAAAD7/wAA//8AALkB3wCxABsAFgEbAK8AGwAUARsAbACg
+ANEAoABvAIMAcQCDAHYAgwBzADMAbgAzAHAAMwByADMA1wAzANQBBgDQAQAAfgA8AOMAPAB4AEkA
+3QBJAH8AWgDkAFoAqgA/AKsAAQAPAT8AEAEBAHkAagDeAGoAqAAAAA0BAACmADcApwABAAsBNwAM
+AQEABAAIAJwBzACdAcwA1QHMANYBzAC0ACAAGQEgADECDAAyAgwAMwK9ADYCDAA3AgwAOAK9AKAA
+iAAFAYgAoQDVAAYB1QCiAAQABwEEAI8AiAD0AIgAkAAiAPUAIgCRAAQA9gAEAJ8ADAD7AAwAlAAA
+AJUAAACcAJcAnQDQAJoAjQCYABEAlgAzAJcAdwCUAAEAlQABAJwAlwCdANAAmgCNAJgAEQCWADMA
+lwB3AJQAAgCVAAMAnACXAJ0A0ACaAI0AmAARAJYAMwCXAHcAlAADAJUABwCcAJcAnQDQAJoAjQCY
+ABEAlgAzAJcAdwD6AAAA+QAAAAIBlwADAdAAAAGNAP4AEQD8ADMA/QB3APoAAQD5AAEAAgGXAAMB
+0AAAAY0A/gARAPwAMwD9AHcA+gACAPkAAwACAZcAAwHQAAABjQD+ABEA/AAzAP0AdwD6AAMA+QAH
+AAIBlwADAdAAAAGNAP4AEQD8ADMA/QB3AIUAAACGAAAAhwBVAIgAAACJAKcAigAAAIsA3gCMAAAA
+hQABAIYAAQCHAFUAiAAAAIkApwCKAAAAiwDeAIwAAACFAAIAhgADAIcAVQCIAAAAiQCnAIoAAACL
+AN4AjAAAAIUAAwCGAAcAhwBVAIgAAACJAKcAigAAAIsA3gCMAAAA6wAAAOoAAADsAFUA7QAAAO4A
+pwDvAAAA8ADeAPEAAADrAAEA6gABAOwAVQDtAAAA7gCnAO8AAADwAN4A8QAAAOsAAgDqAAMA7ABV
+AO0AAADuAKcA7wAAAPAA3gDxAAAA6wADAOoABwDsAFUA7QAAAO4ApwDvAAAA8ADeAPEAAACkAYAA
+oQFAAPv/AAD//wAApQEBALkB3wCxABsAFgEbAK8AGwAUARsAbACgANEAoABvAIMAcQCDAHYAgwBz
+ADMAbgAzAHAAMwByADMA1wAzANQBBgDQAQAAfgA8AOMAPAB4AEkA3QBJAH8AWgDkAFoAqgA/AKsA
+AQAPAT8AEAEBAHkAagDeAGoAqAAAAA0BAACmADcApwABAAsBNwAMAQEABAAIAJwBzACdAcwA1QHM
+ANYBzAC0ACAAGQEgADECDAAyAgwAMwK9ADYCDAA3AgwAOAK9AKAAiAAFAYgAoQDVAAYB1QCiAAQA
+BwEEAI8AiAD0AIgAkAAiAPUAIgCRAAQA9gAEAJ8ADAD7AAwAlAAAAJUAAACcAJcAnQDQAJoAjQCY
+ABEAlgAzAJcAdwCUAAEAlQABAJwAlwCdANAAmgCNAJgAEQCWADMAlwB3AJQAAgCVAAMAnACXAJ0A
+0ACaAI0AmAARAJYAMwCXAHcAlAADAJUABwCcAJcAnQDQAJoAjQCYABEAlgAzAJcAdwD6AAAA+QAA
+AAIBlwADAdAAAAGNAP4AEQD8ADMA/QB3APoAAQD5AAEAAgGXAAMB0AAAAY0A/gARAPwAMwD9AHcA
++gACAPkAAwACAZcAAwHQAAABjQD+ABEA/AAzAP0AdwD6AAMA+QAHAAIBlwADAdAAAAGNAP4AEQD8
+ADMA/QB3AIUAAACGAAAAhwBVAIgAAACJAKcAigAAAIsA3gCMAAAAhQABAIYAAQCHAFUAiAAAAIkA
+pwCKAAAAiwDeAIwAAACFAAIAhgADAIcAVQCIAAAAiQCnAIoAAACLAN4AjAAAAIUAAwCGAAcAhwBV
+AIgAAACJAKcAigAAAIsA3gCMAAAA6wAAAOoAAADsAFUA7QAAAO4ApwDvAAAA8ADeAPEAAADrAAEA
+6gABAOwAVQDtAAAA7gCnAO8AAADwAN4A8QAAAOsAAgDqAAMA7ABVAO0AAADuAKcA7wAAAPAA3gDx
+AAAA6wADAOoABwDsAFUA7QAAAO4ApwDvAAAA8ADeAPEAAACkAYAAoQFAAPv/AAAAAAAAAgAAAA3S
+EtIT0hTSDNIV0gvSAtIR0gRDABAUEAkQERABQBvSHNIA0goACwAEAA4AtQAaAQ8AQgC8AMMAIQEo
+AbYAtwC4ALkAvQC+AL8AwAAbARwBHQEeASIBIwEkASUBCgAAAAsAAAC2AAAAtwAAALgAAAC5AAAA
+GwEAABwBAAAdAQAAHgEAAL0AAAC+AAAAvwAAAMAAAAAiAQAAIwEAACQBAAAlAQAAEtIAABPSAAAA
+AAEAAgADACwAZAB0AIAAjAChAAcAAAAAAAEAAgADAAAAAAC3EyIAuBQjALkVJAC7FiUAvBcmAL0Y
+JwDAGSgAxBopAAcbAAAIHAEACx0CAAweAwAQHwQAIiEFACQiBgAmIwcAKCQIAColCQAsJgoALicL
+ADAoDAA0KQ0AOCoOADwrDwBALBAAZC4RAGgvEgBsMBMAcDEUAHQyFQB4MxYAfDQXAIA1GACENhkA
+iDcaAIw4GwCROhwAlTsdAJk8HgCdPR8AoT4gAKU/IQAkSQYCLEoKAjRLDQE8TA8BZE0RAWxOEwF0
+TxUBfFAXAYRRGQGVUh0BnVMfAQEEAAACBQEAAwYCAAQHAwAFCAQABgkFAAcKBgAICwcACQwIAAoN
+CQALDgoADA8LAA0QDAAOEQ0AAUAABAJBAQQDQgIEBEMDBAVEBAQGRQUEB0YGBAhHBwQJSAgEBAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAQACAAIAAwAEAAQABQAGAAYABwAIAAgACQAKAAoACwAMAAwADQAO
+AA4ADwAmACcAKAApACoARgBGAEcASABIAEkASgBKAEsATABoAGkAagBqAGsAbABsAG0AbgBuAG8A
+cABwAHEAcgByAHMAcwB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AAoAPwAA
+AAAAAAAAAAAAAAAAAAAAAQABAAIAAwADAAQABQAFAAYABwAHAAgACQAJAAoACwALAAwADAANAA4A
+IwAkACUAJgAnACgAKQBEAEUARgBGAEcARwBIAEgASQBJAEoASwBoAGgAaQBqAGsAbABtAG0AbgBv
+AG8AcABxAHEAcgByAHMAcwBzAHMAcwBzAHMAcwBzAHMAcwBzAHMAcwBzAHMAcwBzAAoAPwAAAAAA
+AAAAAAAAAAAAAAAAAQACAAIAAwAEAAQABQAGAAYABwAIAAgACQAKAAoACwAMAAwADQAOAA4ADwAm
+ACcAKAApACoARgBGAEcASABIAEkASgBKAEsATABoAGkAagBqAGsAbABsAG0AbgBuAG8AcABwAHEA
+cgByAHMAcwB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AAoAPwAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAABAAEAAgADAAMABAAFAAUABgAHAAcACAAJAAkACgAKAAsAJAAlACUA
+JgAnACgAKABEAEUARgBGAEcASABIAEkASgBKAEsATABoAGgAaQBqAGsAbABtAG0AbgBvAG8AcABx
+AHEAcgByAHIAcgByAHIAcgByAHIAcgByAHIAcgByAHIAcgByAHIAcgByAAoAPwCAX4AAAAAAALIM
+yAD/////////AAH//wID////BP//////////////////////Bf8G/wf/CP8J/wr/C/8M////Df//
+/w7///8P////EP//////////////////////////////////////////////Ef///xL///8T////
+FP///xX///8W////F////xj///8Z////Gv///xv/////HP///x3///8e////H////yD///8h////
+//////////////////8iIyT/JSYn//8o////Kf//////////////////////////////////////
+////////////////////////////////////////AAABAAEBAAAAAAAAAAEAAAAAAAAAAAAAAAAA
+AAMAAAAAAAAAAQAAAAAAAABIKQEAAAAAALBqAAABAAAAHNEBAAIAAACQ0AEAAwAAAJAbAgAEAAAA
+SCkBAAUAAAB0DwEABgAAALDiAAAHAAAA/A8BAAgAAAC4PQAACQAAAEBeAAAKAAAAhMEAAAsAAADE
+NwAADAAAAJAeAgANAAAA6NsAAA4AAAAo3AAADwAAAOTbAAAQAAAAJNwAABEAAADMPAEAEgAAAKTn
+AQATAAAAhDEAABQAAAAgZAEAFQAAADhQAQAWAAAAHGABABcAAAD8zwEAGAAAAIyJAQAZAAAANAIB
+ABoAAABEKQEAGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABI
+jgAASI4AAEiOAAA8eQAASI4AAEiOAACgeQAASI4AAEiOAABIjgAASI4AAEiOAABIjgAASI4AAEiO
+AABIjgAAvH8AAAR/AAD0fgAAbH4AACx/AABUfgAASI4AAEiOAACYhQAAaIgAABSKAABIjgAASI4A
+AEiOAACwjQAAsIQAAOiEAABUhAAASI4AAEiOAABIjgAAbI0AAEiOAAA0hAAASI4AAEiOAABIjgAA
+SI4AAEiOAABIjgAASI4AAEiOAABIjgAASI4AAEiOAABIjgAASI4AAEiOAABIjgAASI4AAEiOAABI
+jgAASI4AAEiOAABIjgAASI4AAEiOAABIjgAASI4AAEiOAABIjgAASI4AAEiOAABIjgAASI4AAEiO
+AABgegAASI4AAEiOAABIjgAASI4AAEiOAADQigAASI4AAEiOAABIjgAASI4AAEiOAADEegAASI4A
+ADB8AADQewAAYHsAAMB7AAD4dgAASI4AAMx2AABIjgAASI4AAEiOAABIjgAASI4AAEiOAABIjgAA
+SI4AAFh2AABIjgAASI4AAEiOAABIjgAASI4AAEiOAABIjgAASI4AAEiOAABIjgAASI4AAEiOAABI
+jgAASI4AAEiOAABIjgAASI4AABh+AABIjgAASI4AANx/AABIjgAASI4AAEiOAABIjgAASI4AACSB
+AAAMgAAASI4AAEiOAABIjgAASI4AAEiOAABIjgAASI4AAEiOAABIjgAASI4AAEiOAABIfAAASI4A
+AEiOAABIjgAASI4AAEiOAABIjgAASI4AAASNAABIjgAAZI0AAHCKAABIjgAASI4AAKx0AAAwigAA
+SI4AAEiOAAB0fgAAjH4AAEiOAABIjgAAgHoAADx3AABIjgAASI4AAEiOAADwhAAAPH4AAEiOAABI
+jgAASI4AAEiOAABIjgAASI4AAHx9AABIjgAAcI4AAPyOAADcjgAAFI8AAKiOAACQjgAAHI8AAGyO
+AABIjgAASI4AAEiOAABIjgAASI4AAEiOAABIjgAASI4AAIh6AABIjgAASI4AAEiOAABIjgAASI4A
+AEiOAABIjgAASJEAAFSSAABYdQAAzHUAAEiOAABIjgAASI4AAEiOAABIjgAAbHcAAEiOAABIjgAA
+SI4AAEiOAABIjgAASI4AAEiOAABIjgAASI4AAEiOAABIjgAASI4AANyPAAAgjwAAjJAAAHCQAACw
+jwAAOI8AAKSQAABYkAAASI4AAEiOAABIjgAASI4AAEiOAABIjgAASI4AAEiOAACgdwAAjHgAACx4
+AAC8kAAA5HUAABR5AACseQAASI4AAEiOAABIjgAASI4AAJh5AACceQAASI4AAEiOAABAeQAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAABJ0AAEybAABongAAdJ0AAHyfAAAAAAEA/////wAAAAD//////////wEAAAD4
+EwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAND+AAAAAAAAAAAYIKAAICCgAEAh
+oABIIaAAHCCgACQgoABEIaAATCGgACggoAAwIKAAaCGgAHAhoAAsIKAANCCgAGwhoAB0IaAAOCCg
+ADwgoAB4IaAAfCGgAJgRAAAA/wMAUBMAAAD/BQDcEQAAAP8tALgRAAAA/z0ANBEAAAD/BABcEQAA
+AP8lABTEAAAA/90AbBIAABAQTAA4EwAAAP8iAAASAAAA/yYA2BIAAAD/KACkEgAAAP8gAATDAAAA
+IAAASMIAAAD/MAAAAAAAAAAAAAABAQA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PBUV
+FRU8PDw8FRUVFTw8PDwAAAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8
+PDw8PDwVFRUVPDw8PBUVFRU8PDw8AAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8
+PDw8PDw8PDw8PDw8FRUVFTw8PDwVFRUVPDw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAB8AAEAjKoAAKAj
+AACMqgAAjKoAAIyqAACEDAAAtN4BAAzRAACMqgAAjKoAAJw0AACcNAAAnDQAAJw0AACcNAAAnDQA
+AJw0AACMqgAAjKoAAIyqAACMqgAAyFUAAIyqAACMqgAAjKoAAIyqAACMqgAA8NAAAIyqAACMqgAA
+iMEAAAAAAABg5wAAZOcAALQCAACgAgAA4DsBAAAAAABEuAAATL0BAGy4AAB0vQEAkLgAAJy9AQDw
+n4AAmDiAAFyagAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQhAAAsIQAA3LqAAAAC
+AAAAAAAA5PYAALT2AADcvIAAQAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOj2AAC8OAEAbMOA
+AFQAAAAAAAAA5PYAAJA3AQAcwoAAUAEAAAAAAADk9gAAmDIBAPQJgAAIAAAAAQAAAOT2AACw9QAA
+AAAAAFABAAAAAAAA5PYAACQzAQAwMYAAAgAAAAAAAADk9gAAMDIBAPAJgAAEAAAAAAAAAOz2AAC0
+9gAAwMOAACoAAAAAAAAA5PYAALT2AADQPoAABAAAAAAAAAAAAAAAvPYAAAAAAAAAAAAAAQAAAAAA
+AADQ9gAAAAAAAAAAAAAAAAAAAAAAALj2AAAAAAAAAAAAAAAAAADk9gAAwL8BAAAAAAAAAAAAAAAA
+AOT2AACAvwEA/AmAAAQAAAAAAAAAbgBuAGkAwACgAFAAgAC+AFABfQA+AAAAAAAAAJwCBADmASUA
+VQMEANwBYwAAAG4AbgBpAMAAoABQAIAAvgBQAX0APgAAAAAAAACcAgQA5gElAFUDBADcAWMAAAAA
+AAAAAQEAAMT/AAAV0gAAAAAAAP8DAADE/wAADNIAAAAAAAD/AQAAxP8AABXSAAAKAAAAAPwPAMT/
+AAAM0gAACQAAAAD+AwDE/wAAFdIAABQAAAAAAPA/xP8AAAzSAAASAAAAAAD8B8T/AAAG0gAAAAAA
+AP8BAADE/wAAB9IAAAAAAAD/AwAAxP8AAAbSAAAJAAAAAP4DAMT/AAAH0gAACgAAAAD8DwDE/wAA
+BtIAABIAAAAAAPwHxP8AAAfSAAAUAAAAAADwPwAAAAAAAAAAAAAAAAEAAAABAAAACgAAAAUAAAAF
+AAAABgAAAAoAAAAKAAAABgAAAAQAAAAFAAAABgAAAAUAAAAFAAAABgAAAAYAAAAGAAAABgAAAAcA
+AAAHAAAABwAAAAgAAAAIAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAABAAAAAgAA
+AAEAAAABAAAAAwAAAAMAAAACAAAAAQAAAAQAAAAAAAAAAAAAAAIAAAABAAAAAQAAAAAAAAAAAAAA
+BwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAACwBAABeAQAAAQAAAAEA
+AAABAAAAAQAAAAMAAAAAAAAAAAAAAJwJAQAADgEA8AwBAGwOAQD8DQEANAwBAGgOAQDECgEAwAoB
+AGDjFgAg1hMAAAAAABAAAAAAgAAAAACgABAnAADoAwAA6AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAgAAAAIAAAABAAAAAQAAAAIAAAAFAAAAAgAAAAIAAAAFAAAAAgAAAAIAAAABAAAAAQAAAAUA
+AAAFAAAAAgAAAAUAAAAFAAAAAAAAAAUAAAACAAAAAgAAAAAAAAAAAAAAAAAAAAUAAAAFAAAAAAAA
+AAUAAAACAAAAAgAAAAUAAAAFAAAABQAAAAAAAAAFAAAAAgAAAAUAAAABAAAAAQAAAAIAAAACAAAA
+AgAAAAUAAAAFAAAAAgAAAAUAAAABAAAAAQAAAAIAAAACAAAAAgAAAAUAAAAFAAAAAgAAAAIAAAAF
+AAAAAQAAAAIAAAAFAAAAAgAAAAUAAAAFAAAABAAAAAUAAAAFAAAAAQAAAAUAAAAFAAAABQAAAAIA
+AAACAAAABQAAAAUAAAAFAAAAAQAAAAUAAAAFAAAABQAAAAIAAAACAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAABEAABAAAAAoAAAUIABgIQAAIgAAADwAAB
+QwAGAxAAAsAAAAPAAAFDAAYEEAACQAAAAoAAAUQABgURAABAAAADwAABRQAGBhEAAOAAAAPAAAFF
+AAYHEQABAAAAAoAAAUYABggRAAIgAAADwAABRwAGCREAAsAAAAPAAAFHAAYKEQACQAAAAoAAAUgA
+BgsSAABAAAADwAABSQAGDBIAAOAAAAPAAAFJAAYNEgABAAAAAoAAAUoABg4SAAIAAAACgAABTAAG
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAECAQEAAgEAAQICAgABAQACAQIBAgACAAECA4CAgICAgICAAYACgICAgIDAAJAA
+0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG4AAABuAAIAbgBuAG4A
+AgBpAGkAbgABAMAAwADoAAEAoACgADYBAwBQAFAA9QABAIAAgADoAAEAvgC+AL4AAQBQAVABUAEB
+AH0AfQCvAAMAPgA+AD4AAQAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAQCcApwCnAIBAAQABAAEAAEA
+5gHmAeYBAQAlACUAJQABAFUDVQNVAwEABAAEAAQAAQDcAdwB3AEBAGMAYwBjAAEAAAAAAAAAAAAy
+AAUAMgAFAAIACABkAKAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKPGAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAIwKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABw2wEA
+FQAAAAMAAADEQoAAAAAAAAAAAAAAAAAAvNoBAAUAAAADAAAAxEKAAAAAAAAAAAAAAAAAALDaAQAK
+AAAAAwAAAMRCgAAAAAAAAAAAAAAAAAB82AEACgAAAAMAAADEQoAAAAAAAAAAAAAAAAAAzNkBAAoA
+AAAAAAAA5EKAAAAAAAAAAAAAAAAAAMzZAQAKAAAAAAAAAORCgAAAAAAAAAAAAAAAAADM2QEACgAA
+AAAAAADkQoAAAAAAAAAAAAAAAAAAzNkBAAoAAAAAAAAA5EKAAAAAAAAAAAAAAAAAAMzZAQAKAAAA
+AAAAAORCgAAAAAAAAAAAAAAAAADM2QEACgAAAAAAAADkQoAAAAAAAAAAAAAAAAAAzNkBAAoAAAAA
+AAAA5EKAAAAAAAAAAAAAAAAAAMzZAQAKAAAAAAAAAORCgAAAAAAAAAAAAAAAAADM2QEACgAAAAAA
+AADkQoAAAAAAAAAAAAAAAAAAzNkBAAoAAAAAAAAA5EKAAAAAAAAAAAAAAAAAAMzZAQAKAAAAAAAA
+AORCgAAAAAAAAAAAAAAAAADM2QEACgAAAAAAAADkQoAAAAAAAAAAAAAAAAAA3NoBAAoAAAADAAAA
+xEKAAAAAAAAAAAAAAAAAADTcAQAFAAAAAwAAAMRCgAAAAAAAAAAAAAAAAADU1wEACgAAAAAAAADk
+QoAAAAAAAAAAAAAAAAAARNgBAAoAAAAAAAAA5EKAAAAAAAAAAAAAAAAAAHTmAQAKAAAAAwAAAMRC
+gAAAAAAAAAAAAAAAAACo2AEACgAAAAAAAADkQoAAAAAAAAAAAAAAAAAAUNkBAAoAAAAAAAAA5EKA
+AAAAAAAAAAAAAAAAANDZAQAKAAAAAAAAAORCgAAAAAAAAAAAAAAAAABQ2gEACgAAAAAAAADkQoAA
+AAAAAAAAAAAAAAAAdNsBAAoAAAAAAAAA5EKAAAAAAAAAAAAAAAAAAOTbAQAKAAAAAAAAAORCgAAA
+AAAAAAAAAAAAAAAQ3AEABgAAAAAAAADkQoAAAAAAAAAAAAAAAAAAINwBAAYAAAAAAAAA5EKAAAAA
+AAAAAAAAAAAAAAAAAADEQoAAxEKAALggoABsIKAAAIABAP9//P8AAAAAAAAAAORCgADkQoAApCCg
+ADggoAABAAAA/P///wAAAAAAAAAABEOAAARDgACoIKAAPCCgABAAAADH////AAAAAAAAAAAkQ4AA
+JEOAAKwgoAB4IaAAQAEAAD/+//8AAAAAAAAAAERDgABEQ4AAsCCgAHwhoAAADAAA//H//wAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAKDYAQAVAAAAAwAAAMRCgAAAAAAAUAAAAAAAAACACYAAuKOAABgA
+AAB4o4AAAAAAAAAAAAAAAAAAgAmAALijgAAYAAAAeKOAAAAAAAAAAAAAAAAAAH8AAAAAAAAAAH8A
+AAAAAAAAAAAAAAAAAKCFgAAAAAAAAAAAAP//AAABAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAQID
+BAQEBAQFBgcICAgICAkKCwwNAABuO2g7YjtcO246aDpiOlw6bjloOWI5XDluOGg4YjhcOG43aDdi
+N1w3biloKWIpXCluKGgoYihcKG4naCdiJ1wnbhloGWIZXBluGGgYYhhcGG4XaBdiF1wXbhZoFmIW
+XBZuFWgVYhVcFW4UaBRiFFwUbhNoE2ITXBNuEmgSYhJcEm4RaBFiEVwRbhBoEGIQXBBuAmgCYgJc
+Am4BaAFiAVwBbgBoAGIAXABUAAAAbjtoO2I7XDtuOmg6YjpcOm45aDliOVw5bitoK2IrXCtuKmgq
+YipcKm4paCliKVwpbihoKGIoXChuJ2gnYidcJ24maCZiJlwmbiVoJWIlXCVuJGgkYiRcJG4jaCNi
+I1wjbiJoImIiXCJuIWghYiFcIW4gaCBiIFwgbhJoEmISXBJuEWgRYhFcEW4QaBBiEFwQVxBSEE0Q
+SRBuAWgBYgFcAW4AaABiAFwAVAAAAAAAAAAAAAAAHQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAMhaAQAIAAAAAwAAAMRCgAD4CoAAeAuAAPgLgAB4DIAACg0RFAoNERQZGRkZ
+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
+et/fpY+MjAP4oaFZgImJCRcNDRrav79lMebm18ZCQoS4aGjQw0FBgrCZmSl3LS1aEQ8PHsuwsHv8
+VFSo1ru7bToWFiz///8A////Af8CA////wQF/wn/BwoGCAsAAQECAQICAwEBAQEBAQEBAgICAgIC
+AgIDAwMDAwMDAwQEBAQEBAQEAQICAgICAgMDAwMDAwMDAwMDAwMDBAQEBAQEBAQEBAQEBAQEBAQE
+BAQEBAQEAAAAOgECAdUA3wDaAKIAdQB/AIoFKgM5AagBigXKAtkASAEBAw8HChQ3bmoBGgHZAOgA
+CgG6AHkAiADKAUoB4gD5AMoB6gCCAJkAdNFFF+iiiy4ABQcBAwQABQEFAAAABQYAAgQABQAFAAAB
+AgECAwQAAAUGBwgJCgAABQAAAAAAAAABAAAAAgAAAAMAAAAAAAAABAAAAAIAAAAFAAAAAAD/AAD/
+//8oACgAMAAsACwAKAA8ADQAQAA8AIwAbABYAEgA9ACwAH//Bw8fPwEDMAAAADYAAAAMAAAAEgAA
+ABgAAAAkAAAABgAAAAkAAAAFAAcCAwQGBkADgAbACQANgBMAGkAdgCCABgANgBMAGgAnADSAOgBB
+wAmAE0AdACeAOgBOwFeAYZkDMwfZCnMOphXmHIAgGSQzB3MOphXmHFkrzDkAQTNI2QqmFYAgWSsA
+QaZWgGFZbJ3YiZ1O7MRONEiDNCd2YicapEEaEzuxExEYgREP/MAPTuzETid2YicapEEaEzuxEw3S
+IA2JndgJCIzACAd+4Ac0SIM0GqRBGhEYgREN0iANCIzACAZpkAawstUFBVRABSd2YicTO7ETDdIg
+DYmd2AkGaZAGxE7sBARGYAQDP/ADqqqqqhqkQRoTO7ETD/zADxEYgREN0iANCqiAChM7sRMP/MAP
+D/zADw3SIA0LtEALC7RAC4md2AkN0iANCqiACgqogAoIjMAIB3iABwd4gAcGaZAGD/zADw3SIA0L
+tEALDdIgDQu0QAuJndgJCIzACImd2AkIjMAIB37gBwd+4AfBLCkHCqiACgiMwAgHeIAHCIzACAd4
+gAcGaZAGsLLVBQZpkAawstUFBVRABQVUQAXWHcYEAQcPHz9///9m5gAABQYBAgMEAABUAFQAbABg
+AFwAVACMAHgADQ8FBwkLAQMoACgANAAwACwALABEADwALAAsADwANAAwACwAVABEAFVVVQFLaC8B
+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
+QNsBAEzbAQBY2wEAYNsBAGjbAQAAAAABAAAAAgAAAAQAAAAIAAAAEAAAACAAAABAAAAAgAAAABsA
+AAA2BAIEAgAAAAABAhAECAAAAAIQBAgAAAAAAQEAAQIBAQEAAAAAAAAAAP////8AAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIANAAAAIAAAgA0AAIANAAAAIAAAgA0A
+AAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAALT8AQAgIIAPAABAAGkgAABpIEAA
+aSAAAGkgQAAgIIAPAADoAGkgAABpIEAAaSAAAGkgQAAgIIAPAADI42kgAABpIEAAaSAAAEogAABK
+IQAASiIAAEojAABKJAAASiUAAEomAABKJwAASiAAEEohABBKIgAQSiMAEEokABBKJQAQSiYAEEon
+ABBKIAAgSiEAIEoiACBKIwAgSiQAIEolACBKJgAgSicAIEogADBKIQAwCiSAP4EAAEBBLJwwQCyc
+MEIkHDQKIoA/gADYYgojADf6D4AGSiYAcGkgQABKJgBwSiYAcEomAHBKJgBwABYAcIAAVCtAeCAg
+QIcAAAAAAAAAAAAA/ByItvwcSLb8HAi2/BzItfwciLX8HEi1/BwItfwcyLT8HIi0/BxItPwcCLT8
+HMiz/ByIs/wcSLPgfuB4BNw43TXw4HgE3DTdM/DgeATcMN0x8OB4BNws3S/w4HgE3CjdLfDgeATc
+JN0r8OB4BNwg3Snw4HgE3BzdJ/DgeATcGN0l8OB4BNwU3SPw4HgE3BDdIfDgeATcDN0f8OB4BNwI
+3Rzw4HgE3ATdGfA0FBowMBQZMCwUGDAoFBcwJBQWMCAUFTAcFBQwGBQTMBQUEjAQFBEwDBQQMALH
+AcawJE0zsCQfM+B+4HjgeOB44HjgeOB4CiSA8AUgRADgIMEHRCT+gEEqxACEAAIALyQC8UIhAQFC
+IAMB6CCiBAQRBAIEEQUCBBEGAgQRBwIEGwgBBBtIAQQbiAEEG8gBLAAlAEQiPoE8ACIARCL8gEAh
+wQDgIMEHQCPDAKgggAEBEYQCARsKASAgwAcEEQQCBBEFAgQbCAHUB+H/BBtIAUQi/IAEEQQCyQfv
+/wQbCAFCIUEAQiBDAKgggAEBEYQCARsKASAgwAfPcaAArC8YgZq4GKERB2APBdjgeM9xoACsLxiB
+s7i6uBih/QZgD2TYCiJAgADZ7gABAC8mAPBKJkAATgAGAE8AIACKJf8P4HgKIkCAANnOAAEAbAAk
+AC8mAPBcAAUAKwg1CEomQAAIcQDYAiG+gOAgxQdCeQHgAiG+gOAgxQdCeesH7/8B4C8tAQBAJUUA
+AiZ88QAAIAAAKEAB6CBiAy8gAIAvIUsAAiG+gMAghgHCIYYA4H4RACAASiAAEEogQBAOIkIALyAL
+Es4gRYCKJf8PCAAFAC8tAQBAJUUAAiZ88QAAIAAAKEABSiZAAOggIgMvIACALyFLAAIhvoDAIIYB
+wiGGAEomAABCIP6QziCCAUQgfpDOIYIB4H4JAAAA4HgKJgDwiiC/D8ogZADgfy8gAwDgf4og/w/8
+HIix/BxIsfwcCLHhw+HC4cHhwAfAHBzAMeHA4H8BwFMiQoHgfE4iA4gWAAwAASjMAAApgQAAKIAA
+4H+FeU4jAwAAKMEA4H8CeOB4UyJCgeB8TiIDiBYADAAAKcwAASmBAAEogADgf4V4TiMDAAEpwADg
+fyJ54HgIdADYBSp+AC9xBSo+AwAgQI4BIcEOBSs+A+B/J3HgeDMAIABKJAAAByHEAC8mQPBKJQAA
+EAAmAC8kBAEOIECBAyVBAIDjDgADAA4iQoEDJcMABSOFgDABAQB5c0h0CHIocwolwIJKIgAQGgAE
+AMAiIRjKJQGDLy9BAcAiYxDAIsMRSicAAAolwIDAJyEIFgAEAMolgYAvKEEBwCdjAMAnAwAOJ4eC
+yickAEAnRwAKJcABTCcAiADZEAAkAADYSHFocgDbQicHiAokQHEoAAEATicKiH4AAQAAKYACASnB
+AQAqhQKgcQEqwgEAK4UCASvDAaByTCIAmGoACQCoIIAFACAAgAEhQYABIoKAASPDAAIiAoMDI8OC
+DAAGAAAiAoMBI8OCwCBmAEIkPoBKJQAAIAABAAwACgAOIkKBAyXDAC8kAIEMAAMADiBAgQMlQQDg
+fihwSHFocgDbICCADwAARAWoIIADACAAgAEhQYABIoKAkXLCIgYDxSBmACAggA8AAHgFANoJagDb
+LyECACAggA8AAKAF4HhTIkKB4HxOIgOIFgAMAAApzAACKYEAASiAAOB/hXhOIwMAAinAAOB/QinB
+B+HFCHUR8OB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB4Yb2MJf+f7fXgf8HF4HjxwOHF
+z3CAAOQsTYDPdYAAQJUghbe6uLoEIYEPAwAAAAe5RXktoLIIYA8A2ACFz3GAAKy9USCAgkyJz3CA
+AIjMMmo2ecdxgABIyWCBVnhBgAXylbtgoau6BPC1u2Chi7pBoAuNo7j5Au//C63hxeHGwIBhgKCB
+AYEAJY2TASDAAKCiAaLBxuB/wcXgeKLB8cBWCs//RcHPdYAA5CwnhRUIQQAwlRQUDjEJDkEQWR2C
+ENAVARYdCEEAz3GAAPAvPJEUFA0xDQ1BEM9xgABIMFmpi+rPdYAA+ArBjYDmANnKIEEAJPIhrQsK
+kQMB2B7wQSgNAgd9QSgBBKd5z3eAAPgKoI9TJUURHw0yBMa5CiHAD+tyz3AAAM0bn9vRBeAAiiSD
+Dw8NnhEA2AzcJwLP/892gAAIzBYmTRGnjaCvyXUWJU0RAKUUFAAxRq3HcYAAyMgCtQCJB60AGUIB
+ABtCAcfx8cCCCc//CMjPcqAAyB8OGhiACcgPGhiACsgQGhiACxIBNgLIJHgRGhiADMjPcYAAdEMt
+GhiAAIEB4AChw7hXCFEDC8h/2Qq5JHgvKAEATiCCBwDYDyCAAAQhAYBCIo0CGfILI0DAF/TPcKAA
+iCDwIFADz3aAAHRBAIbPd4AAeEENDQEQAIcScFwIQQagpgAfABRVAc//4Hif4cwg7ofMIE6ABvcC
+eUFpCwoRCIoh/w8G8ADZDyGBAGG5GHngfyhw8cCyCO//iiAPCoIkAjqacXpyWnOIdah3CiGAIQog
+wCHaCGAAnsGKcNIIYACLcYLGanDKCGAAyXFKcMIIYACEwalwughgAIbBiMXpcK4IYACpcSpwpghg
+AIrBCnCeCGAAjMGpcIrBSgzgAJDCi3DJcT4M4ACSwslwhME2DOAAlMKGwKlxKgzgAJbCmMaQwJLB
+2gygAMlymseUwJbBzgygAOlyyXDpcQoM4ACcwpzAnsHWCyAAjsKfxY4LoA8EbY7AMgkgACRttwgQ
+AIbAisGCDe//QCUCE4twhMF2De//QCUCFZTAQCUBE4IMoADJcpDAQCUBFXYMoADpcslw6XGyC+AA
+nMKMwJzBYgygAMlyfgygAMlwyXCOwW4LIABAJQIXksBAJQETRgygAMlylsBAJQEVOgygAOlyyXDp
+cXIL4ACcwozAnMEmDKAAyXLJcI7BNgsgAEAlAhmuDyAAQCUAF89xgAB8CxChng8gAEAlABnPcYAA
+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
+gACoyLR44LAQJk6TLyiBA04gjQes9Z0G7/6jwPHA4cUIdQTwUg2ADLINoAypcPzoqQbP/qPBQMBB
+wQUUgTAA2IHhQsIN8oLhB/KD4Q30IcEA2A8gQAADFIEwDyBAAAIUgTAPIEAABhSBMCEJUAATCZAA
+IwnRACHBA+EPIEAAAxSBMAPhDyBAAAIUgTAD4Q8gQAAJFIEwIQlRAAIUgTAKuU8hAgQDFIEwDLkl
+eiHBDrlFeSV4IMEVCVEABxSBMCLCBrkIukV5JXjgf6PAo8HhxULBCRSBMEPCQcAZCTMBANgRCVIA
+ChSBMAkJUgAHCRIBAdgHFIIwBhSDMBELgAAiwTBzzCJCgAP0AdghxSENURAKFIEwI8MZCcMACxSC
+MFBxzCOqgIT2gOLKIGkAGwhRAIohyQ/PcIAAcAogoIHl/9nKISIAIaDBxeB/o8DxwAohwA/rcs9w
+AACKJxzbiiTDDwUBIAC4c+B4osHhxULBQSgCAgd6QSgBBEd5z3KAAMjIxrkqYiUK3wEIFAMxz3WA
+AAjMqXFWeUCBCwiBAEKREQrAAEeJ7wregYDYA/AGicHF4H+iwOB+4HjgfuB48cAIyJW4CBoYMAnI
+m7gJGhgwC8iKuI24kLgLGhgwz3CAAOQsA4AYiBkIUQALyM9xAACQKKy4CxoYMP4M4AUP2NHA4H7x
+wOHFCHU+iM9wgACcIkCAQCUAFAO5NXlZYZoO4AsK2poP7/+pcLUEz/7gePHAOgzP/kh1wYAAgChy
+5ggv/8lxAKWRBO/+IaXhxWCAoIEBgCGBAiNDg2CiAyBAAAGi4H/BxeB48cClwUHAQsEMHAAxEBxA
+Mc9xgAB8hjQZwA8wGQAPLBnADigZgA4kGUAOz3CAAHyGIBhAC89wgAB8hhwYAAvPcIAAfIYYGMAK
+z3CAAHyGFBiACs9wgAB8hhAYwAjPcIAAfIYMGIAIz3CAAHyGCBhACM9xgAAAhoAZAAh8GcAHeBmA
+B3QZQAdwGQAHbBkAB2gZgAZkGUAGYBkABlwZwAVYGYAFVBlABVAZAAVMGcAESBmABEQZQARAGQAE
+76HOoa2hjKEsGcACKBmAAiQZQAIgGQACHBnAARgZgAEUGUABEBkAAWOhaiAAA9gZAABqIMAC1BkA
+AGoggALQGQAAaiBAAcgZAABqIAABxBkAAGogwADAGQAAaiCAALwZAABqIEAAuBkAAGogAAC0GQAA
+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
+FEjPdqAA7Cf2CC/+BdgOpc9wgACAKwCAAeDPcYAAgCsAoRcIUQAB2c9woADIHDGgcgzgBShwA9iy
+CG/3qXEE2KoIb/cibQXYoghv9yRtC9iaCG/3Jm0P2JIIb/dAJQESNtiKCG/3QCWBEjfYfghv90Al
+ARM42HYIb/dAJYETCIcEpQ2HBaUOhwalz3CnAJhHHIAHpReHCKUWhwmlz3CrAKD/GIALpc9wqwCg
+/xmADKXPcKsAoP8agA2lz3AFAMYDBqbG2JC4BqbPcCwAAgEGps9wWgBCAQamiiCLAAamz3BAAIcN
+BqbPcNEAwg0Gps9wwAAHDgamz3CAAIArIIARCVEAz3KgAMgcANgRogHYCKcA2A2nDqfPcKcAmEfP
+clAA/wBcoAHYF6cA2Ban/NrPcKsAoP9YoHPaWaAagM9yqwCg/4G4GqLPcIAAgCsgoBUJUQDPcaAA
+yBwB2BGhRgvABc9wQACGDQamz3AQAAIOBqaLcIIK4AOBwTaFAMAieAQogA8AAHQJFYU3hQJ5Qgxv
+9i9wAcJP4M9xgADQiRSlV6EYoc9wQACHDQamz3ARAAYOBqbPcIAAgCsAgM9xgACAK0IgQIAAoQf0
+z3GgAMgcANgRoYtwHgrgA4HBNoUAwCJ4gg4v/BKlMoVVhSx4N4UvIEAOQnk5YdoLb/Y1eeC4HHjA
+IGIAgiDEAs9xgADQiRKlE6UWoc9wgACAKwCAAcIB4FWhz3GAAIArAKEVCFEAz3GgAMgcAdgRoWoK
+wAUBlRC4hSCEAAamApUQuIUghQAGpgOVELiFIIsABqYElRC4hSCPAAamBZUQuAUggA8AAIINBqYG
+lRC4BSCADwAAwg0GpgeVELgFIIAPAAACDgamz3CAAIArAIDPcYAAgCtCIECAAKEH9M9xoADIHADY
+EaEEhSuFCKcFhQ2nBoUOpwiFF6cJhRanz3CrAKD/OKAshTmgLYU6oFYN7/0OhUgVBBCMJIKARfaM
+JD+BDfa6CeAFCthmC4ADQiBAIIDgAgXN/0gVBBCMJIKARfaMJD+BDPYKIcAP63LPcAAAtBmKI0UM
++QRv97hzz3CAAKojAIgG6M9wgACsQgAQBACIcDkBb/aiwM9wgABMQuB/FIDgeM9xAQDwQc9yAQB8
+OJEAL/sA2OB44H7gePHAz3CAAJg4AIBAeM9wgACUOACAQHjRwOB+4HjPcoAAvAoZCB4AgOFR2MAo
+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
+qwCg/zmgOKDRwOB+8cDhxc9xgADkLPAhAgBKJEAAwxIBBg94MiKCDwAAHwMEIYMPAAYAAIDjAdvA
+ewQhjQ9AAAAA13VAAAAAwiQCAcoO7/vAuRkET/TgePHAngtP9GYMoAEIdc9xgAAgvR+Bz3agAMQn
+sLgfoRkWAJYA2QToAtgQHhiQz3CgANQLN6DmDYAAPgigAgHYBe3yDgAABfDSDgAAIg1P+xkWAJYF
+6ALYEB4YkLEDT/TgePHAQgggAQHYANnPcIAA7EQuoP4Ob/YZ2NHA4H7xwBYLT/SiwYt2jgvv+slw
+CiUAkBn0z3CAACC9z3GgAAwkO4FXgDByyiUiEiCGDQkeBALZjBhEAAQlgl8AAHDHP4BFeT+ggOW6
+AwIAAMDpuNbyz3WAALw4AIWKIQgA5JDPdqAAxCcTHliQz3GAACC9P4E6d4Yh/COFCV4EQSkBIcO5
+z3KAAMxdNnoggkB5CHUZFgCWBOgC2BAeGJDPcAAA/38THhiQG9gWHhiQA9nPcKAA1AsxoOB44Hjg
+eOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB4MaDPcIAAWIcZgIDgJA3CAJrlGgMCAM9wgABA1oYL
+oAIA3QsDAADGDG//KnAacACFWg0v/ypx4g0v/wh3iOfMJ+KVyiXBEyvyGwgQIO4KIACBwAolAJAc
+9IYM7/8BwBjwA9nPcKAA1AsxoOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB44HjgeOB4MaAA3Q8P
+kRbPcIAAQNYKC4ACgOWOAgIALgwAAc9wgAAgvR+AEQieAwHZz3CAALQJIKAJ8A8I3gMB2c9wgAC4
+CSCgERYAlgDdQcAxCJ8A6gnv+oHACiUAkBD0BBQFMB0NnwAKIcAP63IK2Iy4iiPHClEFb/WKJIMP
+gOUqAgIABNgTHhiQG9gWHhiQz3CAAFiHGYCA4BAMwgALAgAA4LjB8s92gAAgvRKGhiA6AIwgBIKU
+CwUBz3GgAAwkPIEXhiJ4ZLgQeIoeBBBEIgBTFwgRAh+GDwhfBFElQNEB2AX0ANgD8OoLT/+cHgAQ
+LuhGDw//CiUAkNf0DcwhCN4BH4YdCJ4BLyCHCowgAoYI9M9xgAAgvR+BmLgfoZYJIACBwAolAJDB
+9M92gAAgvR+GKwgeBKgWARDU2BoOoADJcgfozgnAAwvweghP/6zwz3GAAORFHoEB4B6hAd/PcIAA
+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
+yCDAEHBFwBAQCMAQAAATJQMAEyQcCMARHAjAEQAAEyQECMARDxQVIgQAFSb7/zAyAwATJBgIwBEP
+FBUiAgAVJgQAMDAAABMkEEXAERgIwBEAEFgwD3wTIggAzBEAABMlAAATJDRIxxEPexMiAQATMAQo
+wBEPFBUiAgAVJv8AEyUCEBMkBCjAEQ8UFSICABUmvAqAgQAAwBbCLBMkBCjAEQJGEyQEKMARwl8T
+JAQowBEPTRMiBBDFEQIAEyTwHMARAQATJOwcwBEAABMkcAATJRAcwBEAABMlAAATJOAcwBGAABMl
+RmgTJAQowBEAABMlAQATJCQQwBEAABUkAAAAIQ8OGiIAAEAWAAEbcA0AAGGAAGMk//4bMgAAQBcA
+ABslDxsPIpwJgIH/ABsyAgAbQQAbGigAAMAWAAAbJQIAG0AAABtxAQBkcAcAAGEBAGMkAAAbJH4J
+gIEAAEAXdAmAgQAAQBbtDwBhAgBkcBAAAGECAGMkAQAbJH4JgIEAAEAXdgmAgQAAQBbkDwBhBABk
+cAcAAGECAGMkAgAbJH4JgIEAAEAXeAmAgQAAQBbbDwBhAAAdJAAAACEAAg9uCQAAYX4JgIEAAEAW
+AAAbJXoJgIEAGxooAAAAFgEAGyYAAAAXDQAAYZQJgIEAAEAWAgAbJgEQG2gAABskAABAF4AJgIEA
+GhsoDxsOIpgJgIEAAEAWAQAbJgAAQBcACICBDxobIgAAGyUCABtAAAAbcQAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgBIAAuAGAAAAAAAAAAAAA
+KACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAHAAAABwAAAAAAAAAHAAAACQ0RFAoNExcZGRkZCQkAAOibgABQfAAA
+0KCAAAAAAADQoIAAAAAAAN8AAAAZAQAAYgEAAL4BAAAyAgAAwwIAAHsDAABiBAAAhAUAAPIGAAC+
+CAAAAgsAAAEAAAAAAAAAMIAAAAAAAAAxgAAAiIgzMzKAAAAAqqqKM4AAAAAAAAA0gAAAAAAAADWA
+AAAAAAAANoAAAAAAAAA3gAAAAAAAADiAAAAAAAAAOYAAAAAAAAA6gAAAAAAAADuAAAAAAAAAPIAA
+AAAAAAA9gAAAqqoKAD6AAABThYiIP4AAAAAAADAwgAAAAAAAADGAAACamVhVMoAAAACqqqozgAAA
+AAAAADSAAAAAAAAANYAAAAAAAAA2gAAAAAAAADeAAAAAAAAAOIAAAAAAAAA5gAAAAAAAADqAAAAA
+AAAAO4AAAAAAAAA8gAAAAAAAAD2AAACqqgoAPoAAAFWYmao/gAAAAAAAUDCAAAAAAAAAMYAAAAAA
+AAAygAAAAAAAADOAAAAAAAAANIAAAAAAAAA1gAAAAAAAADaAAAAAAAAAN4AAAAAAAAA4gAAAAAAA
+ADmAAAAAAAAAOoAAAAAAAAA7gAAAAAAAADyAAAAAAAAAPYAAAAAAAAA+gAAAAAAAAD+AAAAAAAAA
+MIAAAAAAAAAxgAAAAAAAADKAAAAAAAAAM4AAAAAAAAA0gAAAmnkAADWAAACqqqqqNoAAAAAAAAA3
+gAAAAAAAADiAAAAAAAAAOYAAAAAAAAA6gAAAqqqqCjuAAAAAcJmqPIAAAAAAAAA9gAAAAAAAAD6A
+AAAAAAAAP4AAAAAAAAD//wAApQEBALkB3wA7Ai0AsQAbABYBGwCvABsAFAEbAGwAoADRAKAAbwCD
+AHEAgwBzADMA1AEGANABAAB4AEkAeQBqAN4AagCoAAAADQEAAKYAPwCnAAEACwE/AAwBAQAEAAgA
+nAHMAJ0BzADVAcwA1gHMALQAIAAZASAAjwCIAPQAiACQACIA9QAiAJEABAD2AAQAhQAAAIYAAACH
+AFUAiAAAAIkAqgCKAAAAiwDdAIwAAACFAAEAhgABAIcAVQCIAAAAiQCqAIoAAACLAN0AjAAAAIUA
+AgCGAAMAhwBVAIgAAACJAKoAigAAAIsA3QCMAAAAhQADAIYABwCHAFUAiAAAAIkAqgCKAAAAiwDd
+AIwAAAD7/wAA//8AALkB3wA7Ai0AsQAbABYBGwCvABsAFAEbAGwAoADRAKAAbwCDAHEAgwBzADMA
+1AEGANABAAB4AEkAeQBqAN4AagCoAAAADQEAAKYAPwCnAAEACwE/AAwBAQAEAAgAnAHMAJ0BzADV
+AcwA1gHMALQAIAAZASAAjwCIAPQAiACQACIA9QAiAJEABAD2AAQAqAAMAA0BDACFAAAAhgAAAIcA
+mQCIAAAAiQCqAIoAAACLAN0AjAAAAIUAAQCGAAEAhwCZAIgAAACJAKoAigAAAIsA3QCMAAAAhQAC
+AIYAAwCHAJkAiAAAAIkAqgCKAAAAiwDdAIwAAACFAAMAhgAHAIcAmQCIAAAAiQCqAIoAAACLAN0A
+jAAAAPv/AAD//wAAuQHfALEAGwAWARsArwAbABQBGwBsAKAA0QCgAG8AgwBxAIMAdgCDAHMAMwBu
+ADMAcAAzAHIAMwDXADMA1AEGANABAAB+ADwA4wA8AHgASQDdAEkAfwBaAOQAWgCqAD8AqwABAA8B
+PwAQAQEAeQBqAN4AagCoAAAADQEAAKYANwCnAAEACwE3AAwBAQAEAAgAnAHMAJ0BzADVAcwA1gHM
+ALQAIAAZASAAMQIMADICDAAzAr0ANgIMADcCDAA4Ar0AoACIAAUBiAChANUABgHVAKIABAAHAQQA
+jwCIAPQAiACQACIA9QAiAJEABAD2AAQAnwAMAPsADACUAAAAlQAAAJwAlwCdANAAmgCNAJgAEQCW
+ADMAlwB3AJQAAQCVAAEAnACXAJ0A0ACaAI0AmAARAJYAMwCXAHcAlAACAJUAAwCcAJcAnQDQAJoA
+jQCYABEAlgAzAJcAdwCUAAMAlQAHAJwAlwCdANAAmgCNAJgAEQCWADMAlwB3APoAAAD5AAAAAgGX
+AAMB0AAAAY0A/gARAPwAMwD9AHcA+gABAPkAAQACAZcAAwHQAAABjQD+ABEA/AAzAP0AdwD6AAIA
++QADAAIBlwADAdAAAAGNAP4AEQD8ADMA/QB3APoAAwD5AAcAAgGXAAMB0AAAAY0A/gARAPwAMwD9
+AHcAhQAAAIYAAACHAFUAiAAAAIkApwCKAAAAiwDeAIwAAACFAAEAhgABAIcAVQCIAAAAiQCnAIoA
+AACLAN4AjAAAAIUAAgCGAAMAhwBVAIgAAACJAKcAigAAAIsA3gCMAAAAhQADAIYABwCHAFUAiAAA
+AIkApwCKAAAAiwDeAIwAAADrAAAA6gAAAOwAVQDtAAAA7gCnAO8AAADwAN4A8QAAAOsAAQDqAAEA
+7ABVAO0AAADuAKcA7wAAAPAA3gDxAAAA6wACAOoAAwDsAFUA7QAAAO4ApwDvAAAA8ADeAPEAAADr
+AAMA6gAHAOwAVQDtAAAA7gCnAO8AAADwAN4A8QAAAKQBgAChAUAA+/8AAP//AAClAQEAuQHfALEA
+GwAWARsArwAbABQBGwBsAKAA0QCgAG8AgwBxAIMAdgCDAHMAMwBuADMAcAAzAHIAMwDXADMA1AEG
+ANABAAB+ADwA4wA8AHgASQDdAEkAfwBaAOQAWgCqAD8AqwABAA8BPwAQAQEAeQBqAN4AagCoAAAA
+DQEAAKYANwCnAAEACwE3AAwBAQAEAAgAnAHMAJ0BzADVAcwA1gHMALQAIAAZASAAMQIMADICDAAz
+Ar0ANgIMADcCDAA4Ar0AoACIAAUBiAChANUABgHVAKIABAAHAQQAjwCIAPQAiACQACIA9QAiAJEA
+BAD2AAQAnwAMAPsADACUAAAAlQAAAJwAlwCdANAAmgCNAJgAEQCWADMAlwB3AJQAAQCVAAEAnACX
+AJ0A0ACaAI0AmAARAJYAMwCXAHcAlAACAJUAAwCcAJcAnQDQAJoAjQCYABEAlgAzAJcAdwCUAAMA
+lQAHAJwAlwCdANAAmgCNAJgAEQCWADMAlwB3APoAAAD5AAAAAgGXAAMB0AAAAY0A/gARAPwAMwD9
+AHcA+gABAPkAAQACAZcAAwHQAAABjQD+ABEA/AAzAP0AdwD6AAIA+QADAAIBlwADAdAAAAGNAP4A
+EQD8ADMA/QB3APoAAwD5AAcAAgGXAAMB0AAAAY0A/gARAPwAMwD9AHcAhQAAAIYAAACHAFUAiAAA
+AIkApwCKAAAAiwDeAIwAAACFAAEAhgABAIcAVQCIAAAAiQCnAIoAAACLAN4AjAAAAIUAAgCGAAMA
+hwBVAIgAAACJAKcAigAAAIsA3gCMAAAAhQADAIYABwCHAFUAiAAAAIkApwCKAAAAiwDeAIwAAADr
+AAAA6gAAAOwAVQDtAAAA7gCnAO8AAADwAN4A8QAAAOsAAQDqAAEA7ABVAO0AAADuAKcA7wAAAPAA
+3gDxAAAA6wACAOoAAwDsAFUA7QAAAO4ApwDvAAAA8ADeAPEAAADrAAMA6gAHAOwAVQDtAAAA7gCn
+AO8AAADwAN4A8QAAAKQBgAChAUAA+/8AAAAAAAACAAAADdIS0hPSFNIM0hXSC9IC0hHSBEMAEBQQ
+CRAREAFAG9Ic0gDSCgALAAQADgC1ABoBDwBCALwAwwAhASgBtgC3ALgAuQC9AL4AvwDAABsBHAEd
+AR4BIgEjASQBJQEKAAAACwAAALYAAAC3AAAAuAAAALkAAAAbAQAAHAEAAB0BAAAeAQAAvQAAAL4A
+AAC/AAAAwAAAACIBAAAjAQAAJAEAACUBAAAS0gAAE9IAAAAAAQACAAMALABkAHQAgACMAKEABwAA
+AAAAAQACAAMAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+BwAAAAcAAAAAAAAAAwAAAAQAAAADAAAAAAAAAP8DAAADAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAA
+AAAAAAAAACwAAQAAAAEAAQABAAAAAAAAAAAAAQABAAIAAgACAAMAAwAEAAQABQAFAAYABgAHAAcA
+CAAIAAkACQAKAAoACwALAAwADAANAA0ADgAOAA8AAAABAAIAAAAL0g7SDdII0gnSCtIS0hPSFNIR
+0hDSAtIB0gPSAIAF0gRDG9Ic0gTSAEUw0jHSAAC1ABoBgQEFAAQADwAQAAoACwAMAE4AAAAAAAEA
+AgAAAA3SEdIQ0gLSAdID0hvSC9IAgAXSEtIT0hTSBEMI0gnSCtIc0gbSB9Jw0gAAtQAaAYEBBAAP
+AIMA6ABOAZIA9wBdAQYACAAJAAoACwAMAAUAAAAAAAAAAAAKAAAAAQAAAAAAAAAAAAAAAAAAAAMA
+AAAEAAAAAwAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAP8DAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAALAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQABAAAABNIN0hHSENIC0gHS
+A9Ib0gCABdIL0hLSE9IU0gRDcNIAAAAAAQAAAAEAAAABAAAAAQAAAAMAAAACAAAAAwAAAAMAAAAA
+AAAAAQAAAAAAAAAAAAAAAAAAAP8DAAAAAAAAtQAaAYEBBAAPAAYACAAJAAoACwAMAAAAAAAAAAAA
+LAABABUAFQAVAAEAAQABAAAAAAABAAIAAAAc0g3SEdIQ0gLSAdID0hvSC9IAgAXSEtIT0hTSBEMG
+0gfSBNJw0gAAtQAaAYEBBQAEAAYACAAJAAoACwAMAIMAkgDoAPcATgFdAQ8AAAAAALcTIgC4FCMA
+uRUkALsWJQC8FyYAvRgnAMAZKADEGikABxsAAAgcAQALHQIADB4DABAfBAAiIQUAJCIGACYjBwAo
+JAgAKiUJACwmCgAuJwsAMCgMADQpDQA4Kg4APCsPAEAsEABkLhEAaC8SAGwwEwBwMRQAdDIVAHgz
+FgB8NBcAgDUYAIQ2GQCINxoAjDgbAJE6HACVOx0AmTweAJ09HwChPiAApT8hACRJBgIsSgoCNEsN
+ATxMDwFkTREBbE4TAXRPFQF8UBcBhFEZAZVSHQGdUx8BAQQAAAIFAQADBgIABAcDAAUIBAAGCQUA
+BwoGAAgLBwAJDAgACg0JAAsOCgAMDwsADRAMAA4RDQABQAAEAkEBBANCAgQEQwMEBUQEBAZFBQQH
+RgYECEcHBAlICAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAgACAAMABAAEAAUABgAGAAcACAAIAAkACgAK
+AAsADAAMAA0ADgAOAA8AJgAnACgAKQAqAEYARgBHAEgASABJAEoASgBLAEwAaABpAGoAagBrAGwA
+bABtAG4AbgBvAHAAcABxAHIAcgBzAHMAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0
+AHQAdAAKAD8AAAAAAAAAAAAAAAAAAAAAAAEAAQACAAMAAwAEAAUABQAGAAcABwAIAAkACQAKAAsA
+CwAMAAwADQAOACMAJAAlACYAJwAoACkARABFAEYARgBHAEcASABIAEkASQBKAEsAaABoAGkAagBr
+AGwAbQBtAG4AbwBvAHAAcQBxAHIAcgBzAHMAcwBzAHMAcwBzAHMAcwBzAHMAcwBzAHMAcwBzAHMA
+cwAKAD8AAAAAAAAAAAAAAAAAAAAAAAEAAgACAAMABAAEAAUABgAGAAcACAAIAAkACgAKAAsADAAM
+AA0ADgAOAA8AJgAnACgAKQAqAEYARgBHAEgASABJAEoASgBLAEwAaABpAGoAagBrAGwAbABtAG4A
+bgBvAHAAcABxAHIAcgBzAHMAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAAK
+AD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAIAAwADAAQABQAFAAYABwAHAAgACQAJAAoA
+CgALACQAJQAlACYAJwAoACgARABFAEYARgBHAEgASABJAEoASgBLAEwAaABoAGkAagBrAGwAbQBt
+AG4AbwBvAHAAcQBxAHIAcgByAHIAcgByAHIAcgByAHIAcgByAHIAcgByAHIAcgByAHIAcgAKAD8A
+gGOAAAAAAACyDMgA/////////wAB//8CA////wT//////////////////////wX/Bv8H/wj/Cf8K
+/wv/DP///w3///8O////D////xD//////////////////////////////////////////////xH/
+//8S////E////xT///8V////Fv///xf///8Y////Gf///xr///8b/////xz///8d////Hv///x//
+//8g////If//////////////////////IiMk/yUmJ///KP///yn/////////////////////////
+/////////////////////////////////////////////////////wABAAEBAAAAAAAAAAABAAAA
+AAAAAAAAAAAAAAADAAAAAAAAAAEAAAAAAAAAsBsBAAAAAACwdAAAAQAAAMSqAQACAAAAOKoBAAMA
+AAB89QEABAAAALAbAQAFAAAANAkBAAYAAABI4gAABwAAALwJAQAIAAAAbC4AAAkAAADETgAACgAA
+AIDEAAALAAAAvCsAAAwAAACA9QEADQAAAOjaAAAOAAAAlNsAAA8AAAB02gAAEAAAAHTbAAARAAAA
+rCcBABIAAAA0wQEAEwAAABgkAAAUAAAA1E4BABUAAAAYOwEAFgAAABhKAQAXAAAAeKkBABgAAAD0
+dQEAGQAAAMD7AAAaAAAArBsBABsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAA5JQAAOSUAADklAAAfIIAAOSUAADklAAA4IIAAOSUAADklAAA5JQAAOSUAADklAAA
+5JQAAOSUAADklAAA5JQAADCKAAB4iQAAaIkAAOCIAACgiQAAnIgAAOSUAADklAAAMIwAAACPAACs
+kAAA5JQAAOSUAADklAAATJQAAEiLAACAiwAA7IoAAOSUAADklAAA5JQAAAiUAADklAAAzIoAAOSU
+AADklAAA5JQAAOSUAADklAAA5JQAAOSUAADklAAA5JQAAOSUAADklAAA5JQAAOSUAADklAAA5JQA
+AOSUAADklAAA5JQAAOSUAADklAAA5JQAAOSUAADklAAA5JQAAOSUAADklAAA5JQAAOSUAADklAAA
+5JQAAOSUAADklAAAoIMAAOSUAADklAAA5JQAAOSUAADklAAAbJEAAOSUAADklAAA5JQAAOSUAADk
+lAAAfIYAAOSUAACMhgAAiIYAAICGAACEhgAAaIAAAOSUAAA8gAAA5JQAAOSUAADklAAA5JQAAOSU
+AADklAAA5JQAAOSUAADIfwAA5JQAAOSUAADklAAA5JQAAOSUAADklAAA5JQAAOSUAADklAAA5JQA
+AOSUAADUhAAAcIQAAOSUAADwhAAA5JQAAMCDAABgiAAA5JQAAOSUAABQigAA5JQAAOSUAADklAAA
+5JQAAOSUAACcigAAgIoAAOSUAADklAAA5JQAAOSUAADklAAA5JQAAOSUAADklAAA5JQAAOSUAADk
+lAAAkIYAAOSUAADklAAA5JQAAGiRAADklAAA5JQAAOSUAACgkwAA5JQAAACUAAAIkQAA5JQAAOSU
+AACwfgAAyJAAAOSUAADklAAA6IgAAACJAADklAAA5JQAADiGAACsgAAA5JQAAOSUAADklAAAiIsA
+AISIAADklAAA5JQAAOSUAADklAAA5JQAAOSUAADEhwAA5JQAAAyVAACYlQAAeJUAALCVAABElQAA
+LJUAALiVAAAIlQAA5JQAAOSUAADklAAA5JQAAOSUAADklAAA5JQAAOSUAABAhgAA5JQAAOSUAADk
+lAAA5JQAAOSUAADklAAA5JQAAEiWAABUlwAAyH4AADx/AADklAAA5JQAAOSUAADklAAA5JQAANyA
+AADklAAA5JQAAOSUAADklAAA5JQAAOSUAADklAAA5JQAAOSUAADklAAA5JQAAOSUAADklAAA5JQA
+AOSUAADklAAA5JQAAOSUAADklAAA5JQAAOSUAADklAAA5JQAAOSUAADklAAA5JQAAOSUAADklAAA
+4IAAAMyBAABsgQAAvJUAAFR/AABUggAA7IIAAOSUAADklAAA5JQAAOSUAADYggAA3IIAAOSUAADk
+lAAAgIIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAFijAACgoQAAvKQAAMijAADQpQAAAAABAP////8AAAAA////
+//////8BAAAAkBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAADQ/gAAAAAAAAAA
+AAAAABggoAAgIKAAQCGgAEghoAAcIKAAJCCgAEQhoABMIaAAKCCgADAgoABoIaAAcCGgACwgoAA0
+IKAAbCGgAHQhoAA4IKAAPCCgAHghoAB8IaAASA8AAAD/AwDoDwAAAP8FAIwPAAAA/y0AaA8AAAD/
+PQAEDwAAAP8EACwPAAAA/yUARMUAAAD/3QCwDwAAEBBMAAAAAAAAAAAAAAEBADw8PDw8PDw8PDw8
+PDw8PDw8PDw8PDw8PDw8PDw8PDw8FRUVFTw8PDwVFRUVPDw8PAAAAAAAAAAAAAAAAAAAAAA8PDw8
+PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PBUVFRU8PDw8FRUVFTw8PDwAAAAAAAAAAAAAAAAA
+AAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwVFRUVPDw8PBUVFRU8PDw8AAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAA/wAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAA6BEAAGwYAAAwFQAAwBIAACQaAAAgFgAAcBcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFQKgAB4oYAAGAAAADihgAAAAAAA
+AAAAAAAAAAAAAAAAPPkAAJSwAACEIQAAlLAAAJSwAACUsAAAOAoAAFC5AQBEzwAAlLAAAJSwAABc
+JwAAXCcAAFwnAABcJwAAXCcAAFwnAABcJwAAlLAAAJSwAACUsAAAlLAAAJxFAACUsAAAlLAAAJSw
+AACUsAAAlLAAACjPAACUsAAAlLAAAITEAAAAAAAA+OQAAPzkAAC0AgAAoAIAAMAmAQAUvQAADJcB
+ADy9AAA0lwEAYL0AAFyXAQCAQYAAZJaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIHwAA
+EB8AAHykgAAAAgAAAAAAANzxAACs8QAAfKaAAEAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADg
+8QAAnCMBAAytgABUAAAAAAAAANzxAABwIgEAvKuAAFABAAAAAAAA3PEAAHgdAQCoCoAACAAAAAEA
+AADc8QAAqPAAAAAAAABQAQAAAAAAANzxAAAEHgEAGDqAAAIAAAAAAAAA3PEAABAdAQCkCoAABAAA
+AAAAAADk8QAArPEAAGCtgAAqAAAAAAAAANzxAACs8QAAkEaAAAQAAAAAAAAAAAAAALTxAAAAAAAA
+AAAAAAEAAAAAAAAAyPEAAAAAAAAAAAAAAAAAAAAAAACw8QAAAAAAAAAAAAAAAAAA3PEAAACZAQAA
+AAAAAAAAAAAAAADc8QAAwJgBALAKgAAEAAAAAAAAAG4AbgBpAMAAoABQAIAAvgBQAX0APgAAAAAA
+AACcAgQA5gElAFUDBADcAWMAAABuAG4AaQDAAKAAUACAAL4AUAF9AD4AAAAAAAAAnAIEAOYBJQBV
+AwQA3AFjAAAAAAAAAAEBAACE+AAAFdIAAAAAAAD/AwAAhPgAAAzSAAAAAAAA/wEAAIT4AAAV0gAA
+CgAAAAD8DwCE+AAADNIAAAkAAAAA/gMAhPgAABXSAAAUAAAAAADwP4T4AAAM0gAAEgAAAAAA/AeE
++AAABtIAAAAAAAD/AQAAhPgAAAfSAAAAAAAA/wMAAIT4AAAG0gAACQAAAAD+AwCE+AAAB9IAAAoA
+AAAA/A8AhPgAAAbSAAASAAAAAAD8B4T4AAAH0gAAFAAAAAAA8D8AAAAAAAAAAAAAAAABAAAAAQAA
+AAoAAAAFAAAABQAAAAYAAAAKAAAACgAAAAYAAAAEAAAABQAAAAYAAAAFAAAABQAAAAYAAAAGAAAA
+BgAAAAYAAAAHAAAABwAAAAcAAAAIAAAACAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAC
+AAAAAQAAAAIAAAABAAAAAQAAAAMAAAADAAAAAgAAAAEAAAAEAAAAAAAAAAAAAAACAAAAAQAAAAEA
+AAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAsAQAA
+XgEAAAEAAAABAAAAAQAAAAEAAAADAAAAAAAAAAAAAABcAwEAwAcBALAGAQAsCAEAvAcBAPQFAQAo
+CAEAhAQBAIAEAQBg4xYAINYTAAAAAAAQAAAAAIAAAAAAoAAQJwAA6AMAAOgDAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAIAAAACAAAAAQAAAAEAAAACAAAABQAAAAIAAAACAAAABQAAAAIAAAACAAAA
+AQAAAAEAAAAFAAAABQAAAAIAAAAFAAAABQAAAAAAAAAFAAAAAgAAAAIAAAAAAAAAAAAAAAAAAAAF
+AAAABQAAAAAAAAAFAAAAAgAAAAIAAAAFAAAABQAAAAUAAAAAAAAABQAAAAIAAAAFAAAAAQAAAAEA
+AAACAAAAAgAAAAIAAAAFAAAABQAAAAIAAAAFAAAAAQAAAAEAAAACAAAAAgAAAAIAAAAFAAAABQAA
+AAIAAAACAAAABQAAAAEAAAACAAAABQAAAAIAAAAFAAAABQAAAAQAAAAFAAAABQAAAAEAAAAFAAAA
+BQAAAAUAAAACAAAAAgAAAAUAAAAFAAAABQAAAAEAAAAFAAAABQAAAAUAAAACAAAAAgAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAARAAAQAAAAKAAAFCAAYC
+EAACIAAAA8AAAUMABgMQAALAAAADwAABQwAGBBAAAkAAAAKAAAFEAAYFEQAAQAAAA8AAAUUABgYR
+AADgAAADwAABRQAGBxEAAQAAAAKAAAFGAAYIEQACIAAAA8AAAUcABgkRAALAAAADwAABRwAGChEA
+AkAAAAKAAAFIAAYLEgAAQAAAA8AAAUkABgwSAADgAAADwAABSQAGDRIAAQAAAAKAAAFKAAYOEgAC
+AAAAAoAAAUwABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAECAQEAAgEAAQICAgABAQACAQIBAgACAAECA4CAgICAgICAAYACgICA
+gIDAAJAA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAjAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADy1AQAV
+AAAAAwAAAExKgAAAAAAAAAAAAAAAAADgtAEABQAAAAMAAABMSoAAAAAAAAAAAAAAAAAA1LQBAAoA
+AAADAAAATEqAAAAAAAAAAAAAAAAAALCyAQAKAAAAAAAAAGxKgAAAAAAAAAAAAAAAAADwswEACgAA
+AAAAAABsSoAAAAAAAAAAAAAAAAAA8LMBAAoAAAAAAAAAbEqAAAAAAAAAAAAAAAAAAPCzAQAKAAAA
+AAAAAGxKgAAAAAAAAAAAAAAAAADwswEACgAAAAAAAABsSoAAAAAAAAAAAAAAAAAA8LMBAAoAAAAA
+AAAAbEqAAAAAAAAAAAAAAAAAAPCzAQAKAAAAAAAAAGxKgAAAAAAAAAAAAAAAAADwswEACgAAAAAA
+AABsSoAAAAAAAAAAAAAAAAAA8LMBAAoAAAAAAAAAbEqAAAAAAAAAAAAAAAAAAPCzAQAKAAAAAAAA
+AGxKgAAAAAAAAAAAAAAAAADwswEACgAAAAAAAABsSoAAAAAAAAAAAAAAAAAA8LMBAAoAAAAAAAAA
+bEqAAAAAAAAAAAAAAAAAAPCzAQAKAAAAAAAAAGxKgAAAAAAAAAAAAAAAAAB0tgEABgAAAAAAAABs
+SoAAAAAAAAAAAAAAAAAA3LUBAAUAAAADAAAATEqAAAAAAAAAAAAAAAAAAAiyAQAKAAAAAAAAAGxK
+gAAAAAAAAAAAAAAAAAB4sgEACgAAAAAAAABsSoAAAAAAAAAAAAAAAAAA4L8BAAoAAAADAAAATEqA
+AAAAAAAAAAAAAAAAAMyyAQAKAAAAAAAAAGxKgAAAAAAAAAAAAAAAAAB0swEACgAAAAAAAABsSoAA
+AAAAAAAAAAAAAAAA9LMBAAoAAAAAAAAAbEqAAAAAAAAAAAAAAAAAAHS0AQAKAAAAAAAAAGxKgAAA
+AAAAAAAAAAAAAABAtQEACgAAAAAAAABsSoAAAAAAAAAAAAAAAAAAsLUBAAoAAAAAAAAAbEqAAAAA
+AAAAAAAAAAAAAAAAAABMSoAATEqAALggoABsIKAAAIABAP9//P8AAAAAAAAAAGxKgABsSoAApCCg
+ADggoAABAAAA/P///wAAAAAAAAAAjEqAAIxKgACoIKAAPCCgABAAAADH////AAAAAAAAAACsSoAA
+rEqAAKwgoAB4IaAAQAEAAD/+//8AAAAAAAAAAMxKgADMSoAAsCCgAHwhoAAADAAA//H//wAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAMSyAQAVAAAAAwAAAExKgAAAAAAAAAAAAAAAAABUCoAAeKGAABgA
+AAA4oYAAAAAAAAAAAAAAAAAAfwAAAAAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAADgAAABoAAAAdAAA
+AIAAAACMAAAAnQAAAAcAAAAAAAAA/////wAAAAAtAQAA3QEAAFoCAAC6AgAACgMAAE0DAACHAwAA
+ugMAAOgDAAARBAAANwQAAFkEAAB6BAAAmAQAALQEAADOBAAA5wQAAP4EAAAVBQAAKgUAAD4FAABR
+BQAAZAUAAHUFAACGBQAAlwUAAKcFAAC2BQAAxQUAANMFAADhBQAA7gUAAPsFAAAIBgAAFAYAACAG
+AAArBgAANwYAAEIGAABMBgAAVwYAAGEGAABrBgAAdQYAAH4GAACIBgAAkQYAAJoGAACiBgAAqwYA
+ALQGAAC8BgAAxAYAAMwGAADUBgAA2wYAAOMGAADqBgAA8gYAAPkGAAAABwAABwcAAA4HAAAUBwAA
+GwcAACIHAAAoBwAALgcAADUHAAA7BwAAQQcAAEcHAABNBwAAUwcAAFgHAABeBwAAZAcAAGkHAABv
+BwAAdAcAAHkHAAB/BwAAhAcAAIkHAACOBwAAkwcAAJgHAACdBwAAogcAAKcHAACrBwAAsAcAALUH
+AAC5BwAAvgcAAMIHAADHBwAAywcAANAHAADUBwAA2AcAANwHAADhBwAA5QcAAOkHAADtBwAA8QcA
+APUHAAD5BwAA/QcAAAEIAAAFCAAACAgAAAwIAAAQCAAAFAgAABcIAAAbCAAAHwgAACIIAAAmCAAA
+KQgAAC0IAAAwCAAANAgAADcIAAA7CAAAPggAAEEIAABFCAAASAgAAEsIAABPCAAAUggAAFUIAABY
+CAAAWwgAAF8IAABiCAAAZQgAAGgIAABrCAAAbggAAHEIAAB0CAAAdwgAAHoIAAB9CAAAgAgAAIII
+AACFCAAAiAgAAIsIAACOCAAAkQgAAJMIAACWCAAAmQgAAAAAAAABAAAAAAAAAAcAAAAAAAAAAAAA
+AAAAAAAAAQIDBAQEBAQFBgcICAgICAkKCwwNAABuO2g7YjtcO246aDpiOlw6bjloOWI5XDluOGg4
+YjhcOG43aDdiN1w3biloKWIpXCluKGgoYihcKG4naCdiJ1wnbhloGWIZXBluGGgYYhhcGG4XaBdi
+F1wXbhZoFmIWXBZuFWgVYhVcFW4UaBRiFFwUbhNoE2ITXBNuEmgSYhJcEm4RaBFiEVwRbhBoEGIQ
+XBBuAmgCYgJcAm4BaAFiAVwBbgBoAGIAXABUAAAAbjtoO2I7XDtuOmg6YjpcOm45aDliOVw5bito
+K2IrXCtuKmgqYipcKm4paCliKVwpbihoKGIoXChuJ2gnYidcJ24maCZiJlwmbiVoJWIlXCVuJGgk
+YiRcJG4jaCNiI1wjbiJoImIiXCJuIWghYiFcIW4gaCBiIFwgbhJoEmISXBJuEWgRYhFcEW4QaBBi
+EFwQVxBSEE0QSRBuAWgBYgFcAW4AaABiAFwAVAAAAAAAAAAAAAAAHQAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAIMAAACSAAAAgwAAAJIAAADoAAAA9wAAAOgAAAD3AAAAAAAAAAkAAAAAAAAACgAA
+ADgAAABoAAAAdAAAAIAAAACMAAAAnQAAAAcAAAAAAAAABwAAAAcAAAAHAAAAAAAAAAAAAAAAAAAA
+AAAAAMREAQAIAAAAAwAAAExKgACgDIAAIA2AAKANgAAgDoAACg0RFAoNERQZGRkZCgoAAAAAAAAG
+BgYGCQkJCQAGAAAABQYHCA0ODxAVFhcYGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwUmpocJJqa
+mpqak5pugT81CYsrAAAAMgAAAI8AjACKAEMADwAgaDcAAAARAD46IBEAAAIlAAAMLwAAAi85OQAK
+JTy3R2+KAAcUJ2IuAAACABcAAAUQCiAwQAAABgYKABYOFhQAAAAMEBQYIAgEAAA8ODQwLCgkIBwY
+FBAMCAQACwcDADs3My8rJyMfGxcTDwsHAzExOjMzOjIzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAACIAAAAAAAAAHQAAAAAAAABvAAAAUAAAAPYAAABQAAAA9wAAAIAAAAD4
+AAAABQAAADMAAABzAAAANwAAAHQAAAA7AAAAAAAAADQAAAB0AAAAOAAAAHcAAAA8AAAAAwAAADEA
+AAAHAAAANQAAAAcAAAA5AAAAAAAAADIAAAB/AAAANgAAAH8AAAA6AAAAAAAAAB8AAAAAAAAAIAAA
+AAAAAAAhAAAAAAAAAAgAAAABAAAAcQAAABEAAADqAAAAqgAAAOsAAAAKAAAAagAAAAAAAAANAAAA
+eAAAAA4AAAAnAAAADwAAACAAAAAQAAAAAgAAAPMAAAAAAAAA9AAAAAAAAAD1AAAAAAAAAAAAAAAB
+AQEBAQEBAQICAgICAgICAwMDAwMDAwMBAgAAAAAAAAAAAAAEAAAABQAAAOEDDh7hAAAA4QMOHuEA
+AAAAAAAACgAAABEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADhAw4e4QAAABX2Y/aw9vz2RveQ99j3H/hl+Kn47fgv
++XD5sPnu+Sv6Z/qi+tz6FPtL+4H7tvvq+xz8Tfx9/Kv82fwF/TD9Wf2C/an9z/30/Rf+Of5a/nr+
+mP62/tL+7f4G/x7/Nf9L/2D/c/+F/5b/pv+0/8H/zf/Y/+H/6f/w//b/+v/9//////////3/+v/2
+//D/6f/h/9j/zf/B/7T/pv+W/4X/c/9g/0v/Nf8e/wb/7f7S/rb+mP56/lr+Of4X/vT9z/2p/YL9
+Wf0w/QX92fyr/H38Tfwc/Or7tvuB+0v7FPvc+qL6Z/or+u75sPlw+S/57fip+GX4H/jY95D3Rvf8
+9rD2Y/ZwuYO6lruqvL690r7nv/zAEcInwz3EU8VqxoDHl8ivycbK3sv2zA/OJ89A0FnRctKM06bU
+v9Xa1vTXDtkp2kTbX9x63Zbesd/N4OnhBeMh5D7lWuZ355PosOnN6urrB+0k7kLvX/B98ZryuPPV
+9PP1Efcv+Ez5avqI+6b8xP3i/gAAHgE8AloDeASWBbQG0QfvCA0KKwtIDGYNgw6hD74Q3BH5EhYU
+MxVQFm0XiRimGcIa3xv7HBceMx9PIGohhiKhI7wk1yXyJgwoJilBKlordCyOLacuwC/ZMPExCjMi
+NDo1UTZpN4A4ljmtOsM72TzvPQQ/GUAuQUJCVkNqRH1F////AP///wH/AgP///8EBf8J/wcKBggL
+AAEBAgECAgMBAQEBAQEBAQICAgICAgICAwMDAwMDAwMEBAQEBAQEBAECAgICAgIDAwMDAwMDAwMD
+AwMDAwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAADoBAgHVAN8A2gCiAHUAfwCKBSoDOQGoAYoF
+ygLZAEgBAQMPBwoUN25qARoB2QDoAAoBugB5AIgAygFKAeIA+QDKAeoAggCZAHTRRRfooosuAAUH
+AQMEAAUBBQAAAAUGAAIEAAUABQAAAQIBAgMEAAAFBgcICQoAAAkAAAAAAAAAAQAAAAIAAAADAAAA
+AAAAAAQAAAACAAAABQAAAAcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcH
+BwcHBwcHBwcHBwcHBwcHBwYGBgYGBQUFBQUEBAQEBAMDAwMDAgICAgIBAQEBAQAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoACgAMAAsACwAKAA8
+ADQAQAA8AIwAbABYAEgA9ACwAH//Bw8fPwEDMAAAADYAAAAMAAAAEgAAABgAAAAkAAAABgAAAAkA
+AAAFAAcCAwQGBkADgAbACQANgBMAGkAdgCCABgANgBMAGgAnADSAOgBBwAmAE0AdACeAOgBOwFeA
+YZkDMwfZCnMOphXmHIAgGSQzB3MOphXmHFkrzDkAQTNI2QqmFYAgWSsAQaZWgGFZbJ3YiZ1O7MRO
+NEiDNCd2YicapEEaEzuxExEYgREP/MAPTuzETid2YicapEEaEzuxEw3SIA2JndgJCIzACAd+4Ac0
+SIM0GqRBGhEYgREN0iANCIzACAZpkAawstUFBVRABSd2YicTO7ETDdIgDYmd2AkGaZAGxE7sBARG
+YAQDP/ADqqqqqhqkQRoTO7ETD/zADxEYgREN0iANCqiAChM7sRMP/MAPD/zADw3SIA0LtEALC7RA
+C4md2AkN0iANCqiACgqogAoIjMAIB3iABwd4gAcGaZAGD/zADw3SIA0LtEALDdIgDQu0QAuJndgJ
+CIzACImd2AkIjMAIB37gBwd+4AfBLCkHCqiACgiMwAgHeIAHCIzACAd4gAcGaZAGsLLVBQZpkAaw
+stUFBVRABQVUQAXWHcYEAQcPHz9///9m5gAABQYBAgMEAABUAFQAbABgAFwAVACMAHgADQ8FBwkL
+AQMoACgANAAwACwALABEADwALAAsADwANAAwACwAVABEAFVVVQFLaC8BVVVVBeM4jgOqqqoCcRzH
+AaqqqgrHcRwHAAQAAGQAAAAAAAAADwA/AAEAAAAPAD8AAQAAAA8APwABAAAADwA/AAEAAAAPAD8A
+AQAAAA8APwABAAAADwA/AAIAAAAPAD8AAQAAACIWAACAAAADAAABWQAAJBYAAQAAAAMAAAFaAAAm
+FgACAAAABAAAAVoAACgWAAIAAAADAAABWwAAKhYAAoAAAAMAAAFcAAAsFwAAAAAABAAAAVwAAC4X
+AACAAAADAAABXQAAMBcAAQAAAAMAAAFeAAA0FwACAAAAAwAAAV8AADYXAAKAAAADAAABYAAAOBgA
+AAAAAAQAAAFgAAA8GAABAAAAAwAAAWIAAD4YAAIAAAAEAAABYgAAQBgAAgAAAAMAAAFjAABkGwAC
+AAAAAwAAAW8AAWYbAAKAAAADAAABcAABaBwAAAAAAAQAAAFwAAFsHAABAAAAAwAAAXIAAW4cAAIA
+AAAEAAABcgABcBwAAgAAAAMAAAFzAAJ0HQAAAAAABAAAAXQAAnYdAACAAAADAAABdQACeB0AAQAA
+AAMAAAF2AAJ8HQACAAAAAwAAAXcAA34dAAKAAAADAAABeAADgB4AAAAAAAQAAAF4AAOEHgABAAAA
+AwAAAXoAA4YeAAIAAAAEAAABegAEiB4AAgAAAAMAAAF7AASMHwAAAAAABAAAAXwABJEfAAFAAAAD
+AAABfgAElR8AAwAAAAQAAAF/AAWXHwACwAAAAwAAAYAABZkgAABAAAADAAABgQAFnSAAAUAAAAMA
+AAGCAAWfIAABwAAAAwAAAYMABaEgAAMAAAAEAAABgwAFpSEAAEAAAAMAAAGFAAVoXAEAAAAAAGhc
+AQAAAAAAaFwBAAAAAABoXAEAAAAAAGhcAQAAAAAAaFwBAAAAAABoXAEAAAAAAGhcAQAAAAAAZFYB
+ABgAAAAoWAEAIAAAAIhdAQAUAAAAfF4BABQAAADUWwEADgAAAKhaAQAOAAAAqFsBABQAAACoWwEA
+FAAAAEAjQCUhISEhQEBAQEAFBAQBAUBAQEAFBUBADAxADQwMAQEBBUBABQUABAAEQEAABEBAQAVA
+QEBAQAVAQEAFBQUBAQEBQAUFBQEFAQFABQUFQAVABQUFBQUAAAAAAAAAAGQAAAAAkAEACgAAAAQA
+AAAcEQAAHDIAABwzAAAEAAAAHBUAABwCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAClxoT4me6N9g3/vdax3lSR
+UGADAqnOfVYZ52K15k2a7EWPnR9AiYf6Fe/rssmOC/vsQWez/V/qRb8j91OW5FubwnUc4a49akxa
+bEF+AvVPg1xo9FE00Qj5k+Jzq1NiPyoMCFKVZUZenSgwoTcPCrUvCQ42JJsbPd8mzWlOzX+f6hsS
+nh10WC40LTay3O60+1v2pE12YbfOfXtSPt1xXpcT9aZouQAALMFgQB/jyHnttr7URo3ZZ0ty3pTU
+mOiwSoVruyrF5U8W7cWG15pVZpQRz4oQ6QYEgf7woER4uiXjS/Oi/l3AgIoFrT+8IUhwBPHfY8F3
+da9jQjAgGuUO/W2/TIEUGDUmL8PhvqI1zIg5LleT8lWC/Ed6rMjnuisyleagwJgZ0Z5/o2ZEflSr
+O4MLyowpx9NrPCh5p+K8HRZ2rTvbVmROdB4U25IKDGxI5Lhdn26970OmxKg5pDE304vyMtVDi1lu
+t9qMAWSx0pzgSbTY+qwH8yXPr8qO9OlHGBDVb4jwb0pyXCQ48VfHc1GXI8t8oZzoIT7dltxhhg2F
+D5DgQnzEcarM2JAFBgH3Ehyjwl9q+a7QaZEXWJknOrknONkT67MrMyK70nCpiQenM7YtIjySFSDJ
+SYf/qnhQeqWPA/hZgAkXGtplMdfGhLjQw4KwKXdaER7Le/yo1m06LAABAgQEAAAABAwMCAQMBARA
+AAAAgAAAAAABAAAAAgAAQAAAAAAEAABAAAAAQAAAAADwYQAAAQECAQICAwAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAGQAAAAqAAAADgAAAAAAAQEAAAAAAAAAAAABAQAAAAACAAEAAgIDAwMAtQEA
+DLUBABi1AQAktQEALLUBADS1AQABAQABAgEBAQAAAAAAAAAA/////wAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA0AAAAgAACADQAAgA0AAAAgAACADQAAAAYAAAAE
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAEAAAALAEAAAcA
+AAAAAAAAEgAAAAQAAAALAAAACAAAAAQAAADYU4AACQAAAAQAAAAcAAAACgAAAAQAAABEU4AACwAA
+AAQAAAAsR4AADAAAAAQAAAAcAAAADQAAAAQAAACYRoAADgAAAAAAAAAPAAAABAAAABYAAAA=
+====
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/ral/LICENSE.orig
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/contrib/dev/ral/LICENSE.orig Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,16 @@
+$FreeBSD$
+
+Copyright (c) 2005-2008, Ralink Technology Corp.
+ Paul Lin <paul_lin at ralinktech.com.tw>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/ral/rt2561.fw.uu.orig
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/contrib/dev/ral/rt2561.fw.uu.orig Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,202 @@
+# $FreeBSD$
+#
+# Copyright (c) 2005-2008, Ralink Technology Corp.
+# Paul Lin <paul_lin at ralinktech.com.tw>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+begin 644 rt2561.fw
+M`AP2`A/+PHPB(@`"%@_"K\*-=8R4=8J3TJ\B`AC:$AOH0`,"`AZ0(0+@]2V0
+M``/@$@@E`+```,X!`%X0`&\1`/(@`4TA`7`B`80P`8\Q`=50`9]1`?)2`@9@
+M```"%)``"N`@Y0,P!P/2""(2%Z4BD"$`X/41Y1'$,U3@)"'U at N0T(?6#X$2`
+M\.41Q#-4X"0L]8+D-"'U@^41\,0S5.`D+?6"Y#0A]8/E+?#DD"$#\"(2$3&0
+M(0#@]3%@!1(;BH`#$AL]Y)`A`_"O+1(<8B)U,?^0`0#@5/?PD`$!X%3^\%0^
+M\.20``OP\)`A`_"O+1(<8B)^*W^`?0,2!`Z0-,W@(./YD"$4$@@!D#3`$@@-
+MD"$8$@@!D#3($@@-D"$<$@@!D#3$$@@-D#3,=`'PH^!$!/"0`0'@1`'P1$#P
+MD``+X$00\.20(0/PKRT2'&(BD`$`X%3W\)`!`>!4_O!4O_"0``O at 5._PY)`A
+M`_"O+1(<8B)^*W^`?0,2!`[DD"$#\*\M$AQB(M(%A2TCY)`A`_`B$AITP@#D
+MD"$#\*\M$AQB(H4M)9``"^!4^__PY)``!_"0``IT!/#DD``(\)`A`."0``GP
+MD``'=''P[T0$D``+\.20(0/P(I`A`.#_5!_U,*/@]2>/)A((D.20(0/PKRT2
+M'&(BD"$`X/4L$A at 3Y)`A`_"O+1(<8B(2&5/DD"$#\*\M$AQB(N20(0/PKRT2
+M'&(BCA6/%LKMRLGKR3`*!']*@`)_0LOOR^K#E`10`H`!PT`$RT0 at RX46@H45
+M@^OPH^3PA1:"A16#HZ/E&O#E&846 at H45@Z.CH_#E%B0$]8+D-17U at W0/\.46
+M)`7U at N0U%?6#Y/#E%B0&]8+D-17U@^3PY18D!_6"Y#45]8-T$/#JD!J<D_OJ
+M9`%@".ID`F`#N@,$RT0(R^46)`CU at N0U%?6#Z_#E%B05]8+D-17U at W3_\.46
+M)!;U at N0U%?6#Z?#E%B0)]8+D-17U at W0$\"4:]1KD-1GU&>K#E`1``P(#UNI@
+M`[H!'^HD`?WD,_SE&JX9>`/#,\XSSMCY_Q('EHX9CQH"`[;J)/_]Y#3__'X`
+M?PL2!X3,[LS-[\WE&L3X5`_(:/_E&<14\$C^$@>6C!N-'.HD__WD-/_\?@!_
+M"Q('A,SNS,WOS>4:Q/A4#\AH_^49Q%3P2/X2!Y:.&8\:Y1Q%&V`(!1KE&G`"
+M!1GJ)/_]Y#3__'X`?P,2!X33Y1R?Y1N>4!CE'$4;8!*Z`P_E%B0)]8+D-17U
+M@^!$@/#E%B0*]8+D-17U@^4:\.49_^46)`OU at N0U%?6#[_"`+>4:5#__Y18D
+M"O6"Y#45]8/O\.4:KAEX!L[#$\X3V/G_Y18D"_6"Y#45]8/O\(46 at H45@^!$
+M`?`BCA*/$XT4Y12BX9()Y30D&?6"Y#4S]8/@_>4T)!KU at N0U,_6#X/NB"9(*
+M=1D`=1H:$@(?,`D$?\B``G_HY1,D&/6"Y#42]8/O\.4Q8`1_`H`"?P'E$R09
+M]8+D-1+U@^_PY30D&?6"Y#4S]8/@_WT:?``2#F3E$R0:]8+D-1+U@^_PY1,D
+M&_6"Y#42]8/N\.4Q8&#E$R0<_^0U$O[E-"02_>0U,_QU&Q%[!A(4J^43)"+_
+MY#42_GPP?1!U&Q%[!A(4J^43)"C_Y#42_GPP?0AU&Q%[!A(4J^4T)!CU at N0U
+M,_6#X/_E$R0M]8+D-1+U@^_P@#_E$R0<_^0U$OY\,'T0=1L1>P82%*OE$R0B
+M_^0U$OY\,'T(=1L1>P82%*OE$R0H_^0U$OY\,'T0=1L1>P82%*OE$R0N]8+D
+M-1+U@^3PY1,D+_6"Y#42]8/D\.4T)!'U at N0U,_6#X/_#$__E$R0P]8+D-1+U
+M@^_P,`E!Y1,D,/6"Y#42]8/@_^4Q8`1^`(`"?A#O3O#E,6`&?@!_`(`/Y10P
+MX`9^`'__@`1^`'\`Y1,D,?6"Y#42]8/O\"+E$R0P]8+D-1+U@^!$0/#E%##@
+M#^4T)!#U at N0U,_6#X/^``G\`Y1,D,?6"Y#42]8/O\"+E-"01]8+D-3/U@^`P
+MYSOE-"0<]8+D-3/U@^!E*W`#=2O_Y30D'?6"Y#4S]8/@_Q(<8GXB?Q`2&'R.
+M,X\TD"(NX/ZCX(XS]33#(M(*Y30D&_6"Y#4S]8/@<#J%-(*%,X/`@\""X/ZC
+MX/^%-(*%,X.CH^#\H^#]P^^=_^Z<_M""T(/PH^_PTY0`[F2`E(!0`P(')X#&
+MA32"A3.#X/ZCX,/N9("4@%`#`@<G$AQ!A32"A3.#X/RCX/W#G^YD@/CL9("8
+M0""%-(*%,X/`@\""HZ/@_J/@_^V?_^R>T(+0 at _"C[_#""H4T at H4S@^#^H^#_
+MY30D$/6"Y#4S]8/@_</OG?WNE`#\$A9:4"R%-(*%,X/`@\""X/ZCX/^%-(*%
+M,X.CH^#\H^#]P^^=_^Z<T(+0 at _"C[_#""B`*`P(&-WXB?Q`2&'R.,X\TCX*.
+M@^#^H^#3E`#N9("4@$`-?B)_$*TTK#,2%0Z`&A(;JX4T at H4S@^Z/\!('ZWXB
+M?S"M-*PS$A4.D"(NX/ZCX/]E-'`#[F4S<`+3(HXSCS3#(N^-\*2H\,^,\*0H
+MSHWPI"[^(KP`"[X`*>^-\(3_K?`BY,SX=?`([R__[C/^[#/\[IWLF$`%_.Z=
+M_ at _5\.GDSOTB[?CU\.Z$(-(<_JWP=?`([R__[3/]0`>84`;5\/(BPYC]#]7P
+MZB+%\/BCX"CPQ?#XY8(5 at G`"%8/@./`BX/RCX/VCX/ZCX/\B[/"C[?"C[O"C
+M[_`BI"6"]8+E\#6#]8,BT(/0 at OCDDW`2=`&3<`VCHY/X=`&3]8*(@^1S=`*3
+M:&#OHZ.C at -^*@XF"Y'/D_Y`PC.3P[Y`;49-$@)`PC?"C=`'PH^3PD#",X/YT
+M-B_XQN[&H^#^[Y`;49-$@&Y@`1\/[\.4"4#((@````#E,!(()0BQ``D?`0F'
+M`@H;`PIO!`JV!0LI!@N8!P``"]#"`1(`!I`P.N#U$N4F(.4(D#28X%3^\"*0
+M-)C at 1`'PY28PY at _E)S#F!5,2_8`20Q("@`WE)S#F!4,2`H`#4Q+]Y28PYP_E
+M)S#G!5,2]X`20Q((@`WE)S#G!4,2"(`#4Q+W0Q(!0Q($D#`ZY1+P(L(!$@`&
+MD#`ZX/42Y28 at Y0B0-)C at 5/[P(I`TF.!$`?#E)E3`8!SE)S#F!5,2_8`#0Q("
+MY2<PYP53$O>`'T,2"(`:Y2<PY at 5#$@*``U,2_>4G,.<%0Q((@`-3$O=#$@%#
+M$@20,#KE$O`BP@$2``:0,#K@]1)#$@%#$@3E)C#E7)`TF.!$`?#E)E3`8!SE
+M)S#F!5,2_8`#0Q("Y2<PYP53$O>`,$,2"(`KY2<PY at 5#$@*``U,2_>4G,.<%
+M0Q((@`-3$O?E)_14'_^0,#3 at 5.!/\.3U+)`P.N42\(`5D#28X%3^\.4G]%0?
+M_Y`P-.!4X$_PD#`UX/424Q+ at Y1+P(L(!$@`&D#`ZX/42Y28PY3R0-)C at 1`'P
+MY2<PY at 53$OV``T,2`N4G,.<%4Q+W@`-#$@CE)E3`8`A#$@%#$@2`!E,2_D,2
+M!)`P.N42\"*0-)C at 5/[P(L(!$@`&D#`ZX/42Y2<PY at 5#$@*``U,2_>4G,.<%
+M0Q((@`-3$O?E)E3`8`A3$OY3$ON`!D,2`4,2!)`TF.!$`?"0,#KE$O`B(`(3
+M$AP>KRE^`!(<=*\U?@`2''O2`I`P.N#U$N4F(.4-P@$2``:0-)C at 5/[P(I`T
+MF.!$`?#E)E3`8"S"`1(`!N4G,.8%4Q+]@`-#$@+E)S#G!5,2]X`#0Q((0Q(!
+M0Q($D#`ZY1+P(C`!`P(+T!(5P-(!(L(!$@`&Y28 at Y0F0-)C at 5/[P@%60-)C@
+M1`'PY28PY at _E)S#F!5,2_8`20Q("@`WE)S#F!4,2`H`#4Q+]Y28PYP_E)S#G
+M!5,2]X`20Q((@`WE)S#G!4,2"(`#4Q+W0Q(!4Q+[D#`ZY1+PD#`ZX/42(N4F
+M,.4L(`,AT@,2'!YU-09U*0FO*7X`$AQTD#`ZX/424Q+^0Q($Y1+PD#28X$0!
+M\"*0-)C at 5/[P(N4Q9`%P01(:U$`#`@U/$AME4"!^*W^`?0,2!`Y_`1(9>$`)
+MT at D2#^[D]2\B$@U0=2\!(G\!$AEX4`1U+P(BT at D2#^[D]2\B$AH=4%$2&\N0
+M,/3@]2I^,'_LH^#]Y/L2&2OD__X2'#:0``IT`O"0``O at 1`+_\/V0`05T(/"0
+M`0;@1"#P[52_D``+\)`TS.!$`?"CX$0!\*/@1`'PT at 02&CI00Q(:5WXP?^!\
+M,'WL=1L1>P82%*N0,/7@=?`@I/^N\!(<-I``"^!4_?_P_>20``3PD`$&X%3?
+M\)``"G1`\$V0``OPP at 02&OY0.!(:5WXP?^!\''V"=1L2>P82%*N0``1T`O"0
+M``KPY/_^$APVD``+X%3]\.20``3PD`$&X%3?\,($$ALH4"42&E=_`A(9>)`!
+M!.!4?_"0``O at 5/W_\.20``3P[U2_D``+\,($$AK44"T2&E=^,'_@?!Q]@G4;
+M$GL&$A2KD``$=`+PD``*\)`!!N!4W_"0``O at 5+_PP@0BD#3-X/D at X_CE*_1@
+M9I`TP!((`84T at H4S@W7P(.4K$@@9Y8(D!/6"Y#6#]8,2"`V0-, at 2"`&%-(*%
+M,X-U\"#E*Q((&>6")`CU at N0U@_6#$@@-D#30$@@!A32"A3.#=?`@Y2L2"!GE
+M at B0,]8+D-8/U at Q((#>4T)/#_Y3,TWO[O>`7.PQ/.$]CY]2N%-(*%,X-U\"`2
+M"!GE at B0$]8+D-8/U at Q((`9`TP!((#84T at H4S@W7P(.4K$@@9Y8(D"/6"Y#6#
+M]8,2"`&0-, at 2"`V%-(*%,X-U\"#E*Q((&>6")`SU at N0U@_6#$@@!D#3$$@@-
+MD`$!X$1`\)`!`.!$"/#I1`20-,WPD#3,X$0!\*/@1`'PH^!$`?`BCQ6,%HT7
+MY17#E`105N45E`!`!GH`>V"`!'H`>\#E%\3X5`_(:/_E%L14\$C^Y160&HZ3
+M_7P`$@>6[RO[[CKZY1?$^%0/R&C_Y1;$5/!(_N45D_U\`!('ENU,8&,+NP`!
+M"H!<>@![&N47KA9X`L,SSC/.V/DD"__D/O[E%9`:CI/]?``2!Y;O>`+#,\XS
+MSMCY*_ON.OKE%ZX6>`+#,\XSSMCY)`O_Y#[^Y160&HZ3_7P`$@>6[4Q@!W0$
+M*_OD.OK/Z\_.ZLXBY2X48!T48#T48%T4<`,"#]<D!&`#`@_M(`T#`@_M=2X!
+M(I``"N#_,.4#1"#PY4!%/V`#`@_M=2X"$AF;$AMXKR at 2&J at BD`$#X/\PYW;O
+M1("0`0/P$@A1$AG>$AN[=2X#KR)^`!(<*B+E0$4_<"$2%$$2&W at 2&;X2&[L2
+M'`0P#0MU+@&O,GX`$APJ(N3U+B*0``K at _S#E+$0@\!(401(;>!(9OA(;NQ(<
+M!'4N!"+E0$4_<!`P#0IU+@&O,OX2'"HBY/4N(I``!'0"\)``"O`P"3+E-$4S
+M<`+#(H4T at H4S@\"#P(+ at _J/@_X4T at H4S@Z.CX/RCX/W#[YW_[IS0 at M"#\*/O
+M\.4T13-P`L,B$@7M4/.0``K@(.4#,`=!Y31%,W`"PR*%-(*%,X/`@\""X/ZC
+MX/^%-(*%,X.CH^#\H^#]P^^=_^Z<T(+0 at _"C[_#E-$4S<`+#(A(%[5#S at +6%
+M-(*%,X/@_J/@_Q(6ZM,B$AK^0`42&M101'XP?^!\''V"=1L2>P82%*N0``1T
+M`O"0``KPY/_^$APVD``+X%2_\%1___#DD##I\.]4_9``"_#DD``$\-()$@_N
+MY/4O$AL34$A^,'_@?!Q]@G4;$GL&$A2KD``$=`+PD``*\.3__A(<-I``"^!4
+MO_!4_?#DD``$\/\2&7A0!'4O!R*0`03 at 5'_PT at D2#^[D]2\BPJ_D]2_UB'6H
+M#W6)$?6X]>AUD`]U,?]U*_^0(B[PH_"0(D[PH_#"!<((P@#"!\($D``*=/_P
+MD``+=`'PD`$#=/_PY)`!!/"0`05T__#DD`$&\)``!/"0,.AT$/"0`0?PD`$(
+M!/"0`0ET2/"0`0IT?_"0`0)T'_"0`0!T%/"0`0%T(/"0``#@1(#P=4D`=4H!
+MP@'2KR(2&M10+1(82)`!!N!4W_!^,'_@?!Q]@G4;$GL&$A2KD``$=`+PD``*
+M\-()$@_NY/4O(A(;*%!0$AA(D``+X%3]\.20``3PD`$#=(#PD`$$X$2`\'\"
+M$AEX4`1U+P4B?C!_X'P<?8)U&Q)[!A(4JY``!'0"\)``"O#2"1(/[I`!!.!4
+M?_#D]2\BD#`P=`+P=1$'=1+0D#`PX##@#N42%1)P`A41Y1)%$7#KY1)%$7`2
+M$AITD"$`X&`'D#28X$0$\,,BY)`T6/"0-#)T'_!U$0=U$M"0-('@9`-@#N42
+M%1)P`A41Y1)%$7#JY1)%$7`2$AITD"$`X&`'D#28X$0$\,,BD#28X$0$\.20
+M``'PTR*0,#K@]1`2'%=0)N4G,.8%4Q#]@`-#$`+E)S#G!5,0]X`#0Q`(4Q#^
+M0Q`$D#`ZY1#P$AQ,4$B0`0/@]1!4'&`^Y1!4X_"CX/40\.4G,.8%0Q`"@`-3
+M$/WE)S#G!4,0"(`#4Q#W4Q#^0Q`$D#`ZY1#PKRE^`!(<=*\U?@`2''LB$AJ_
+M4'(2'$&%-(*%,X/@_*/@PY_U$NR>]1'3Y1*4`.419("4@$`&KA&O$H`$?@!_
+M`(X1CQ+E-"00]8+D-3/U@^##E1+U$N25$?41PV2`E(!0!>3U$?42Y30D$O_D
+M-3/^K1)[`1(9*Y`!!70@\)`!!N!$(/!U+P,BP.#`\,"#P(+`T'70",*OD"(N
+MX/ZCX(XS]33E+R7@))OU at N0T&_6#Y)/^=`&3RN[*^1((2Q(;]E`"T@<2%RP2
+M`!X2&NE0!:\E$AQB,`4;Y2]P%R`$%!(23I(`P at 72"Z(`Y#/U%*\C$A:BTJ_0
+MT-""T(/0\-#@,I`IH.!P8Y`PC.3PHW3"\*-T`?"CY/"0,(S at _Y`IH/"0,(SD
+M\*-TQ?"C=`'PH^3PD#",X/^0*:'PD#",Y/"C=,3PHW0!\*/D\)`PC.#_D"FB
+M\)`PC.3PHW3#\*-T`?"CY/"0,(S at D"FC\"*.%H\7C!B-&>3_[\.;4%/E&S#@
+M$N]\`"49_>PU&(V"]8/@]1R`'^4;,.$3[WP`)1G][#48C8+U@^23]1R`!^49
+M+_CF]1SE&S#D#^47+_6"Y#46]8/E'/"`!N47+_BF'`^`J"*,$XT4[R0>]8+D
+M/O6#X/RCX$Q at 0>\D'O6"Y#[U@^#\H^#U at HR#X/RCX/V%%(*%$X/@^J/@^]/M
+MF^ID@/CL9("80!/O)![U at N0^]8/@_*/@SNS._X"OK12L$Q(8KR(2&K]03^4T
+M)!+_Y#4S_N4T)!#U at N0U,_6#X/WD^Q(9*^4T)!#U at N0U,_6#X/]^`!(<-I``
+M"G1`\)``"^!$0/_PD``*=(#P3Y``"_"0,.ET`?!U+P8BD#`ZX/_E)S#F$C`,
+M!N]4]?Z`!.]$"O[/[L^`$#`,!N]$"OZ`!.]4]?[/[L_/5/[/ST0$SY`P.N_P
+M,`P)?PA^`!(<=(`'?R)^`1(<=+(,(L#@P/#`@\""P-!UT`C"K\*,PHW3Y4J4
+M`.5)E`!`".5*%4IP`A5)T^5,E`#E2Y0`0`CE3!5,<`(52Q(`#M*,TJ_0T-""
+MT(/0\-#@,L/OE`3N9("4@$`,T^V4!.QD@)2`4`$BP^^4_.YD@)1_0`S3[93\
+M[&2`E']0`2+3[Y0$[F2`E(!0#</ME/SL9("4?T`"TR+#(N3^[_1 at 070$+O6"
+MY#0A]8/@M/\C=`0N]8+D-"'U@^_P,`L-=`@N]8+D-"'U@^44\)```G0!\"*^
+M`PJ0``)T`?#D_H#"#H"_(HX3CQ02'$'#[Y44_^Z5$\WOS?S3[90`[&2`E(!`
+M!<[LSH`$?@!_`<SNS.R0``7PD``&[_"0``1T4?"0``O at 1`+P(C`'/.4O<#C"
+M!Y`B+N#^H^".$?42D").X/ZCX/^0(B[N\*/O\)`B3N41\*/E$O".,X\T,`@%
+M$A>EP at C""1(/[B)_@'XIY/W\CX*.@^#[=$4M^,;KQG0$+_6"Y#[U@^#[=$$M
+M^,;KQG0(+__D/OX-O0`!#.UD!$QPSR*0(0#@Q#-4X"00]8+D-"&K at OH2&ZN+
+M at HJ#[H_P$@?K?B)_,,WKS<SJS!(5#N20(0/PKRT2'&(BD```=`[P````Y/`2
+M$3$2'(B0-)C at 1`'PY3"T!0H2'$Q0#1(5P(`(Y3"T!P,2$M02#RJ`Y(#^(N3_
+MY3`D_G`LY/[NPY4L4!)T`<CNR`B``L,SV/S/3\\. at .B0,#3 at 5.#^Y2=4'V_T
+MSD[.[O`BD#3.X$0"\)`TS>!4_O"0-,W@(./YD`$1X%0B_[\B`].``<-0\)`!
+M`.!4]_"0`0'@5+_P(N\D'O6"Y#[U@^#\H^#[RNS*)![U at N0\]8/@_*/@_>\D
+M'O6"Y#[U@^SPH^WPSNK.S^O/(N\D'O6"Y#[U@^#ZH^#[[20>]8+D//6#ZO"C
+MZ_#O)![U at N0^]8/L\*/M\"+`X,#0PJ_"CL*/T^5`E`#E/Y0`0`WE0!5`<`(5
+M/Q(<:]*.TJ_0T-#@,A(:OU`B?C!_X'P<?8)U&Q)[!A(4JY``!'0"\)``"O#2
+M"1(/[N3U+R*.$X\4C17K8`D4<!NO%1(9_B)^,'_ at K!.M%'4;$7L&$A2KKQ42
+M&?XB$A=LD"$!X/4H=$$E*/CF]3)T124H^.;U(I`A`.!@`](-(L(-(LWOS9`!
+M`N`PYP+#(GXJ?P`2!`Z0`03 at 1(#PD`$"X$2`\-,BD#0PY/"C\*-T'_"CY/"0
+M`1#@(.$#`(#VD`$2X"#A`P"`]B+D_W0V+_CFD#",\.^0&U&3D#"-\*-T`?"C
+MY/`/OPGC(N3_[Y`;6Y.0,(SP[Y`;49.0,(WPHW0!\*/D\`^_">,BY)``!?#O
+M8`*``G\!D``&[_"0``1T4?"0``O at 1`+P(I`P\.#U*I``"N`PY`Z0,/+ at 8`B0
+M``IT$/#3(L,BD##PX/4JD``*X##D#I`P\N!P")``"G00\-,BPR*0-,[@1`+P
+MD#3-X%3^\)`!`.!4]_"0`0'@5+_P(I```70.\)`TF.!4^_"0-%AT`?"0,#!T
+M!/`B`@0+%@P2&"0P2&!LD,@``0(#"P\*#@D-"`SOQ#,S5,#_D`$`X%0_3_"0
+M`0+ at 1(#P(I`!`^`PYPQT@/"0`03 at 5'_PTR+#(I``"N`PX0QT`O"0``O at 5/WP
+MTR+#(I``"N`PX at QT!/"0``O at 5/OPTR+#(I``"N`PY at QT0/"0``O at 5+_PTR+#
+M(I``"N`PYPQT@/"0``O at 5'_PTR+#(I`!!>`PY0QT(/"0`0;@5-_PTR+#(N3U
+M,9``"G3_\)`B+G0A\*-T$/`B4E-4$A46$!%``"``0/\_/[TH(0#E-"01]8+D
+M-3/U@^`PY at +3(L,BD#!`=#+PHW2P\*-T`?"CY/`B=3$!D``*=/_PD``+X$0@
+M\"(+T1-3%6L1Q@`)&0,0E1O:D#!DX/VCX/[M)>#_[C/^(I`P0'0R\*-TL/"C
+MY/"C\"*0`0#@1`CPD`$!X$1`\"(2&K]0"-()$@_NY/4O(I``"N`PX`5T`?#3
+M(L,BD``*X##E!70@\-,BPR*0-#!T'_"CY/"C\*/P(GA_Y/;8_76!3`(7W,*O
+MPHS"C1(`#M*O(L*.CC^/0!(<:]*.(I`P/._P[D2`H_`BD#!XX/VCX/[M_R+E
+M2D5)<`/3@`'#(N5,14MP`].``<,BP at OD]102%J(BPH]UC?5UBT$BCDF/2M*,
+M(HY+CTS2C"(```````#"#>3U+B(`````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```````````````````````````````````````````````````````````(
+"K#``
+`
+end
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/ral/rt2561s.fw.uu.orig
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/contrib/dev/ral/rt2561s.fw.uu.orig Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,202 @@
+# $FreeBSD$
+#
+# Copyright (c) 2005-2008, Ralink Technology Corp.
+# Paul Lin <paul_lin at ralinktech.com.tw>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+begin 644 rt2561s.fw
+M`APM`@??PHPB(@`"&4/"K\*-=8R4=8J3TJ\B`AJ<$@C?0`,"`AZ0(0+@]2V0
+M``/@$@0_`+```,X!`%X0`&\1`/(@`4TA`7`B`80P`8\Q`=50`9]1`?)2`@9@
+M```"%)``"N`@Y0,P!P/2""(2%"LBD"$`X/41Y1'$,U3@)"'U at N0T(?6#X$2`
+M\.41Q#-4X"0L]8+D-"'U@^41\,0S5.`D+?6"Y#0A]8/E+?#DD"$#\"(2!<N0
+M(0#@]3%@!1(;X(`#$ANFY)`A`_"O+1(0Z")U,?^0`0#@5/?PD`$!X%3^\%0^
+M\.20``OP\)`A`_"O+1(0Z")^*W^`?0,2"ON0-,W@(./YD"$4$@0;D#3`$@0G
+MD"$8$@0;D#3($@0GD"$<$@0;D#3$$@0GD#3,=`'PH^!$!/"0`0'@1`'P1$#P
+MD``+X$00\.20(0/PKRT2$. at BD`$`X%3W\)`!`>!4_O!4O_"0``O at 5._PY)`A
+M`_"O+1(0Z")^*W^`?0,2"OODD"$#\*\M$A#H(M(%A2TCY)`A`_`B$A.NP@#D
+MD"$#\*\M$A#H(H4M)9``"^!4^__PY)``!_"0``IT!/#DD``(\)`A`."0``GP
+MD``'=''P[T0$D``+\.20(0/P(I`A`.#_5!_U,*/@]2>/)A(48N20(0/PKRT2
+M$. at BD"$`X/4L$A>CY)`A`_"O+1(0Z"(2&NWDD"$#\*\M$A#H(N20(0/PKRT2
+M$. at BY3%D`7!!$@CM0`,"`YT2#C10('XK?X!]`Q(*^W\!$@K80`G2"1(.1^3U
+M+R(2"61U+P$B?P$2"MA0!'4O`B+2"1(.1^3U+R(2")!041(*K)`P].#U*GXP
+M?^RCX/WD^Q(-H.3__A(.*9``"G0"\)``"^!$`O_P_9`!!70@\)`!!N!$(/#M
+M5+^0``OPD#3,X$0!\*/@1`'PH^!$`?#2!!((K5!#$@J[?C!_X'PP?>QU&Q%[
+M!A(3R)`P]>!U\""D_Z[P$@XID``+X%3]__#]Y)``!/"0`0;@5-_PD``*=$#P
+M39``"_#"!!())5`X$@J[?C!_X'P<?7YU&Q)[!A(3R)``!'0"\)``"O#D__X2
+M#BF0``O at 5/WPY)``!/"0`0;@5-_PP at 02"4]0)1(*NW\"$@K8D`$$X%1_\)``
+M"^!4_?_PY)``!/#O5+^0``OPP at 02".U0+1(*NWXP?^!\''U^=1L2>P82$\B0
+M``1T`O"0``KPD`$&X%3?\)``"^!4O_#"!"+OC?"DJ/#/C/"D*,Z-\*0N_B*\
+M``N^`"GOC?"$_ZWP(N3,^'7P".\O_^XS_NPS_.Z=[)A`!?SNG?X/U?#IY,[]
+M(NWX]?#NA"#2'/ZM\'7P".\O_^TS_4`'F%`&U?#R(L.8_0_5\.HBQ?#XH^`H
+M\,7P^.6"%8)P`A6#X#CP(N#\H^#]H^#^H^#_(NSPH^WPH^[PH^_P(J0E at O6"
+MY?`U at _6#(M"#T(+XY)-P$G0!DW`-HZ.3^'0!D_6"B(/D<W0"DVA@[Z.CHX#?
+MBH.)@N1SY2X48!T48#T48%T4<`,"!1 at D!&`#`@4N(`T#`@4N=2X!(I``"N#_
+M,.4#1"#PY4!%/V`#`@4N=2X"$AL2$AO.KR at 2&X\BD`$#X/\PYW;O1("0`0/P
+M$@A5$AM5$AP!=2X#KR)^`!(<12+E0$4_<"$2%]@2&\X2&S42'`$2'!\P#0MU
+M+@&O,GX`$AQ%(N3U+B*0``K at _S#E+$0@\!(7V!(;SA(;-1(<`1(<'W4N!"+E
+M0$4_<!`P#0IU+@&O,OX2'$4BY/4N(A())4`%$@CM4$1^,'_@?!Q]?G4;$GL&
+M$A/(D``$=`+PD``*\.3__A(.*9``"^!4O_!4?__PY)`PZ?#O5/V0``OPY)``
+M!/#2"1(.1^3U+Q().E!(?C!_X'P<?7YU&Q)[!A(3R)``!'0"\)``"O#D__X2
+M#BF0``O at 5+_P5/WPY)``!/#_$@K84`1U+P<BD`$$X%1_\-()$@Y'Y/4O(L*O
+MY/4O]8AUJ`]UB1'UN/7H=9`/=3'_=2O_D"(N\*/PD").\*/PP at 7"",(`P@?"
+M!)``"G3_\)``"W0!\)`!`W3_\.20`03PD`$%=/_PY)`!!O"0``3PD##H=!#P
+MD`$'\)`!"`3PD`$)=$CPD`$*='_PD`$"=!_PD`$`=!3PD`$!="#PD```X$2`
+M\'5)`'5*`<(!TJ\B$@CM4"T2"GB0`0;@5-_P?C!_X'P<?7YU&Q)[!A(3R)``
+M!'0"\)``"O#2"1(.1^3U+R(2"4]04!(*>)``"^!4_?#DD``$\)`!`W2`\)`!
+M!.!$@/!_`A(*V%`$=2\%(GXP?^!\''U^=1L2>P82$\B0``1T`O"0``KPT at D2
+M#D>0`03 at 5'_PY/4O(I`P.N#U$!(<7%`FY2<PY at 53$/V``T,0`N4G,.<%4Q#W
+M@`-#$`A3$/Y#$`20,#KE$/`2'%%02)`!`^#U$%0<8#[E$%3C\*/@]1#PY2<P
+MY at 5#$`*``U,0_>4G,.<%0Q`(@`-3$/=3$/Y#$`20,#KE$/"O*7X`$AQPKS5^
+M`!(<=R(2",I0<A(0S84T at H4S@^#\H^##G_42[)[U$=/E$I0`Y1%D@)2`0`:N
+M$:\2@`1^`'\`CA&/$N4T)!#U at N0U,_6#X,.5$O42Y)41]1'#9("4@%`%Y/41
+M]1+E-"02_^0U,_ZM$GL!$@V at D`$%="#PD`$&X$0@\'4O`R+`X,#PP(/`@L#0
+M==`(PJ^0(B[@_J/@CC/U-.4O)>`D\?6"Y#0;]8/DD_YT`9/*[LKY$@1E$@D7
+M4`+2!Q(9CA(`'A()`E`%KR42$. at P!1OE+W`7(`04$A,HD@#"!=(+H@#D,_44
+MKR,2$/'2K]#0T(+0@]#PT.`RY/^0,(SD\.^0&[J31("0,(WPHW0!\*/D\)`P
+MC.#^=#8O^,;NQJ/@_N^0&[J31(!N8`$?#^_#E`E`R"*0,/#@]2J0``K@,.0.
+MD##RX&`(D``*=!#PTR+#(I`P\.#U*I``"N`PY`Z0,/+@<`B0``IT$/#3(L,B
+MD`$#X##G#'2`\)`!!.!4?_#3(L,BD``*X##@!70!\-,BPR*0``K@,.$,=`+P
+MD``+X%3]\-,BPR*0``K@,.(,=`3PD``+X%3[\-,BPR*0``K@,.4%="#PTR+#
+M(I``"N`PY at QT0/"0``O at 5+_PTR+#(I``"N`PYPQT@/"0``O at 5'_PTR+#(I`!
+M!>`PY0QT(/"0`0;@5-_PTR+#(I`TS>#Y(./XY2OT8&:0-,`2!!N%-(*%,X-U
+M\"#E*Q($,^6")`3U at N0U@_6#$@0GD#3($@0;A32"A3.#=?`@Y2L2!#/E at B0(
+M]8+D-8/U at Q($)Y`TT!($&X4T at H4S@W7P(.4K$@0SY8(D#/6"Y#6#]8,2!"?E
+M-"3P_^4S--[^[W@%SL,3SA/8^?4KA32"A3.#=?`@$@0SY8(D!/6"Y#6#]8,2
+M!!N0-,`2!">%-(*%,X-U\"#E*Q($,^6")`CU at N0U@_6#$@0;D#3($@0GA32"
+MA3.#=?`@Y2L2!#/E at B0,]8+D-8/U at Q($&Y`TQ!($)Y`!`>!$0/"0`0#@1`CP
+MZ40$D#3-\)`TS.!$`?"CX$0!\*/@1`'P(I`TSN!$`O"0-,W at 5/[PD#3-X"#C
+M^9`!$>!4(O^_(@/3@`'#4/"0`0#@5/?PD`$!X%2_\"*0`0#@1`CPD`$!X$1`
+M\"*0-,[@1`+PD#3-X%3^\)`!`.!4]_"0`0'@5+_P(LWOS9`!`N`PYP+#(GXJ
+M?P`2"ON0`03 at 1(#PD`$"X$2`\-,BCA*/$XT4Y12BX9()Y30D&?6"Y#4S]8/@
+M_>4T)!KU at N0U,_6#X/NB"9(*=1D`=1H:$A$Y,`D$?\B``G_HY1,D&/6"Y#42
+M]8/O\.4Q8`1_`H`"?P'E$R09]8+D-1+U@^_PY30D&?6"Y#4S]8/@_WT:?``2
+M#-KE$R0:]8+D-1+U@^_PY1,D&_6"Y#42]8/N\.4Q8&#E$R0<_^0U$O[E-"02
+M_>0U,_QU&Q%[!A(3R.43)"+_Y#42_GPP?1!U&Q%[!A(3R.43)"C_Y#42_GPP
+M?0AU&Q%[!A(3R.4T)!CU at N0U,_6#X/_E$R0M]8+D-1+U@^_P@#_E$R0<_^0U
+M$OY\,'T0=1L1>P82$\CE$R0B_^0U$OY\,'T(=1L1>P82$\CE$R0H_^0U$OY\
+M,'T0=1L1>P82$\CE$R0N]8+D-1+U@^3PY1,D+_6"Y#42]8/D\.4T)!'U at N0U
+M,_6#X/_#$__E$R0P]8+D-1+U@^_P,`E!Y1,D,/6"Y#42]8/@_^4Q8`1^`(`"
+M?A#O3O#E,6`&?@!_`(`/Y10PX`9^`'__@`1^`'\`Y1,D,?6"Y#42]8/O\"+E
+M$R0P]8+D-1+U@^!$0/#E%##@#^4T)!#U at N0U,_6#X/^``G\`Y1,D,?6"Y#42
+M]8/O\"*/%8P6C1?E%<.4!%!6Y164`$`&>@![8(`$>@![P.47Q/A4#\AH_^46
+MQ%3P2/[E%9`;=9/]?``2`[#O*_ON.OKE%\3X5`_(:/_E%L14\$C^Y163_7P`
[email protected][4Q at 8PN[``$*@%QZ`'L:Y1>N%G@"PS/.,\[8^20+_^0^_N45D!MUD_U\
+M`!(#L.]X`L,SSC/.V/DK^^XZ^N47KA9X`L,SSC/.V/DD"__D/O[E%9`;=9/]
+M?``2`[#M3&`'=`0K^^0Z^L_KS\[JSB*.$X\4C17K8`D4<!NO%1(."B)^,'_@
+MK!.M%'4;$7L&$A/(KQ42#@HBCA./%!(0S</OE13_[I43S>_-_-/ME`#L9("4
+M@$`%SNS.@`1^`'\!S.[,[)``!?"0``;O\)``!'11\)``"^!$`O`BY)``!?#O
+M8`*``G\!D``&[_"0``1T4?"0``O at 1`+P(I`P/._P[D2`H_`BY30D$?6"Y#4S
+M]8/@,.8"TR+#(I``!'0"\)``"O`P"3+E-$4S<`+#(H4T at H4S@\"#P(+ at _J/@
+M_X4T at H4S@Z.CX/RCX/W#[YW_[IS0 at M"#\*/O\.4T13-P`L,B$@[N4/.0``K@
+M(.4#,`=!Y31%,W`"PR*%-(*%,X/`@\""X/ZCX/^%-(*%,X.CH^#\H^#]P^^=
+M_^Z<T(+0 at _"C[_#E-$4S<`+#(A(.[E#S at +6%-(*%,X/@_J/@_Q(-R-,BY30D
+M$?6"Y#4S]8/@,.<[Y30D'/6"Y#4S]8/@92MP`W4K_^4T)!WU at N0U,_6#X/\2
+M$.A^(G\0$AH^CC./-)`B+N#^H^".,_4TPR+2"N4T)!OU at N0U,_6#X'`ZA32"
+MA3.#P(/`@N#^H^#_A32"A3.#HZ/@_*/@_</OG?_NG/[0 at M"#\*/O\-.4`.YD
+M@)2`4`,"$"B`QH4T at H4S@^#^H^##[F2`E(!0`P(0*!(0S84T at H4S@^#\H^#]
+MPY_N9(#X[&2`F$`@A32"A3.#P(/`@J.CX/ZCX/_MG__LGM""T(/PH^_PP at J%
+M-(*%,X/@_J/@_^4T)!#U at N0U,_6#X/W#[YW][I0`_!(0A5`LA32"A3.#P(/`
+M at N#^H^#_A32"A3.#HZ/@_*/@_</OG?_NG-""T(/PH^_PP at H@"@,"#SA^(G\0
+M$AH^CC./-(^"CH/@_J/@TY0`[F2`E(!`#7XB?Q"M-*PS$AA"@!H2$-B%-(*%
+M,X/NC_`2!`5^(G\PK32L,Q(80I`B+N#^H^#_931P`^YE,W`"TR*.,X\TPR+#
+M[Y0$[F2`E(!`#-/ME`3L9("4@%`!(L/OE/SN9("4?T`,T^V4_.QD@)1_4`$B
+MT^^4!.YD@)2`4`W#[93\[&2`E']``M,BPR*0,'C at _:/@_NW_(I`P9.#]H^#^
+M[27 at _^XS_B+""^3U%!(0\2+D_N_T8$%T!"[U at N0T(?6#X+3_(W0$+O6"Y#0A
+M]8/O\#`+#70(+O6"Y#0A]8/E%/"0``)T`?`BO@,*D``"=`'PY/Z`P at Z`OR*.
+M%8\6RNW*R>O),`H$?TJ``G]"R^_+ZL.4!%`"@`'#0`3+1"#+A1:"A16#Z_"C
+MY/"%%H*%%8.CH^4:\.49A1:"A16#HZ.C\.46)`3U at N0U%?6#=`_PY18D!?6"
+MY#45]8/D\.46)`;U at N0U%?6#Y/#E%B0']8+D-17U at W00\.J0&X.3^^ID`6`(
+MZF0"8`.Z`P3+1`C+Y18D"/6"Y#45]8/K\.46)!7U at N0U%?6#=/_PY18D%O6"
+MY#45]8/I\.46)`GU at N0U%?6#=`3P)1KU&N0U&?49ZL.4!$`#`A+PZF`#N@$?
+MZB0!_>0S_.4:KAEX`\,SSC/.V/[email protected]/&@(2T.HD__WD-/_\?@!_"Q(#
+MGLSNS,WOS>4:Q/A4#\AH_^49Q%3P2/X2`[",&XT<ZB3__>0T__Q^`'\+$@.>
+MS.[,S>_-Y1K$^%0/R&C_Y1G$5/!(_A(#L(X9CQKE'$4;8`@%&N4:<`(%&>HD
+M__WD-/_\?@!_`Q(#GM/E')_E&YY0&.4<11M@$KH##^46)`GU at N0U%?6#X$2`
+M\.46)`KU at N0U%?6#Y1KPY1G_Y18D"_6"Y#45]8/O\(`MY1I4/__E%B0*]8+D
+M-17U@^_PY1JN&7@&SL,3SA/8^?_E%B0+]8+D-17U@^_PA1:"A16#X$0!\"*0
+M,#!T`O!U$0=U$M"0,##@,.`.Y1(5$G`"%1'E$D41<.OE$D41<!(2$ZZ0(0#@
+M8`>0-)C at 1`3PPR+DD#18\)`T,G0?\'41!W42T)`T@>!D`V`.Y1(5$G`"%1'E
+M$D41<.KE$D41<!(2$ZZ0(0#@8`>0-)C at 1`3PPR*0-)C at 1`3PY)```?#3(I``
+M`70.\)`TF.!4^_"0-%AT`?"0,#!T!/`BCA:/%XP8C1GD_^_#FU!3Y1LPX!+O
+M?``E&?WL-1B- at O6#X/4<@!_E&S#A$^]\`"49_>PU&(V"]8/DD_4<@`?E&2_X
+MYO4<Y1LPY`_E%R_U at N0U%O6#Y1SP@`;E%R_XIAP/@*@BD"$`X,0S5.`D$/6"
+MY#0AJX+Z$A#8BX**@^Z/\!($!7XB?S#-Z\W,ZLP2&$+DD"$#\*\M$A#H(N4P
+M$@0_%(,`%/$!%5D"%>T#%D$$%H@%%OL&%VH'```7HL(!$@`&D#`ZX/42Y28@
+MY0B0-)C at 5/[P(I`TF.!$`?#E)C#F#^4G,.8%4Q+]@!)#$@*`#>4G,.8%0Q("
+M@`-3$OWE)C#G#^4G,.<%4Q+W@!)#$@B`#>4G,.<%0Q((@`-3$O=#$@%#$@20
+M,#KE$O`BP@$2``:0,#K@]1+E)B#E")`TF.!4_O`BD#28X$0!\.4F5,!@'.4G
+M,.8%4Q+]@`-#$@+E)S#G!5,2]X`?0Q((@!KE)S#F!4,2`H`#4Q+]Y2<PYP5#
+M$@B``U,2]T,2`4,2!)`P.N42\"+"`1(`!I`P.N#U$D,2`4,2!.4F,.5<D#28
+MX$0!\.4F5,!@'.4G,.8%4Q+]@`-#$@+E)S#G!5,2]X`P0Q((@"OE)S#F!4,2
+M`H`#4Q+]Y2<PYP5#$@B``U,2]^4G]%0?_Y`P-.!4X$_PY/4LD#`ZY1+P@!60
+M-)C at 5/[PY2?T5!__D#`TX%3 at 3_"0,#7@]1)3$N#E$O`BP@$2``:0,#K@]1+E
+M)C#E/)`TF.!$`?#E)S#F!5,2_8`#0Q("Y2<PYP53$O>``T,2".4F5,!@"$,2
+M`4,2!(`&4Q+^0Q($D#`ZY1+P(I`TF.!4_O`BP@$2``:0,#K@]1+E)S#F!4,2
+M`H`#4Q+]Y2<PYP5#$@B``U,2]^4F5,!@"%,2_E,2^X`&0Q(!0Q($D#28X$0!
+M\)`P.N42\"(@`A,2'#FO*7X`$AQPKS5^`!(<=]("D#`ZX/42Y28 at Y0W"`1(`
+M!I`TF.!4_O`BD#28X$0!\.4F5,!@+,(!$@`&Y2<PY at 53$OV``T,2`N4G,.<%
+M4Q+W@`-#$@A#$@%#$@20,#KE$O`B,`$#`A>B$ACTT@$BP@$2``;E)B#E"9`T
+MF.!4_O"`59`TF.!$`?#E)C#F#^4G,.8%4Q+]@!)#$@*`#>4G,.8%0Q("@`-3
+M$OWE)C#G#^4G,.<%4Q+W@!)#$@B`#>4G,.<%0Q((@`-3$O=#$@%3$ON0,#KE
+M$O"0,#K@]1(BY28PY2P@`R'2`Q(<.74U!G4I":\I?@`2''"0,#K@]1)3$OY#
+M$@3E$O"0-)C at 1`'P(I`TF.!4_O`BY/_E,"3^<"SD_N[#E2Q0$G0!R.[("(`"
+MPS/8_,]/SPZ`Z)`P-.!4X/[E)U0?;_3.3L[N\"*0*:#@<&.0,(SD\*-TPO"C
+M=`'PH^3PD#",X/^0*:#PD#",Y/"C=,7PHW0!\*/D\)`PC.#_D"FA\)`PC.3P
+MHW3$\*-T`?"CY/"0,(S at _Y`IHO"0,(SD\*-TP_"C=`'PH^3PD#",X)`IH_`B
+MC!.-%.\D'O6"Y#[U@^#\H^!,8$'O)![U at N0^]8/@_*/@]8*,@^#\H^#]A12"
+MA1.#X/JCX/O3[9OJ9(#X[&2`F$`3[R0>]8+D/O6#X/RCX,[LSO^`KZT4K!,2
+M&G$B$@C*4$_E-"02_^0U,_[E-"00]8+D-3/U@^#]Y/L2#:#E-"00]8+D-3/U
+M@^#_?@`2#BF0``IT0/"0``O at 1$#_\)``"G2`\$^0``OPD##I=`'P=2\&(I`P
+M.N#_Y2<PYA(P#`;O5/7^@`3O1`K^S^[/@!`P#`;O1`K^@`3O5/7^S^[/SU3^
+MS\]$!,^0,#KO\#`,"7\(?@`2''"`!W\B?@$2''"R#"+`X,#PP(/`@L#0==`(
+MPJ_"C,*-T^5*E`#E290`0`CE2A5*<`(52=/E3)0`Y4N4`$`(Y4P53'`"%4L2
+M``[2C-*OT-#0 at M"#T/#0X#(P!SSE+W`XP@>0(B[@_J/@CA'U$I`B3N#^H^#_
+MD"(N[O"C[_"0(D[E$?"CY1+PCC./-#`(!1(4*\((P at D2#D<B?X!^*>3]_(^"
+MCH/@^W1%+?C&Z\9T!"_U at N0^]8/@^W1!+?C&Z\9T""__Y#[^#;T``0SM9`1,
+M<,\BD```=`[P````Y/`2!<L2'(20-)C at 1`'PY3"T!0H2'%%0#1(8](`(Y3"T
+M!P,2!N at 2!&N`Y(#^(N\D'O6"Y#[U@^#\H^#[RNS*)![U at N0\]8/@_*/@_>\D
+M'O6"Y#[U@^SPH^WPSNK.S^O/(N\D'O6"Y#[U@^#ZH^#[[20>]8+D//6#ZO"C
+MZ_#O)![U at N0^]8/L\*/M\"+`X,#0PJ_"CL*/T^5`E`#E/Y0`0`WE0!5`<`(5
+M/Q(<9]*.TJ_0T-#@,A((RE`B?C!_X'P<?7YU&Q)[!A(3R)``!'0"\)``"O#2
+M"1(.1^3U+R(2&<Z0(0'@]2AT024H^.;U,G1%)2CXYO4BD"$`X&`#T at TBP@TB
+MD#0PY/"C\*-T'_"CY/"0`1#@(.$#`(#VD`$2X"#A`P"`]B+D_W0V+_CFD#",
+M\.^0&[J3D#"-\*-T`?"CY/`/OPGC(N3_[Y`;Q).0,(SP[Y`;NI.0,(WPHW0!
+M\*/D\`^_">,B`@0+%@P2&"0P2&!LD,@``0(#"P\*#@D-"`SOQ#,S5,#_D`$`
+MX%0_3_"0`0+ at 1(#P(N3U,9``"G3_\)`B+G0A\*-T$/`B4E-4$A46$!%``"``
+M0/\_/[TH(0"0,$!T,O"C=+#PHW0!\*/D\")U,0&0``IT__"0``O at 1"#P(@(?
+M!V<8GP9@``D:Q04O'!&0,$!T,O"C=+#PH^3PH_`B$@C*4`C2"1(.1^3U+R*0
+M-#!T'_"CY/"C\*/P(GA_Y/;8_76!3`(:!\*OPHS"C1(`#M*O(L*.CC^/0!(<
+M9]*.(N5*14EP`].``<,BY4Q%2W`#TX`!PR+"CW6-]76+02*.28]*THPBCDN/
+M3-*,(@```````,(-Y/4N(@``````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```````````````````````````````````````````````````````````(
+"NV``
+`
+end
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/ral/rt2661.fw.uu.orig
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/contrib/dev/ral/rt2661.fw.uu.orig Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,202 @@
+# $FreeBSD$
+#
+# Copyright (c) 2005-2008, Ralink Technology Corp.
+# Paul Lin <paul_lin at ralinktech.com.tw>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+begin 644 rt2661.fw
+M`A+>`A3PPHPB(@`"%N7"K\*-=8R4=8J3TJ\B`AF)Y3`2#^4`/P``K0$!%0(!
+MJ0,!_00"1`4"MP8#)@<```->P@$2``:0,#K@]1+E)B#E")`TF.!4_O`BD#28
+MX$0!\.4F,.8/Y2<PY at 53$OV`$D,2`H`-Y2<PY at 5#$@*``U,2_>4F,.</Y2<P
+MYP53$O>`$D,2"(`-Y2<PYP5#$@B``U,2]T,2`4,2!)`P.N42\"+"`1(`!I`P
+M.N#U$N4F(.4(D#28X%3^\"*0-)C at 1`'PY294P&`<Y2<PY at 53$OV``T,2`N4G
+M,.<%4Q+W@!]#$@B`&N4G,.8%0Q("@`-3$OWE)S#G!4,2"(`#4Q+W0Q(!0Q($
+MD#`ZY1+P(L(!$@`&D#`ZX/420Q(!0Q($Y28PY5R0-)C at 1`'PY294P&`<Y2<P
+MY at 53$OV``T,2`N4G,.<%4Q+W@#!#$@B`*^4G,.8%0Q("@`-3$OWE)S#G!4,2
+M"(`#4Q+WY2?T5!__D#`TX%3 at 3_#D]2R0,#KE$O"`%9`TF.!4_O#E)_14'_^0
+M,#3 at 5.!/\)`P->#U$E,2X.42\"+"`1(`!I`P.N#U$N4F,.4\D#28X$0!\.4G
+M,.8%4Q+]@`-#$@+E)S#G!5,2]X`#0Q((Y294P&`(0Q(!0Q($@`93$OY#$@20
+M,#KE$O`BD#28X%3^\"+"`1(`!I`P.N#U$N4G,.8%0Q("@`-3$OWE)S#G!4,2
+M"(`#4Q+WY294P&`(4Q+^4Q+[@`9#$@%#$@20-)C at 1`'PD#`ZY1+P(B`"$Q(<
+MG*\I?@`2'/*O-7X`$ASYT@*0,#K@]1+E)B#E#<(!$@`&D#28X%3^\"*0-)C@
+M1`'PY294P&`LP@$2``;E)S#F!5,2_8`#0Q("Y2<PYP53$O>``T,2"$,2`4,2
+M!)`P.N42\"(P`0,"`UX2"8'2`2+"`1(`!N4F(.4)D#28X%3^\(!5D#28X$0!
+M\.4F,.8/Y2<PY at 53$OV`$D,2`H`-Y2<PY at 5#$@*``U,2_>4F,.</Y2<PYP53
+M$O>`$D,2"(`-Y2<PYP5#$@B``U,2]T,2`5,2^Y`P.N42\)`P.N#U$B+E)C#E
+M+"`#(=(#$AR<=34&=2D)KRE^`!(<\I`P.N#U$E,2_D,2!.42\)`TF.!$`?`B
+MD#28X%3^\"(2'')``P(%7Y`A`N#U+9```^`2#^4#\0`$#P$#GQ`#L!$$,R`$
+MCB$$L2($Q3`$T#$%%E`$X%$%,U(%1V````55D``*X"#E`S`'`](((A(8MB*0
+M(0#@]1'E$<0S5.`D(?6"Y#0A]8/@1(#PY1'$,U3@)"SU at N0T(?6#Y1'PQ#-4
+MX"0M]8+D-"'U@^4M\.20(0/P(A((QY`A`.#U,6`%$@E<@`,2"6WDD"$#\*\M
+M$AS@(G4Q_Y`!`.!4]_"0`0'@5/[P5#[PY)``"_#PD"$#\*\M$AS@(GXK?X!]
+M`Q(*3Y`TS>`@X_F0(102#\&0-,`2#\V0(1 at 2#\&0-, at 2#\V0(1P2#\&0-,02
+M#\V0-,QT`?"CX$0$\)`!`>!$`?!$0/"0``O at 1!#PY)`A`_"O+1(<X"*0`0#@
+M5/?PD`$!X%3^\%2_\)``"^!4[_#DD"$#\*\M$AS@(GXK?X!]`Q(*3^20(0/P
+MKRT2'.`BT at 6%+2/DD"$#\"(2&R/"`.20(0/PKRT2'.`BA2TED``+X%3[__#D
+MD``'\)``"G0$\.20``CPD"$`X)``"?"0``=T<?#O1`20``OPY)`A`_`BD"$`
+MX/]4'_4PH^#U)X\F$@`>Y)`A`_"O+1(<X"*0(0#@]2P2&.WDD"$#\*\M$AS@
+M(A(:`N20(0/PKRT2'.`BY)`A`_"O+1(<X"*.%8\6RNW*R>O),`H$?TJ``G]"
+MR^_+ZL.4!%`"@`'#0`3+1"#+A1:"A16#Z_"CY/"%%H*%%8.CH^4:\.49A1:"
+MA16#HZ.C\.46)`3U at N0U%?6#=`_PY18D!?6"Y#45]8/D\.46)`;U at N0U%?6#
+MY/#E%B0']8+D-17U at W00\.J0&TN3^^ID`6`(ZF0"8`.Z`P3+1`C+Y18D"/6"
+MY#45]8/K\.46)!7U at N0U%?6#=/_PY18D%O6"Y#45]8/I\.46)`GU at N0U%?6#
+M=`3P)1KU&N0U&?49ZL.4!$`#`@<7ZF`#N@$?ZB0!_>0S_.4:KAEX`\,SSC/.
+MV/G_$@]6CAF/&@(&]^HD__WD-/_\?@!_"Q(/1,SNS,WOS>4:Q/A4#\AH_^49
+MQ%3P2/X2#U:,&XT<ZB3__>0T__Q^`'\+$@]$S.[,S>_-Y1K$^%0/R&C_Y1G$
+M5/!(_A(/5HX9CQKE'$4;8`@%&N4:<`(%&>HD__WD-/_\?@!_`Q(/1-/E')_E
+M&YY0&.4<11M@$KH##^46)`GU at N0U%?6#X$2`\.46)`KU at N0U%?6#Y1KPY1G_
+MY18D"_6"Y#45]8/O\(`MY1I4/__E%B0*]8+D-17U@^_PY1JN&7@&SL,3SA/8
+M^?_E%B0+]8+D-17U@^_PA1:"A16#X$0!\"*0-,W@^2#C^.4K]&!FD#3`$@_!
+MA32"A3.#=?`@Y2L2#]GE at B0$]8+D-8/U at Q(/S9`TR!(/P84T at H4S@W7P(.4K
+M$@_9Y8(D"/6"Y#6#]8,2#\V0--`2#\&%-(*%,X-U\"#E*Q(/V>6")`SU at N0U
+M at _6#$@_-Y30D\/_E,S3>_N]X!<[#$\X3V/GU*X4T at H4S@W7P(!(/V>6")`3U
+M at N0U@_6#$@_!D#3`$@_-A32"A3.#=?`@Y2L2#]GE at B0(]8+D-8/U at Q(/P9`T
+MR!(/S84T at H4S@W7P(.4K$@_9Y8(D#/6"Y#6#]8,2#\&0-,02#\V0`0'@1$#P
+MD`$`X$0(\.E$!)`TS?"0-,S at 1`'PH^!$`?"CX$0!\"+O)![U at N0^]8/@^J/@
+M^^TD'O6"Y#SU@^KPH^OP[R0>]8+D/O6#[/"C[?`B``"0``!T#O````#D\!((
+MQQ(=!I`TF.!$`?#E,+0%"A(<RE`-$@F!@`CE,+0'`Q()T!(0UX#D@/XBPJ_D
+M]2_UB'6H#W6)$?6X]>AUD`]U,?]U*_^0(B[PH_"0(D[PH_#"!<((P@#"!\($
+MD``*=/_PD``+=`'PD`$#=/_PY)`!!/"0`05T__#DD`$&\)``!/"0,.AT$/"0
+M`0?PD`$(!/"0`0ET2/"0`0IT?_"0`0)T'_"0`0!T%/"0`0%T(/"0``#@1(#P
+M=4D`=4H!P@'2KR)U,0&0``IT__"0``O at 1"#P(N3U,9``"G3_\)`B+G0A\*-T
+M$/`BD#`ZX/_E)S#F$C`,!N]4]?Z`!.]$"O[/[L^`$#`,!N]$"OZ`!.]4]?[/
+M[L_/5/[/ST0$SY`P.N_P,`P)?PA^`!(<\H`'?R)^`1(<\K(,(I`P.N#U$!(<
+MU5`FY2<PY at 53$/V``T,0`N4G,.<%4Q#W@`-#$`A3$/Y#$`20,#KE$/`2',I0
+M2)`!`^#U$%0<8#[E$%3C\*/@]1#PY2<PY at 5#$`*``U,0_>4G,.<%0Q`(@`-3
+M$/=3$/Y#$`20,#KE$/"O*7X`$ASRKS5^`!(<^2*.$H\3C13E%*+AD at GE-"09
+M]8+D-3/U@^#]Y30D&O6"Y#4S]8/@^Z()D at IU&0!U&AH2!6`P"01_R(`"?^CE
+M$R08]8+D-1+U@^_PY3%@!'\"@`)_`>43)!GU at N0U$O6#[_#E-"09]8+D-3/U
+M@^#_?1I\`!(0$>43)!KU at N0U$O6#[_#E$R0;]8+D-1+U@^[PY3%@8.43)!S_
+MY#42_N4T)!+]Y#4S_'4;$7L&$A70Y1,D(O_D-1+^?#!]$'4;$7L&$A70Y1,D
+M*/_D-1+^?#!]"'4;$7L&$A70Y30D&/6"Y#4S]8/@_^43)"WU at N0U$O6#[_"`
+M/^43)!S_Y#42_GPP?1!U&Q%[!A(5T.43)"+_Y#42_GPP?0AU&Q%[!A(5T.43
+M)"C_Y#42_GPP?1!U&Q%[!A(5T.43)"[U at N0U$O6#Y/#E$R0O]8+D-1+U@^3P
+MY30D$?6"Y#4S]8/@_\,3_^43)##U at N0U$O6#[_`P"4'E$R0P]8+D-1+U@^#_
+MY3%@!'X`@`)^$.].\.4Q8`9^`'\`@`_E%##@!GX`?_^`!'X`?P#E$R0Q]8+D
+M-1+U@^_P(N43)##U at N0U$O6#X$1`\.44,.`/Y30D$/6"Y#4S]8/@_X`"?P#E
+M$R0Q]8+D-1+U@^_P(N4T)!'U at N0U,_6#X##G.^4T)!SU at N0U,_6#X&4K<`-U
+M*__E-"0=]8+D-3/U@^#_$AS@?B)_$!(95HXSCS20(B[@_J/@CC/U-,,BT at KE
+M-"0;]8+D-3/U@^!P.H4T at H4S@\"#P(+ at _J/@_X4T at H4S@Z.CX/RCX/W#[YW_
+M[IS^T(+0 at _"C[_#3E`#N9("4@%`#`@UH@,:%-(*%,X/@_J/@P^YD@)2`4`,"
+M#6 at 2'+^%-(*%,X/@_*/@_<.?[F2`^.QD@)A`((4T at H4S@\"#P(*CH^#^H^#_
+M[9__[)[0 at M"#\*/O\,(*A32"A3.#X/ZCX/_E-"00]8+D-3/U@^#]P^^=_>Z4
+M`/P2%S!0+(4T at H4S@\"#P(+ at _J/@_X4T at H4S@Z.CX/RCX/W#[YW_[IS0 at M"#
+M\*/O\,(*(`H#`@QX?B)_$!(95HXSCS2/@HZ#X/ZCX-.4`.YD@)2`0`U^(G\0
+MK32L,Q(6,X`:$APUA32"A3.#[H_P$@^K?B)_,*TTK#,2%C.0(B[@_J/@_V4T
+M<`/N93-P`M,BCC./-,,BY3%D`7!!$AN#0`,"#T,2'`!0('XK?X!]`Q(*3W\!
+M$AHG0`G2"1(1F^3U+R(2!T]U+P$B?P$2&B=0!'4O`B+2"1(1F^3U+R(2&LQ0
+M41(<59`P].#U*GXP?^RCX/WD^Q(9VN3__A(<M)``"G0"\)``"^!$`O_P_9`!
+M!70@\)`!!N!$(/#M5+^0``OPD#3,X$0!\*/@1`'PH^!$`?#2!!(:Z5!#$AL&
+M?C!_X'PP?>QU&Q%[!A(5T)`P]>!U\""D_Z[P$ARTD``+X%3]__#]Y)``!/"0
+M`0;@5-_PD``*=$#P39``"_#"!!(;K5`X$AL&?C!_X'P=?0!U&Q)[!A(5T)``
+M!'0"\)``"O#D__X2'+20``O at 5/WPY)``!/"0`0;@5-_PP at 02&]=0)1(;!G\"
+M$AHGD`$$X%1_\)``"^!4_?_PY)``!/#O5+^0``OPP at 02&X-0+1(;!GXP?^!\
+M'7T`=1L2>P82%="0``1T`O"0``KPD`$&X%3?\)``"^!4O_#"!"+OC?"DJ/#/
+MC/"D*,Z-\*0N_B*\``N^`"GOC?"$_ZWP(N3,^'7P".\O_^XS_NPS_.Z=[)A`
+M!?SNG?X/U?#IY,[](NWX]?#NA"#2'/ZM\'7P".\O_^TS_4`'F%`&U?#R(L.8
+M_0_5\.HBQ?#XH^`H\,7P^.6"%8)P`A6#X#CP(N#\H^#]H^#^H^#_(NSPH^WP
+MH^[PH^_P(J0E at O6"Y?`U at _6#(M"#T(+XY)-P$G0!DW`-HZ.3^'0!D_6"B(/D
+M<W0"DVA@[Z.CHX#?BH.)@N1SCQ6,%HT7Y17#E`105N45E`!`!GH`>V"`!'H`
+M>\#E%\3X5`_(:/_E%L14\$C^Y160&SV3_7P`$@]6[RO[[CKZY1?$^%0/R&C_
+MY1;$5/!(_N45D_U\`!(/5NU,8&,+NP`!"H!<>@![&N47KA9X`L,SSC/.V/DD
+M"__D/O[E%9`;/9/]?``2#U;O>`+#,\XSSMCY*_ON.OKE%ZX6>`+#,\XSSMCY
+M)`O_Y#[^Y160&SV3_7P`$@]6[4Q@!W0$*_OD.OK/Z\_.ZLXBY2X48!T48#T4
+M8%T4<`,"$80D!&`#`A&:(`T#`A&:=2X!(I``"N#_,.4#1"#PY4!%/V`#`A&:
+M=2X"$AI*$AP3KR at 2&U<BD`$#X/\PYW;O1("0`0/P$AA"$AJ-$AQ%=2X#KR)^
+M`!(<J"+E0$4_<"$2%682'!,2&FT2'$42'(XP#0MU+@&O,GX`$ARH(N3U+B*0
+M``K at _S#E+$0@\!(59A(<$Q(:;1(<11(<CG4N!"+E0$4_<!`P#0IU+@&O,OX2
+M'*@BY/4N(I``!'0"\)``"O`P"3+E-$4S<`+#(H4T at H4S@\"#P(+ at _J/@_X4T
+M at H4S@Z.CX/RCX/W#[YW_[IS0 at M"#\*/O\.4T13-P`L,B$@PN4/.0``K@(.4#
+M,`=!Y31%,W`"PR*%-(*%,X/`@\""X/ZCX/^%-(*%,X.CH^#\H^#]P^^=_^Z<
+MT(+0 at _"C[_#E-$4S<`+#(A(,+E#S at +6%-(*%,X/@_J/@_Q(7P-,B$ANM0`42
+M&X-01'XP?^!\'7T`=1L2>P82%="0``1T`O"0``KPY/_^$ARTD``+X%2_\%1_
+M__#DD##I\.]4_9``"_#DD``$\-()$A&;Y/4O$AO"4$A^,'_@?!U]`'4;$GL&
+M$A70D``$=`+PD``*\.3__A(<M)``"^!4O_!4_?#DD``$\/\2&B=0!'4O!R*0
+M`03 at 5'_PT at D2$9OD]2\B>'_D]MC]=8%,`A,E`@B0Y).C^.23HT`#]H`!\@C?
+M](`IY).C^%0')`S(PS/$5`]$(,B#0`3T5H`!1O;?Y(`+`0($"!`@0("0``KD
+M?@&38+RC_U0_,.4)5!_^Y).C8`$.SU3`)>!@J$"XY).C^N23H_CDDZ/(Q8+(
+MRL6#RO"CR,6"R,K%@\K?Z=[G at +X2&X-0+1(9(I`!!N!4W_!^,'_@?!U]`'4;
+M$GL&$A70D``$=`+PD``*\-()$A&;Y/4O(A(;UU!0$ADBD``+X%3]\.20``3P
+MD`$#=(#PD`$$X$2`\'\"$AHG4`1U+P4B?C!_X'P=?0!U&Q)[!A(5T)``!'0"
+M\)``"O#2"1(1FY`!!.!4?_#D]2\BD#`P=`+P=1$'=1+0D#`PX##@#N42%1)P
+M`A41Y1)%$7#KY1)%$7`2$ALCD"$`X&`'D#28X$0$\,,BY)`T6/"0-#)T'_!U
+M$0=U$M"0-('@9`-@#N42%1)P`A41Y1)%$7#JY1)%$7`2$ALCD"$`X&`'D#28
+MX$0$\,,BD#28X$0$\.20``'PTR(2&VY0<A(<OX4T at H4S@^#\H^##G_42[)[U
+M$=/E$I0`Y1%D@)2`0`:N$:\2@`1^`'\`CA&/$N4T)!#U at N0U,_6#X,.5$O42
+MY)41]1'#9("4@%`%Y/41]1+E-"02_^0U,_ZM$GL!$AG:D`$%="#PD`$&X$0@
+M\'4O`R+`X,#PP(/`@L#0==`(PJ^0(B[@_J/@CC/U-.4O)>`D)?6"Y#0<]8/D
+MD_YT`9/*[LKY$A`+$AR`4`+2!Q(8`A(#7Q(;F%`%KR42'.`P!1OE+W`7(`04
+M$A/RD@#"!=(+H@#D,_44KR,2%WC2K]#0T(+0@]#PT.`RD"F at X'!CD#",Y/"C
+M=,+PHW0!\*/D\)`PC.#_D"F@\)`PC.3PHW3%\*-T`?"CY/"0,(S at _Y`IH?"0
+M,(SD\*-TQ/"C=`'PH^3PD#",X/^0*:+PD#",Y/"C=,/PHW0!\*/D\)`PC."0
+M*:/P(HX6CQ>,&(T9Y/_OPYM04^4;,.`2[WP`)1G][#48C8+U@^#U'(`?Y1LP
+MX1/O?``E&?WL-1B- at O6#Y)/U'(`'Y1DO^.;U'.4;,.0/Y1<O]8+D-1;U@^4<
+M\(`&Y1<O^*8<#X"H(HP3C13O)![U at N0^]8/@_*/@3&!![R0>]8+D/O6#X/RC
+MX/6"C(/@_*/@_844 at H43@^#ZH^#[T^V;ZF2`^.QD@)A`$^\D'O6"Y#[U@^#\
+MH^#.[,[_@*^M%*P3$@AC(A(;;E!/Y30D$O_D-3/^Y30D$/6"Y#4S]8/@_>3[
+M$AG:Y30D$/6"Y#4S]8/@_WX`$ARTD``*=$#PD``+X$1`__"0``IT@/!/D``+
+M\)`PZ70!\'4O!B+`X,#PP(/`@L#0==`(PJ_"C,*-T^5*E`#E290`0`CE2A5*
+M<`(52=/E3)0`Y4N4`$`(Y4P53'`"%4L2``[2C-*OT-#0 at M"#T/#0X#+#[Y0$
+M[F2`E(!`#-/ME`3L9("4@%`!(L/OE/SN9("4?T`,T^V4_.QD@)1_4`$BT^^4
+M!.YD@)2`4`W#[93\[&2`E']``M,BPR+D_N_T8$%T!"[U at N0T(?6#X+3_(W0$
+M+O6"Y#0A]8/O\#`+#70(+O6"Y#0A]8/E%/"0``)T`?`BO@,*D``"=`'PY/Z`
+MP at Z`OR*.$X\4$AR_P^^5%/_NE1/-[\W\T^V4`.QD@)2`0`7.[,Z`!'X`?P',
+M[LSLD``%\)``!N_PD``$=%'PD``+X$0"\"(P!SSE+W`XP@>0(B[@_J/@CA'U
+M$I`B3N#^H^#_D"(N[O"C[_"0(D[E$?"CY1+PCC./-#`(!1(8ML((P at D2$9LB
+MY/^0,(SD\.^0&^R31("0,(WPHW0!\*/D\)`PC.#^=#8O^,;NQJ/@_N^0&^R3
+M1(!N8`$?#^_#E`E`R")_@'XIY/W\CX*.@^#[=$4M^,;KQG0$+_6"Y#[U@^#[
+M=$$M^,;KQG0(+__D/OX-O0`!#.UD!$QPSR*0(0#@Q#-4X"00]8+D-"&K at OH2
+M'#6+ at HJ#[H_P$@^K?B)_,,WKS<SJS!(6,^20(0/PKRT2'.`BY/_E,"3^<"SD
+M_N[#E2Q0$G0!R.[("(`"PS/8_,]/SPZ`Z)`P-.!4X/[E)U0?;_3.3L[N\"*0
+M-,[@1`+PD#3-X%3^\)`TS>`@X_F0`1'@5"+_OR(#TX`!PU#PD`$`X%3W\)`!
+M`>!4O_`B[R0>]8+D/O6#X/RCX/O*[,HD'O6"Y#SU@^#\H^#][R0>]8+D/O6#
+M[/"C[?#.ZL[/Z\\BP.#`T,*OPH["C]/E0)0`Y3^4`$`-Y4`50'`"%3\2'.G2
+MCM*OT-#0X#(2&VY0(GXP?^!\'7T`=1L2>P82%="0``1T`O"0``KPT at D2$9OD
+M]2\BCA./%(T5ZV`)%'`;KQ42&JTB?C!_X*P3K11U&Q%[!A(5T*\5$AJM(A(8
+M?9`A`>#U*'1!)2CXYO4R=$4E*/CF]2*0(0#@8`/2#2+"#2+-[\V0`0+@,.<"
+MPR)^*G\`$@I/D`$$X$2`\)`!`N!$@/#3(I`T,.3PH_"C=!_PH^3PD`$0X"#A
+M`P"`]I`!$N`@X0,`@/8BY/]T-B_XYI`PC/#OD!OLDY`PC?"C=`'PH^3P#[\)
+MXR+D_^^0&_:3D#",\.^0&^R3D#"-\*-T`?"CY/`/OPGC(N20``7P[V`"@`)_
+M`9``!N_PD``$=%'PD``+X$0"\"*0,/#@]2J0``K@,.0.D##RX&`(D``*=!#P
+MTR+#(I`P\.#U*I``"N`PY`Z0,/+@<`B0``IT$/#3(L,BD#3.X$0"\)`TS>!4
+M_O"0`0#@5/?PD`$!X%2_\"*0``%T#O"0-)C at 5/OPD#18=`'PD#`P=`3P(@($
+M"Q8,$A at D,$A@;)#(``$"`PL/"@X)#0@,[\0S,U3`_Y`!`.!4/T_PD`$"X$2`
+M\"*0`0/@,.<,=(#PD`$$X%1_\-,BPR*0``K@,.$,=`+PD``+X%3]\-,BPR*0
+M``K@,.(,=`3PD``+X%3[\-,BPR*0``K@,.8,=$#PD``+X%2_\-,BPR*0``K@
+M,.<,=(#PD``+X%1_\-,BPR*0`07@,.4,="#PD`$&X%3?\-,BPR)24U02%180
+M$4``(`!`_S\_O2 at A`.4T)!'U at N0U,_6#X##F`M,BPR*0,$!T,O"C=+#PHW0!
+M\*/D\"(-Q11X%I`3:@`)&;(20AQDD#!DX/VCX/[M)>#_[C/^(I`P0'0R\*-T
+ML/"CY/"C\"*0`0#@1`CPD`$!X$1`\"(2&VY0"-()$A&;Y/4O(I``"N`PX`5T
+M`?#3(L,BD``*X##E!70@\-,BPR*0-#!T'_"CY/"C\*/P(L*OPHS"C1(`#M*O
+M(L*.CC^/0!(<Z=*.(I`P/._P[D2`H_`BD#!XX/VCX/[M_R+E2D5)<`/3@`'#
+M(N5,14MP`].``<,BP at OD]102%W at BPH]UC?5UBT$BCDF/2M*,(HY+CTS2C"(`
+M``````#"#>3U+B(`````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```````````````````````````````````````````````````````````(
+"0\\`
+`
+end
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/dev/ral/rt2860.fw.uu.orig
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/contrib/dev/ral/rt2860.fw.uu.orig Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,202 @@
+# $FreeBSD: head/sys/contrib/dev/ral/rt2860.fw.uu 232946 2012-03-13 21:25:25Z bschmidt $
+#
+# Copyright (c) 2005-2008, Ralink Technology Corp.
+# Paul Lin <paul_lin at ralinktech.com.tw>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+begin 644 rt2860.fw
+M`@-;`@*F(B+___\"`2S______P(`'O______`@#=P.#`\,"#P(+`T'70&,*O
+M,$4#$A`)D`06X##C`W0(\)`$%.`@YP,"`,MT@/"0<!+@]3:0!`3@),]@,!1@
+M0B3B8$<48%4D(7!@Y54D_F`'%&`()`)P"'T!@"A]`H`DD'`0X/50A39`T@&`
+M/N559`-@!.55<`1]`H`)A39!T@*`*:U5KS82`H*`()!P$.#U1Y!P$>#U1!(0
+M)8`&D'`0X/5%Y/VO-A("@M($D'`3Y/"0<!/D\-*OT-#0 at M"#T/#0X#+`X,#P
+MP(/`@L#0Z,#@Z<#@ZL#@Z\#@[,#@[<#@[L#@[\#@PJ\P10,2$!+2K]#@_]#@
+M_M#@_=#@_-#@^]#@^M#@^=#@^-#0T(+0@]#PT.`RP.#`\,"#P(+`T'70$,*O
+M,$4#$A`,,%@*Y51@!!54@`+"6#!9"N508`054(`"PEG54P<P8`051M($,$4#
+M$A`/PHW2K]#0T(+0@]#PT.`RD'`JX##A0\*OD'`HX)`0'/"0<"G at D!`=\)!P
+M*N"0$![PD!`<X/4WD!`>X"#A\Y`0'."0<"CPD!`=X)!P*?"0$![@D'`J\,(%
+MTJ\B$@+(,$4#$A`#,`$&(`D#$A`<,`(&(`H#$A`?,`,&(`L#$A`?,`0&(`P#
+M$A`B(!,)(!$&Y2M%+&`#TX`!PY*I$@,<@+_"0])%Y/4@]2'U4_5&]2OU+,)"
+M]5'U4O55D`08=(#PD`0:=`CPPAK"&,(;(LCOR.;Z".9*8`S([\@(YA88<`$6
+MPR+M)/_][#3_R._(]@C&[<;3(M"#T(+XY)-P$G0!DW`-HZ.3^'0!D_6"B(/D
+M<W0"DVA@[Z.CHX#?[_1@'^3^$@-GX+3_$A(#9^_P=!PN]8+D-'#U@^WP(@Z^
+M!.,BP.#`\,"#P(+`T'70",*O,$4#$A`&TJ_0T-""T(/0\-#@,L*O$@`&$@()
+M$@+AY/4B]4>0!`!T@/#2KR)UB0+D]8SUBO6(];CUZ'60&-*,=:@%(N]@`Q^`
+M^B+_P"9T`\#@P(+`@W4F"B+`)G0#P.#`@L"#=288(C!%`Q(0%>4@<`,@$`,P
+M$0-#AP$BSN_.[F`(?_\2`O@>@/4BR._(YF`#%L,B[13VTR+([\CF8`86YB3_
+MLR+#(GA_Y/;8_76!7P(!Q704+O6"Y#1P]8,B[Y`#>Y.0`P!S"AC_________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_____P(0*`(0.P(0/`(3O`(3O0(4<@(4<\,B__\"&4H"&O0"%6P"%*<P!08@
+M#0,2`7HP!@8@#@,2'"XB(I`$%.`@YP,"$[N0<!+@]5:0!`3@$@)<$/LP$-(Q
+M$),S$*$T$+0U$*LV$0E0$4Y1$5=2$5=3$5=4$9-5$?!6$D-P$FEQ$I)R$SYS
+M$V&`$XB#$Z"$```3N](8TF%U-2IU, at MU,[@BPAB0`13 at 5/WP(I!P$>#U/`(3
+MM>55M`(/Y5 at PX`:0`0UT"/!]`8`"?0*O5A("@@(3M2`"`S`#"GT"KU82`H("
+M$[7E--.4`4`,D`$,X$0"\*/@1`3PA59!T@(BD'`1X/1P`P(3N^#U,"+E--.4
+M`4`'Y55@`P(3NY!P$.!4?_^_"@V0<!'@M`@&=4X!=4^$D'`0X%1__[\"$I!P
+M$>!D"&`$X+0@!G5.`W5/(.3U)R*0<!'@)/^21R+E--.4`4`'Y55@`P(329`$
+M!.`EX"1=]5>0<!#@_W1')5?XQN_&D'`1X/]T2"57^,;OQN3]KU82`H("$[7E
+M--.4`4`'Y55@`P(32>5'9`=@'>5'9`A@%^5'9`E@$>5'9`I@"^5'9`M@!>5'
+MM`P(D'`1X%0/]3KE1[0)".4ZM`,#Y/5&Y4>T"@CE.K0!`^3U1N3]KU82`H+2
+M!"*0<!'@]/^0<!#@7_^0<!'@52=/D'`8\)!P$>"0<!GPY/VO5A("@C`5`](4
+M(I!P&.#U)Y`"*>#_D'`9X/[O7I`"*?`P1P2O)X`$Y2?T_Y`"*._P(N4TTY0!
+M0`?E56`#`A-)D'`0X/Z0<!'@_>WXYO57_:]6$@*"`A.UY333E`%`!^558`,"
+M$TF0<!#@_I!P$>#][?6"CH/@]5?]KU82`H("$[60$`#@]5?D]5CU69`0`^"T
+M*`5U6`&`/)`0`^"T,`5U6`*`,)`0`^"T,P5U6`2`))`0`^"T-0R0$`+ at M'(%
+M=5@(@!&0$`/@M#4*D!`"X+23`W58$.58,.$9D`4(X$0!\/V0!07 at 5/OP1`3P
+M[53^D`4(\.3U3O5/=3K_PAK"&,(;]320!:1T$?"C=/_PHW0#\.3U,,(9D`$-
+MX$1`\'4\_ZU7KU82`H+DD'`R\(!WY333E`%`"^558`=]`Z]6`@*"D'`0X"3_
+MDI/D_:]6$@*"@%3E--.4`4`-Y55@"7T#KU82`H*`0)!P$.`D_Y)*T at 6M5Z]6
+M$@*"@"WD]33U,)!P$.#T8`/@]32M5Z]6$@*"@!72&04OY2^T&@/D]2_2!*U7
+MKU82`H*0!!1T@/`B(N4TPY0#0!?E5;0"$N4P8`XP8`MT_25&]4;2!.3U4^53
+M8`,"%'$P8"&R33!-'.4TPY0#0!'E5;0"#.4P8`AT`R5&]4:``@5&P at 3E3T5.
+M8`CE3Q5/<`(53C`:27\R?;A\"Q("-5`&D`00=$#P?S5],A(#/U`)D!`$X%3W
+M\-(&Y373E"U`,#`;+<(;HAB2&B`:))`$">!4W?"0$`3 at 1`CPPF'2`R+D]36B
+M&)(:,!H'D`0)X$0B\"(B,!0PD'`9X%4G_Y!P&.!/]2>0`BG at _Y!P&>#^[UZ0
+M`BGP,$<$KR>`!.4G]/^0`BCO\,(4(L)+PDSE1!("7!3)`!57!!53"!4S$!3=
+M(!3]8!4.H```%5F%2$.%2D*%3%[E1V0&8`,"%5F`&^5(Q%0/]4/E2L14#_5"
+MY4S$5`_U7N5'9`9P85-##X!<A4E#A4M"A4U>Y4=D!G!-@!OE2<14#_5#Y4O$
+M5`_U0N5-Q%0/]5[E1V0&<##E0U0/1!#U0X`FY4=D!&`%Y4>T!09#7 at 1U0@GE
+M1[0&$.5#5`]$,/5#@`;22X`"TDSD]2KE0L14\/_E0U0/3_5?TF`BTA7E1R3U
+M8`LDRV`')$!P!L(5(A(9%1(5CL(5PJ_"!-*O(L*OD`04X%0.8`32'(`(Y4Y%
+M3R3_DAS2KY`$%."BY)(==![PY5]4#_4MY2IP$S`<!>5?(.4+,!TIY5]4,&0P
+M<"'E*G`5Y33#E`-`">4P8`5U*@6`!W4J#(`"%2K2;-)M@`_E7S#F!L)LTFV`
+M!-)LPFWE1V0#<"$P2P;";-)M@!CE*G`#,$P1PDSE*G`%=2H'@`(5*M)LTFWE
+M1[0)%.5$(.,+Y3ID`F`%Y3JT`P3";-)MY4>T"A/E.K0!!L)LTFV`".4Z<`32
+M;,)M(&D'Y5X at X`*R:"!K!^5>(.$"LFH@;0?E7B#B`K)L=2Y`(&D$HFB`13!H
+M!N5&HN*`/#`9'.5>(.`$?P&``G\`Y2^T&01^`8`"?@#N;R3_@!WE7B#@!'\!
+M@`)_`.5&5/#^OO`$?@&``GX`[F\D_Y)SDG(@:P2B:H!%,&H&Y4:BXH`\,!D<
+MY5X at X01_`8`"?P#E+[09!'X!@`)^`.YO)/^`'>5>(.$$?P&``G\`Y494\/Z^
+M\`1^`8`"?@#N;R3_DG62="!M!*)L@";E1V0*<"(P;`;E1J+C@!?E.K0!!N5&
+MHN.`4^5&(.0#,.4#TX`!PX!%,&P&Y4:BXH`\,!D<Y5X at X@1_`8`"?P#E+[09
+M!'X!@`)^`.YO)/^`'>5>(.($?P&``G\`Y494\/Z^\`1^`8`"?@#N;R3_DG&2
+M<)`0`."0$"SPD!`#X,.4,$`4HG&2=Z)PDG;E+A,35#_U+L)WTG:0$"_E+O#E
+M1V0&<#F0`BG at 5/[PY4/$5`\48`PD_F`,)`-P$\(X@`_2.(`+Y48PX@/3@`'#
+MDC at P1P6O)P(9#^4G]/\"&0_E1V0'8`_E1V0(8`GE1V0)8`,"&(Z0`BG at 5/SP
+MY3H48"(48"448"TD_&!))/E@%"0.<%#E1A,35#]U\`.$Y?`D_X`ZTCG".(`^
+MY48PX@/3@!W#@!KE1C#B#50XPY0P4`9^`'\!@`1^`'\`[D\D_Y(XPCF`$^5&
+M,.(#TX`!PY(YPCB`!,(XPCDP1P2O)X`$Y2?T_P(9#^5'9`Q@!N5'9`MP>I`"
+M*>!4_?#E.A1@(!1@(11@*R3\8$4D^6`2)`YP2N5&$Q-4/W7P`X3E\(`ITCF`
+M.N5&,.(#TX`!PY(Y@"WE1C#B#50XPY0P4`9^`'\!@`1^`'\`[D\D_Y(Y@`_E
+M1C#B`].``<.2.8`"PCDP1P2O)X`$Y2?T_Y`"*._P(N5'M`L0D`(IX%3K\.4G
+M5.M%1?4G(N20`BGP,$<$KT6`!.5%]/^0`BCO\"*/4-)9(H]4TE at BY/4WPJ_E
+M411 at 2A1@:R0"8`,"&M726755`2`:')`"".!4_O#@(.$CD`0TX+0"'*/@M`(7
+MH^"T`A)_(!(90)`0!.!4\_!U40$"&M7E4'`&=3<#`AK5D!(`X%0#<!5_(!(9
+M0"`:!Y`"".!4^_!U40("&M7E4'`#`AK0(!H5D`((X##C`P(:S)`$-^!D(F`#
+M`AK,D!($=`KPY5 at PXQ7DD`4`\*-T"/"C=`'P=`/P?P$2`S"0$RC at D'`:\)`3
+M*>"0<!OPD!,KX)!P(O"0$RC at 5/#PH^!4\/"0$RO at 5,SPY5 at PXQ?E-'`3Y3ST
+MD!,J8`7 at 5/.`$>!4^_"`%.4\])`3*F`(X%3R13SP@`3 at 5/KP(!H'D`0!X$00
+M\.4TTY0!0`GE,'`%=8Q`@`-UC("0!`'@5/WP(!H'D!($X$0$\.58,.`&D`$-
+MX/4QY333E`%`+)`!#>!$`?#E6"#C#.4TM`,'D!($X%3]\"`"$2`##I`!#>!4
+M^_"0`0S at 5/WP=3<!=54"Y/51@`GE4'`%=3<#]5'E-V`8P@'D]5'"62`:#JTW
+MKT`2&_KE-[0#`M(#TJ\BPJ\P`0[D]5'"6<(!?0*O0!(;^N52%&!6%&`S)`)@
+M`P(;]^4TTY0!0!^0`0S at 1`+PH^!$!/"0$@3 at 1`+P?S(2`S"0`0W at 5/[P=5("
+M=54#Y5 at PX`:0`0WE,?"0$@3 at 5/OP?R`2&45U4@%U50,"&_?E5&`#`AOWD`0!
+MX$0.\"`:!.!4[_#D]8SE6%088!Z0<!K at D!,H\)!P&^"0$RGPHW0%\)!P(N"0
+M$ROP@!&0$RC at 1`_PH^!$#_"CX$0%\)`2!'0#\.58,.,6D`4`=.+PHW0(\*-T
+M`?!T`_!_`1(#,"`:!Y`"".!$!?"0$`3 at 1`SPY/52]54P`@G"`GT!KT$2&_HP
+M`P+"`]*O(N_T8"WD_G04+O6"Y#1P]8/@M/\9=!0N]8+D-'#U@^_P=!PN]8+D
+M-'#U@^WP(@Z^!-4B(B(P&G>0!#?@(.5LD`0HX/4XH^#U-_4YY/4EY3EU\("D
+M)`#_Y?`T@/[E-V4Y<`7\?2B`!'P`?0#O+?_N//X2'*E0!Y`!%.!$`O#E.64X
+M8!#D)3G_Y#2`CX+U@^#U.8"[D`00=`'PD`0HY3CPH^4W\)`$$70!\("-P@;2
+M&R+E)<.4!E`9CX*.@^"T_P<%)>3U)(`NY/4ECX*. at _"`).4D=?`&A'0()?#U
+M at N0T$/6#X/V/@HZ#X&UP!@4E!22``^3U)0^_``$.[U1_8`?E)<.4*D"KY26T
+M*@/3@`'#(@``````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```````````````````````````````````````````````````````````:
+"4X@`
+`
+end
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/libfdt/fdt.c
--- a/head/sys/contrib/libfdt/fdt.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/libfdt/fdt.c Wed Jul 25 16:45:04 2012 +0300
@@ -149,6 +149,15 @@
return offset;
}
+int _fdt_check_prop_offset(const void *fdt, int offset)
+{
+ if ((offset < 0) || (offset % FDT_TAGSIZE)
+ || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
+ return -FDT_ERR_BADOFFSET;
+
+ return offset;
+}
+
int fdt_next_node(const void *fdt, int offset, int *depth)
{
int nextoffset = 0;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/libfdt/fdt_empty_tree.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/contrib/libfdt/fdt_empty_tree.c Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,84 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2012 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+int fdt_create_empty_tree(void *buf, int bufsize)
+{
+ int err;
+
+ err = fdt_create(buf, bufsize);
+ if (err)
+ return err;
+
+ err = fdt_finish_reservemap(buf);
+ if (err)
+ return err;
+
+ err = fdt_begin_node(buf, "");
+ if (err)
+ return err;
+
+ err = fdt_end_node(buf);
+ if (err)
+ return err;
+
+ err = fdt_finish(buf);
+ if (err)
+ return err;
+
+ return fdt_open_into(buf, buf, bufsize);
+}
+
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/libfdt/fdt_ro.c
--- a/head/sys/contrib/libfdt/fdt_ro.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/libfdt/fdt_ro.c Wed Jul 25 16:45:04 2012 +0300
@@ -105,6 +105,30 @@
return i;
}
+static int _nextprop(const void *fdt, int offset)
+{
+ uint32_t tag;
+ int nextoffset;
+
+ do {
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+
+ switch (tag) {
+ case FDT_END:
+ if (nextoffset >= 0)
+ return -FDT_ERR_BADSTRUCTURE;
+ else
+ return nextoffset;
+
+ case FDT_PROP:
+ return offset;
+ }
+ offset = nextoffset;
+ } while (tag == FDT_NOP);
+
+ return -FDT_ERR_NOTFOUND;
+}
+
int fdt_subnode_offset_namelen(const void *fdt, int offset,
const char *name, int namelen)
{
@@ -194,52 +218,66 @@
return NULL;
}
+int fdt_first_property_offset(const void *fdt, int nodeoffset)
+{
+ int offset;
+
+ if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
+ return offset;
+
+ return _nextprop(fdt, offset);
+}
+
+int fdt_next_property_offset(const void *fdt, int offset)
+{
+ if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0)
+ return offset;
+
+ return _nextprop(fdt, offset);
+}
+
+const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
+ int offset,
+ int *lenp)
+{
+ int err;
+ const struct fdt_property *prop;
+
+ if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) {
+ if (lenp)
+ *lenp = err;
+ return NULL;
+ }
+
+ prop = _fdt_offset_ptr(fdt, offset);
+
+ if (lenp)
+ *lenp = fdt32_to_cpu(prop->len);
+
+ return prop;
+}
+
const struct fdt_property *fdt_get_property_namelen(const void *fdt,
- int nodeoffset,
+ int offset,
const char *name,
int namelen, int *lenp)
{
- uint32_t tag;
- const struct fdt_property *prop;
- int offset, nextoffset;
- int err;
+ for (offset = fdt_first_property_offset(fdt, offset);
+ (offset >= 0);
+ (offset = fdt_next_property_offset(fdt, offset))) {
+ const struct fdt_property *prop;
- if (((err = fdt_check_header(fdt)) != 0)
- || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
- goto fail;
-
- nextoffset = err;
- do {
- offset = nextoffset;
-
- tag = fdt_next_tag(fdt, offset, &nextoffset);
- switch (tag) {
- case FDT_END:
- if (nextoffset < 0)
- err = nextoffset;
- else
- /* FDT_END tag with unclosed nodes */
- err = -FDT_ERR_BADSTRUCTURE;
- goto fail;
-
- case FDT_PROP:
- prop = _fdt_offset_ptr(fdt, offset);
- if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff),
- name, namelen)) {
- /* Found it! */
- if (lenp)
- *lenp = fdt32_to_cpu(prop->len);
-
- return prop;
- }
+ if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) {
+ offset = -FDT_ERR_INTERNAL;
break;
}
- } while ((tag != FDT_BEGIN_NODE) && (tag != FDT_END_NODE));
+ if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff),
+ name, namelen))
+ return prop;
+ }
- err = -FDT_ERR_NOTFOUND;
- fail:
if (lenp)
- *lenp = err;
+ *lenp = offset;
return NULL;
}
@@ -263,6 +301,19 @@
return prop->data;
}
+const void *fdt_getprop_by_offset(const void *fdt, int offset,
+ const char **namep, int *lenp)
+{
+ const struct fdt_property *prop;
+
+ prop = fdt_get_property_by_offset(fdt, offset, lenp);
+ if (!prop)
+ return NULL;
+ if (namep)
+ *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+ return prop->data;
+}
+
const void *fdt_getprop(const void *fdt, int nodeoffset,
const char *name, int *lenp)
{
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/libfdt/fdt_rw.c
--- a/head/sys/contrib/libfdt/fdt_rw.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/libfdt/fdt_rw.c Wed Jul 25 16:45:04 2012 +0300
@@ -289,6 +289,33 @@
return 0;
}
+int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len)
+{
+ struct fdt_property *prop;
+ int err, oldlen, newlen;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
+ if (prop) {
+ newlen = len + oldlen;
+ err = _fdt_splice_struct(fdt, prop->data,
+ FDT_TAGALIGN(oldlen),
+ FDT_TAGALIGN(newlen));
+ if (err)
+ return err;
+ prop->len = cpu_to_fdt32(newlen);
+ memcpy(prop->data + oldlen, val, len);
+ } else {
+ err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
+ if (err)
+ return err;
+ memcpy(prop->data, val, len);
+ }
+ return 0;
+}
+
int fdt_delprop(void *fdt, int nodeoffset, const char *name)
{
struct fdt_property *prop;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/libfdt/libfdt.h
--- a/head/sys/contrib/libfdt/libfdt.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/libfdt/libfdt.h Wed Jul 25 16:45:04 2012 +0300
@@ -343,6 +343,75 @@
const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
/**
+ * fdt_first_property_offset - find the offset of a node's first property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: structure block offset of a node
+ *
+ * fdt_first_property_offset() finds the first property of the node at
+ * the given structure block offset.
+ *
+ * returns:
+ * structure block offset of the property (>=0), on success
+ * -FDT_ERR_NOTFOUND, if the requested node has no properties
+ * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings.
+ */
+int fdt_first_property_offset(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_next_property_offset - step through a node's properties
+ * @fdt: pointer to the device tree blob
+ * @offset: structure block offset of a property
+ *
+ * fdt_next_property_offset() finds the property immediately after the
+ * one at the given structure block offset. This will be a property
+ * of the same node as the given property.
+ *
+ * returns:
+ * structure block offset of the next property (>=0), on success
+ * -FDT_ERR_NOTFOUND, if the given property is the last in its node
+ * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings.
+ */
+int fdt_next_property_offset(const void *fdt, int offset);
+
+/**
+ * fdt_get_property_by_offset - retrieve the property at a given offset
+ * @fdt: pointer to the device tree blob
+ * @offset: offset of the property to retrieve
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_get_property_by_offset() retrieves a pointer to the
+ * fdt_property structure within the device tree blob at the given
+ * offset. If lenp is non-NULL, the length of the property value is
+ * also returned, in the integer pointed to by lenp.
+ *
+ * returns:
+ * pointer to the structure representing the property
+ * if lenp is non-NULL, *lenp contains the length of the property
+ * value (>=0)
+ * NULL, on error
+ * if lenp is non-NULL, *lenp contains an error code (<0):
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
+ int offset,
+ int *lenp);
+
+/**
* fdt_get_property_namelen - find a property based on substring
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose property to find
@@ -396,6 +465,40 @@
}
/**
+ * fdt_getprop_by_offset - retrieve the value of a property at a given offset
+ * @fdt: pointer to the device tree blob
+ * @ffset: offset of the property to read
+ * @namep: pointer to a string variable (will be overwritten) or NULL
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_getprop_by_offset() retrieves a pointer to the value of the
+ * property at structure block offset 'offset' (this will be a pointer
+ * to within the device blob itself, not a copy of the value). If
+ * lenp is non-NULL, the length of the property value is also
+ * returned, in the integer pointed to by lenp. If namep is non-NULL,
+ * the property's namne will also be returned in the char * pointed to
+ * by namep (this will be a pointer to within the device tree's string
+ * block, not a new copy of the name).
+ *
+ * returns:
+ * pointer to the property's value
+ * if lenp is non-NULL, *lenp contains the length of the property
+ * value (>=0)
+ * if namep is non-NULL *namep contiains a pointer to the property
+ * name.
+ * NULL, on error
+ * if lenp is non-NULL, *lenp contains an error code (<0):
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+const void *fdt_getprop_by_offset(const void *fdt, int offset,
+ const char **namep, int *lenp);
+
+/**
* fdt_getprop_namelen - get property value based on substring
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose property to find
@@ -749,17 +852,17 @@
const void *val, int len);
/**
- * fdt_setprop_inplace_cell - change the value of a single-cell property
+ * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose property to change
* @name: name of the property to change
- * @val: cell (32-bit integer) value to replace the property with
+ * @val: 32-bit integer value to replace the property with
*
- * fdt_setprop_inplace_cell() replaces the value of a given property
- * with the 32-bit integer cell value in val, converting val to
- * big-endian if necessary. This function cannot change the size of a
- * property, and so will only work if the property already exists and
- * has length 4.
+ * fdt_setprop_inplace_u32() replaces the value of a given property
+ * with the 32-bit integer value in val, converting val to big-endian
+ * if necessary. This function cannot change the size of a property,
+ * and so will only work if the property already exists and has length
+ * 4.
*
* This function will alter only the bytes in the blob which contain
* the given property value, and will not alter or move any other part
@@ -768,7 +871,7 @@
* returns:
* 0, on success
* -FDT_ERR_NOSPACE, if the property's length is not equal to 4
- * -FDT_ERR_NOTFOUND, node does not have the named property
+ * -FDT_ERR_NOTFOUND, node does not have the named property
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
@@ -776,11 +879,57 @@
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings
*/
+static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,
+ const char *name, uint32_t val)
+{
+ val = cpu_to_fdt32(val);
+ return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 64-bit integer value to replace the property with
+ *
+ * fdt_setprop_inplace_u64() replaces the value of a given property
+ * with the 64-bit integer value in val, converting val to big-endian
+ * if necessary. This function cannot change the size of a property,
+ * and so will only work if the property already exists and has length
+ * 8.
+ *
+ * This function will alter only the bytes in the blob which contain
+ * the given property value, and will not alter or move any other part
+ * of the tree.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, if the property's length is not equal to 8
+ * -FDT_ERR_NOTFOUND, node does not have the named property
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,
+ const char *name, uint64_t val)
+{
+ val = cpu_to_fdt64(val);
+ return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_setprop_inplace_cell - change the value of a single-cell property
+ *
+ * This is an alternative name for fdt_setprop_inplace_u32()
+ */
static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
const char *name, uint32_t val)
{
- val = cpu_to_fdt32(val);
- return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
+ return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val);
}
/**
@@ -842,11 +991,20 @@
int fdt_finish_reservemap(void *fdt);
int fdt_begin_node(void *fdt, const char *name);
int fdt_property(void *fdt, const char *name, const void *val, int len);
-static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
+static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)
{
val = cpu_to_fdt32(val);
return fdt_property(fdt, name, &val, sizeof(val));
}
+static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)
+{
+ val = cpu_to_fdt64(val);
+ return fdt_property(fdt, name, &val, sizeof(val));
+}
+static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
+{
+ return fdt_property_u32(fdt, name, val);
+}
#define fdt_property_string(fdt, name, str) \
fdt_property(fdt, name, str, strlen(str)+1)
int fdt_end_node(void *fdt);
@@ -856,6 +1014,7 @@
/* Read-write functions */
/**********************************************************************/
+int fdt_create_empty_tree(void *buf, int bufsize);
int fdt_open_into(const void *fdt, void *buf, int bufsize);
int fdt_pack(void *fdt);
@@ -965,14 +1124,14 @@
const void *val, int len);
/**
- * fdt_setprop_cell - set a property to a single cell value
+ * fdt_setprop_u32 - set a property to a 32-bit integer
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose property to change
* @name: name of the property to change
* @val: 32-bit integer value for the property (native endian)
*
- * fdt_setprop_cell() sets the value of the named property in the
- * given node to the given cell value (converting to big-endian if
+ * fdt_setprop_u32() sets the value of the named property in the given
+ * node to the given 32-bit integer value (converting to big-endian if
* necessary), or creates a new property with that value if it does
* not already exist.
*
@@ -992,11 +1151,57 @@
* -FDT_ERR_BADLAYOUT,
* -FDT_ERR_TRUNCATED, standard meanings
*/
+static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,
+ uint32_t val)
+{
+ val = cpu_to_fdt32(val);
+ return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_setprop_u64 - set a property to a 64-bit integer
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 64-bit integer value for the property (native endian)
+ *
+ * fdt_setprop_u64() sets the value of the named property in the given
+ * node to the given 64-bit integer value (converting to big-endian if
+ * necessary), or creates a new property with that value if it does
+ * not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,
+ uint64_t val)
+{
+ val = cpu_to_fdt64(val);
+ return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_setprop_cell - set a property to a single cell value
+ *
+ * This is an alternative name for fdt_setprop_u32()
+ */
static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
uint32_t val)
{
- val = cpu_to_fdt32(val);
- return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
+ return fdt_setprop_u32(fdt, nodeoffset, name, val);
}
/**
@@ -1031,6 +1236,147 @@
fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
/**
+ * fdt_appendprop - append to or create a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to append to
+ * @val: pointer to data to append to the property value
+ * @len: length of the data to append to the property value
+ *
+ * fdt_appendprop() appends the value to the named property in the
+ * given node, creating the property if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len);
+
+/**
+ * fdt_appendprop_u32 - append a 32-bit integer value to a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 32-bit integer value to append to the property (native endian)
+ *
+ * fdt_appendprop_u32() appends the given 32-bit integer value
+ * (converting to big-endian if necessary) to the value of the named
+ * property in the given node, or creates a new property with that
+ * value if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_appendprop_u32(void *fdt, int nodeoffset,
+ const char *name, uint32_t val)
+{
+ val = cpu_to_fdt32(val);
+ return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_appendprop_u64 - append a 64-bit integer value to a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 64-bit integer value to append to the property (native endian)
+ *
+ * fdt_appendprop_u64() appends the given 64-bit integer value
+ * (converting to big-endian if necessary) to the value of the named
+ * property in the given node, or creates a new property with that
+ * value if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,
+ const char *name, uint64_t val)
+{
+ val = cpu_to_fdt64(val);
+ return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_appendprop_cell - append a single cell value to a property
+ *
+ * This is an alternative name for fdt_appendprop_u32()
+ */
+static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,
+ const char *name, uint32_t val)
+{
+ return fdt_appendprop_u32(fdt, nodeoffset, name, val);
+}
+
+/**
+ * fdt_appendprop_string - append a string to a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @str: string value to append to the property
+ *
+ * fdt_appendprop_string() appends the given string to the value of
+ * the named property in the given node, or creates a new property
+ * with that value if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+#define fdt_appendprop_string(fdt, nodeoffset, name, str) \
+ fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
+
+/**
* fdt_delprop - delete a property
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose property to nop
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/libfdt/libfdt_env.h
--- a/head/sys/contrib/libfdt/libfdt_env.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/libfdt/libfdt_env.h Wed Jul 25 16:45:04 2012 +0300
@@ -13,19 +13,25 @@
#include <string.h>
#endif
-#define _B(n) ((unsigned long long)((uint8_t *)&x)[n])
+#define EXTRACT_BYTE(n) ((unsigned long long)((uint8_t *)&x)[n])
+static inline uint16_t fdt16_to_cpu(uint16_t x)
+{
+ return (EXTRACT_BYTE(0) << 8) | EXTRACT_BYTE(1);
+}
+#define cpu_to_fdt16(x) fdt16_to_cpu(x)
+
static inline uint32_t fdt32_to_cpu(uint32_t x)
{
- return (_B(0) << 24) | (_B(1) << 16) | (_B(2) << 8) | _B(3);
+ return (EXTRACT_BYTE(0) << 24) | (EXTRACT_BYTE(1) << 16) | (EXTRACT_BYTE(2) << 8) | EXTRACT_BYTE(3);
}
#define cpu_to_fdt32(x) fdt32_to_cpu(x)
static inline uint64_t fdt64_to_cpu(uint64_t x)
{
- return (_B(0) << 56) | (_B(1) << 48) | (_B(2) << 40) | (_B(3) << 32)
- | (_B(4) << 24) | (_B(5) << 16) | (_B(6) << 8) | _B(7);
+ return (EXTRACT_BYTE(0) << 56) | (EXTRACT_BYTE(1) << 48) | (EXTRACT_BYTE(2) << 40) | (EXTRACT_BYTE(3) << 32)
+ | (EXTRACT_BYTE(4) << 24) | (EXTRACT_BYTE(5) << 16) | (EXTRACT_BYTE(6) << 8) | EXTRACT_BYTE(7);
}
#define cpu_to_fdt64(x) fdt64_to_cpu(x)
-#undef _B
+#undef EXTRACT_BYTE
#endif /* _LIBFDT_ENV_H */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/libfdt/libfdt_internal.h
--- a/head/sys/contrib/libfdt/libfdt_internal.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/libfdt/libfdt_internal.h Wed Jul 25 16:45:04 2012 +0300
@@ -63,6 +63,7 @@
}
int _fdt_check_node_offset(const void *fdt, int offset);
+int _fdt_check_prop_offset(const void *fdt, int offset);
const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
int _fdt_node_end_offset(void *fdt, int nodeoffset);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/pf/net/pf.c
--- a/head/sys/contrib/pf/net/pf.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/pf/net/pf.c Wed Jul 25 16:45:04 2012 +0300
@@ -40,7 +40,7 @@
#include "opt_inet6.h"
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/contrib/pf/net/pf.c 231852 2012-02-17 02:39:58Z bz $");
+__FBSDID("$FreeBSD: head/sys/contrib/pf/net/pf.c 236671 2012-06-06 09:36:52Z glebius $");
#endif
#ifdef __FreeBSD__
@@ -643,10 +643,10 @@
(*state)->key[PF_SK_WIRE]->af &&
(((*state)->direction == PF_OUT &&
PF_AEQ(&(*state)->src_node->addr,
- &sk->addr[0], sk->af)) ||
+ &sk->addr[1], sk->af)) ||
((*state)->direction == PF_IN &&
PF_AEQ(&(*state)->src_node->addr,
- &sk->addr[1], sk->af))) &&
+ &sk->addr[0], sk->af))) &&
((*state)->rule.ptr->flush &
PF_FLUSH_GLOBAL ||
(*state)->rule.ptr == st->rule.ptr)) {
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/pf/net/pf_if.c
--- a/head/sys/contrib/pf/net/pf_if.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/pf/net/pf_if.c Wed Jul 25 16:45:04 2012 +0300
@@ -37,7 +37,7 @@
#include "opt_inet6.h"
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/contrib/pf/net/pf_if.c 223637 2011-06-28 11:57:25Z bz $");
+__FBSDID("$FreeBSD: head/sys/contrib/pf/net/pf_if.c 238498 2012-07-15 19:10:00Z glebius $");
#endif
#include <sys/param.h>
@@ -506,8 +506,7 @@
if (aw->type != PF_ADDR_DYNIFTL)
return (0);
#ifdef __FreeBSD__
- /* XXX: revisit! */
- if ((dyn = pool_get(&V_pfi_addr_pl, PR_WAITOK | PR_ZERO))
+ if ((dyn = pool_get(&V_pfi_addr_pl, PR_NOWAIT | PR_ZERO))
#else
if ((dyn = pool_get(&pfi_addr_pl, PR_WAITOK | PR_LIMITFAIL | PR_ZERO))
#endif
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/pf/net/pf_ioctl.c
--- a/head/sys/contrib/pf/net/pf_ioctl.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/pf/net/pf_ioctl.c Wed Jul 25 16:45:04 2012 +0300
@@ -37,7 +37,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/contrib/pf/net/pf_ioctl.c 231852 2012-02-17 02:39:58Z bz $");
+__FBSDID("$FreeBSD: head/sys/contrib/pf/net/pf_ioctl.c 236364 2012-05-31 20:10:05Z eri $");
#include "opt_inet.h"
#include "opt_inet6.h"
@@ -298,7 +298,7 @@
V_pf_altq_pl = V_pf_pooladdr_pl = NULL;
V_pf_frent_pl = V_pf_frag_pl = V_pf_cache_pl = V_pf_cent_pl = NULL;
V_pf_state_scrub_pl = NULL;
- V_pfr_ktable_pl = V_pfr_kentry_pl = NULL;
+ V_pfr_ktable_pl = V_pfr_kentry_pl = V_pfr_kcounters_pl = NULL;
}
void
@@ -317,6 +317,7 @@
UMA_DESTROY(V_pf_cent_pl);
UMA_DESTROY(V_pfr_ktable_pl);
UMA_DESTROY(V_pfr_kentry_pl);
+ UMA_DESTROY(V_pfr_kcounters_pl);
UMA_DESTROY(V_pf_state_scrub_pl);
UMA_DESTROY(V_pfi_addr_pl);
}
@@ -337,6 +338,7 @@
UMA_CREATE(V_pf_pooladdr_pl, struct pf_pooladdr, "pfpooladdrpl");
UMA_CREATE(V_pfr_ktable_pl, struct pfr_ktable, "pfrktable");
UMA_CREATE(V_pfr_kentry_pl, struct pfr_kentry, "pfrkentry");
+ UMA_CREATE(V_pfr_kcounters_pl, struct pfr_kcounters, "pfrkcounters");
UMA_CREATE(V_pf_frent_pl, struct pf_frent, "pffrent");
UMA_CREATE(V_pf_frag_pl, struct pf_fragment, "pffrag");
UMA_CREATE(V_pf_cache_pl, struct pf_fragment, "pffrcache");
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/pf/net/pf_table.c
--- a/head/sys/contrib/pf/net/pf_table.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/pf/net/pf_table.c Wed Jul 25 16:45:04 2012 +0300
@@ -35,7 +35,7 @@
#include "opt_inet6.h"
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/contrib/pf/net/pf_table.c 230119 2012-01-14 22:51:34Z csjp $");
+__FBSDID("$FreeBSD: head/sys/contrib/pf/net/pf_table.c 236364 2012-05-31 20:10:05Z eri $");
#endif
#include <sys/param.h>
@@ -179,7 +179,6 @@
VNET_DEFINE(uma_zone_t, pfr_ktable_pl);
VNET_DEFINE(uma_zone_t, pfr_kentry_pl);
VNET_DEFINE(uma_zone_t, pfr_kcounters_pl);
-#define V_pfr_kcounters_pl VNET(pfr_kcounters_pl)
VNET_DEFINE(struct sockaddr_in, pfr_sin);
#define V_pfr_sin VNET(pfr_sin)
VNET_DEFINE(struct sockaddr_in6, pfr_sin6);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/pf/net/pfvar.h
--- a/head/sys/contrib/pf/net/pfvar.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/pf/net/pfvar.h Wed Jul 25 16:45:04 2012 +0300
@@ -1868,6 +1868,8 @@
#define V_pfr_ktable_pl VNET(pfr_ktable_pl)
VNET_DECLARE(uma_zone_t, pfr_kentry_pl);
#define V_pfr_kentry_pl VNET(pfr_kentry_pl)
+VNET_DECLARE(uma_zone_t, pfr_kcounters_pl);
+#define V_pfr_kcounters_pl VNET(pfr_kcounters_pl)
VNET_DECLARE(uma_zone_t, pf_cache_pl);
#define V_pf_cache_pl VNET(pf_cache_pl)
VNET_DECLARE(uma_zone_t, pf_cent_pl);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/rdma/krping/krping.c
--- a/head/sys/contrib/rdma/krping/krping.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/rdma/krping/krping.c Wed Jul 25 16:45:04 2012 +0300
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/contrib/rdma/krping/krping.c 237263 2012-06-19 07:34:13Z np $");
#include <sys/ctype.h>
@@ -41,7 +41,6 @@
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/socket.h>
-#include <sys/module.h>
#include <sys/endian.h>
#include <sys/limits.h>
#include <sys/proc.h>
@@ -53,11 +52,13 @@
#include <sys/queue.h>
#include <sys/taskqueue.h>
#include <sys/syslog.h>
+#include <netinet/in.h>
#include <vm/vm.h>
#include <vm/pmap.h>
-#include <contrib/rdma/rdma_cm.h>
+#include <linux/types.h>
+#include <rdma/rdma_cm.h>
#include "getopt.h"
#include "krping.h"
@@ -83,6 +84,7 @@
{"bw", OPT_NOPARAM, 'B'},
{"tx-depth", OPT_INT, 't'},
{"poll", OPT_NOPARAM, 'P'},
+ {"memlimit", OPT_INT, 'm'},
{NULL, 0, 0}
};
@@ -254,10 +256,14 @@
ib_req_notify_cq(cb->cq, IB_CQ_NEXT_COMP);
while ((ret = ib_poll_cq(cb->cq, 1, &wc)) == 1) {
if (wc.status) {
- if (wc.status != IB_WC_WR_FLUSH_ERR)
- log(LOG_ERR, "cq completion failed status %d\n",
+ if (wc.status == IB_WC_WR_FLUSH_ERR) {
+ DEBUG_LOG("cq flushed\n");
+ continue;
+ } else {
+ log(LOG_CRIT, "cq completion failed status %d\n",
wc.status);
- goto error;
+ goto error;
+ }
}
switch (wc.opcode) {
@@ -432,8 +438,17 @@
}
}
- cb->rdma_buf = contigmalloc(cb->size, M_DEVBUF, M_WAITOK, 0, -1UL,
- PAGE_SIZE, 0);
+ /* RNIC adapters have a limit upto which it can register physical memory
+ * If DMA-MR memory mode is set then normally driver registers maximum
+ * supported memory. After that if contigmalloc allocates memory beyond the
+ * specified RNIC limit then Krping may not work.
+ */
+ if (cb->use_dmamr && cb->memlimit)
+ cb->rdma_buf = contigmalloc(cb->size, M_DEVBUF, M_WAITOK, 0, cb->memlimit,
+ PAGE_SIZE, 0);
+ else
+ cb->rdma_buf = contigmalloc(cb->size, M_DEVBUF, M_WAITOK, 0, -1UL,
+ PAGE_SIZE, 0);
if (!cb->rdma_buf) {
log(LOG_ERR, "rdma_buf malloc failed\n");
@@ -458,8 +473,12 @@
}
if (!cb->server || cb->wlat || cb->rlat || cb->bw) {
- cb->start_buf = contigmalloc(cb->size, M_DEVBUF, M_WAITOK,
- 0, -1UL, PAGE_SIZE, 0);
+ if (cb->use_dmamr && cb->memlimit)
+ cb->start_buf = contigmalloc(cb->size, M_DEVBUF, M_WAITOK,
+ 0, cb->memlimit, PAGE_SIZE, 0);
+ else
+ cb->start_buf = contigmalloc(cb->size, M_DEVBUF, M_WAITOK,
+ 0, -1UL, PAGE_SIZE, 0);
if (!cb->start_buf) {
log(LOG_ERR, "start_buf malloc failed\n");
ret = ENOMEM;
@@ -1636,6 +1655,8 @@
cb->state = IDLE;
cb->size = 64;
cb->txdepth = RPING_SQ_DEPTH;
+ cb->use_dmamr = 1;
+ cb->memlimit = 0;
mtx_init(&cb->lock, "krping mtx", NULL, MTX_DUPOK|MTX_DEF);
while ((op = krping_getopt("krping", &cmd, krping_opts, NULL, &optarg,
@@ -1713,6 +1734,15 @@
case 'd':
debug++;
break;
+ case 'm':
+ cb->memlimit = optint;
+ if (cb->memlimit < 1) {
+ log(LOG_ERR, "Invalid memory limit %ju\n",
+ cb->memlimit);
+ ret = EINVAL;
+ } else
+ DEBUG_LOG(PFX "memory limit %d\n", (int)optint);
+ break;
default:
log(LOG_ERR, "unknown opt %s\n", optarg);
ret = EINVAL;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/rdma/krping/krping.h
--- a/head/sys/contrib/rdma/krping/krping.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/rdma/krping/krping.h Wed Jul 25 16:45:04 2012 +0300
@@ -1,7 +1,7 @@
/*
- * $FreeBSD$
+ * $FreeBSD: head/sys/contrib/rdma/krping/krping.h 237263 2012-06-19 07:34:13Z np $
*/
-#include <contrib/rdma/ib_verbs.h>
+#include <rdma/ib_verbs.h>
#include <netinet/in.h>
/*
@@ -92,6 +92,8 @@
int count; /* ping count */
int size; /* ping data size */
int validate; /* validate ping data */
+ uint64_t memlimit; /* limit of the physical memory that
+ can be registered with dma_mr mode */
/* CM stuff */
struct rdma_cm_id *cm_id; /* connection on client side,*/
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/rdma/krping/krping_dev.c
--- a/head/sys/contrib/rdma/krping/krping_dev.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/rdma/krping/krping_dev.c Wed Jul 25 16:45:04 2012 +0300
@@ -11,10 +11,9 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/contrib/rdma/krping/krping_dev.c 237263 2012-06-19 07:34:13Z np $");
#include <sys/types.h>
-#include <sys/module.h>
#include <sys/systm.h> /* uprintf */
#include <sys/errno.h>
#include <sys/param.h> /* defines used in kernel.h */
@@ -51,6 +50,9 @@
/* vars */
static struct cdev *krping_dev;
+#undef MODULE_VERSION
+#include <sys/module.h>
+
static int
krping_loader(struct module *m, int what, void *arg)
{
@@ -175,6 +177,4 @@
return(err);
}
-MODULE_DEPEND(krping, rdma_core, 1, 1, 1);
-MODULE_DEPEND(krping, rdma_cma, 1, 1, 1);
DEV_MODULE(krping,krping_loader,NULL);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/rdma/rdma_addr.c
--- a/head/sys/contrib/rdma/rdma_addr.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/rdma/rdma_addr.c Wed Jul 25 16:45:04 2012 +0300
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/contrib/rdma/rdma_addr.c 237263 2012-06-19 07:34:13Z np $");
#include <sys/param.h>
#include <sys/condvar.h>
@@ -117,7 +117,8 @@
const unsigned char *dst_dev_addr)
{
dev_addr->dev_type = RDMA_NODE_RNIC;
- memcpy(dev_addr->src_dev_addr, IF_LLADDR(dev), MAX_ADDR_LEN);
+ memset(dev_addr->src_dev_addr, 0, MAX_ADDR_LEN);
+ memcpy(dev_addr->src_dev_addr, IF_LLADDR(dev), dev->if_addrlen);
memcpy(dev_addr->broadcast, dev->if_broadcastaddr, MAX_ADDR_LEN);
if (dst_dev_addr)
memcpy(dev_addr->dst_dev_addr, dst_dev_addr, MAX_ADDR_LEN);
@@ -207,7 +208,7 @@
goto put;
}
ret = arpresolve(iproute.ro_rt->rt_ifp, iproute.ro_rt, NULL,
- rt_key(iproute.ro_rt), dmac, &lle);
+ (struct sockaddr *)dst_in, dmac, &lle);
if (ret) {
goto put;
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/contrib/rdma/rdma_cache.c
--- a/head/sys/contrib/rdma/rdma_cache.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/contrib/rdma/rdma_cache.c Wed Jul 25 16:45:04 2012 +0300
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/contrib/rdma/rdma_cache.c 237263 2012-06-19 07:34:13Z np $");
#include <sys/types.h>
@@ -132,7 +132,7 @@
for (p = 0; p <= end_port(device) - start_port(device); ++p) {
cache = device->cache.gid_cache[p];
for (i = 0; i < cache->table_len; ++i) {
- if (!memcmp(gid, &cache->table[i], 6)) { /* XXX */
+ if (!memcmp(gid, &cache->table[i], sizeof *gid)) {
*port_num = p + start_port(device);
if (index)
*index = i;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/bde/g_bde.c
--- a/head/sys/geom/bde/g_bde.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/bde/g_bde.c Wed Jul 25 16:45:04 2012 +0300
@@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/geom/bde/g_bde.c 238198 2012-07-07 17:09:44Z trasz $
*
*/
@@ -77,19 +77,15 @@
struct g_geom *gp;
struct g_provider *pp;
struct g_bde_softc *sc;
- int error;
g_trace(G_T_TOPOLOGY, "g_bde_orphan(%p/%s)", cp, cp->provider->name);
g_topology_assert();
- KASSERT(cp->provider->error != 0,
- ("g_bde_orphan with error == 0"));
gp = cp->geom;
sc = gp->softc;
gp->flags |= G_GEOM_WITHER;
- error = cp->provider->error;
LIST_FOREACH(pp, &gp->provider, provider)
- g_orphan_provider(pp, error);
+ g_orphan_provider(pp, ENXIO);
bzero(sc, sizeof(struct g_bde_softc)); /* destroy evidence */
return;
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/eli/g_eli.c
--- a/head/sys/geom/eli/g_eli.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/eli/g_eli.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/eli/g_eli.c 228634 2011-12-17 15:26:34Z avg $");
+__FBSDID("$FreeBSD: head/sys/geom/eli/g_eli.c 238116 2012-07-04 17:54:17Z pjd $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -726,6 +726,8 @@
(sc->sc_flags & G_ELI_FLAG_AUTH) != 0) {
sc->sc_flags |= G_ELI_FLAG_FIRST_KEY;
}
+ if (md->md_version < G_ELI_VERSION_07)
+ sc->sc_flags |= G_ELI_FLAG_ENC_IVKEY;
sc->sc_ealgo = md->md_ealgo;
sc->sc_nkey = nkey;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/eli/g_eli.h
--- a/head/sys/geom/eli/g_eli.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/eli/g_eli.h Wed Jul 25 16:45:04 2012 +0300
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/geom/eli/g_eli.h 226840 2011-10-27 16:12:25Z pjd $
+ * $FreeBSD: head/sys/geom/eli/g_eli.h 238116 2012-07-04 17:54:17Z pjd $
*/
#ifndef _G_ELI_H_
@@ -68,6 +68,8 @@
* 5 - Added multiple encrypton keys and AES-XTS support.
* 6 - Fixed usage of multiple keys for authenticated providers (the
* G_ELI_FLAG_FIRST_KEY flag will be set for older versions).
+ * 7 - Encryption keys are now generated from the Data Key and not from the
+ * IV Key (the G_ELI_FLAG_ENC_IVKEY flag will be set for older versions).
*/
#define G_ELI_VERSION_00 0
#define G_ELI_VERSION_01 1
@@ -76,7 +78,8 @@
#define G_ELI_VERSION_04 4
#define G_ELI_VERSION_05 5
#define G_ELI_VERSION_06 6
-#define G_ELI_VERSION G_ELI_VERSION_06
+#define G_ELI_VERSION_07 7
+#define G_ELI_VERSION G_ELI_VERSION_07
/* ON DISK FLAGS. */
/* Use random, onetime keys. */
@@ -104,6 +107,8 @@
#define G_ELI_FLAG_SUSPEND 0x00100000
/* Provider uses first encryption key. */
#define G_ELI_FLAG_FIRST_KEY 0x00200000
+/* Provider uses IV-Key for encryption key generation. */
+#define G_ELI_FLAG_ENC_IVKEY 0x00400000
#define G_ELI_NEW_BIO 255
@@ -237,7 +242,7 @@
*datap = p;
}
static __inline void
-eli_metadata_encode_v1v2v3v4v5v6(struct g_eli_metadata *md, u_char **datap)
+eli_metadata_encode_v1v2v3v4v5v6v7(struct g_eli_metadata *md, u_char **datap)
{
u_char *p;
@@ -275,7 +280,8 @@
case G_ELI_VERSION_04:
case G_ELI_VERSION_05:
case G_ELI_VERSION_06:
- eli_metadata_encode_v1v2v3v4v5v6(md, &p);
+ case G_ELI_VERSION_07:
+ eli_metadata_encode_v1v2v3v4v5v6v7(md, &p);
break;
default:
#ifdef _KERNEL
@@ -315,7 +321,7 @@
}
static __inline int
-eli_metadata_decode_v1v2v3v4v5v6(const u_char *data, struct g_eli_metadata *md)
+eli_metadata_decode_v1v2v3v4v5v6v7(const u_char *data, struct g_eli_metadata *md)
{
MD5_CTX ctx;
const u_char *p;
@@ -357,7 +363,8 @@
case G_ELI_VERSION_04:
case G_ELI_VERSION_05:
case G_ELI_VERSION_06:
- error = eli_metadata_decode_v1v2v3v4v5v6(data, md);
+ case G_ELI_VERSION_07:
+ error = eli_metadata_decode_v1v2v3v4v5v6v7(data, md);
break;
default:
error = EOPNOTSUPP;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/eli/g_eli_ctl.c
--- a/head/sys/geom/eli/g_eli_ctl.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/eli/g_eli_ctl.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/eli/g_eli_ctl.c 221630 2011-05-08 09:25:54Z pjd $");
+__FBSDID("$FreeBSD: head/sys/geom/eli/g_eli_ctl.c 238116 2012-07-04 17:54:17Z pjd $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -1020,6 +1020,12 @@
/* Compatible. */
break;
}
+ if (G_ELI_VERSION == G_ELI_VERSION_07 &&
+ (*version == G_ELI_VERSION_05 ||
+ *version == G_ELI_VERSION_06)) {
+ /* Compatible. */
+ break;
+ }
gctl_error(req, "Userland and kernel parts are out of sync.");
return;
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/eli/g_eli_integrity.c
--- a/head/sys/geom/eli/g_eli_integrity.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/eli/g_eli_integrity.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/eli/g_eli_integrity.c 221628 2011-05-08 09:17:56Z pjd $");
+__FBSDID("$FreeBSD: head/sys/geom/eli/g_eli_integrity.c 235419 2012-05-13 23:27:06Z eadler $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -205,8 +205,8 @@
* Report previous corruption if there was one.
*/
if (coroff != -1) {
- G_ELI_DEBUG(0, "%s: %jd bytes "
- "corrupted at offset %jd.",
+ G_ELI_DEBUG(0, "%s: Failed to authenticate %jd "
+ "bytes of data at offset %jd.",
sc->sc_name, (intmax_t)corsize,
(intmax_t)coroff);
coroff = -1;
@@ -221,7 +221,8 @@
}
/* Report previous corruption if there was one. */
if (coroff != -1) {
- G_ELI_DEBUG(0, "%s: %jd bytes corrupted at offset %jd.",
+ G_ELI_DEBUG(0, "%s: Failed to authenticate %jd "
+ "bytes of data at offset %jd.",
sc->sc_name, (intmax_t)corsize, (intmax_t)coroff);
}
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/eli/g_eli_key.c
--- a/head/sys/geom/eli/g_eli_key.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/eli/g_eli_key.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/eli/g_eli_key.c 220922 2011-04-21 13:31:43Z pjd $");
+__FBSDID("$FreeBSD: head/sys/geom/eli/g_eli_key.c 238114 2012-07-04 17:43:25Z pjd $");
#include <sys/param.h>
#ifdef _KERNEL
@@ -197,7 +197,7 @@
mkey += sizeof(sc->sc_ivkey);
/*
- * The authentication key is: akey = HMAC_SHA512(Master-Key, 0x11)
+ * The authentication key is: akey = HMAC_SHA512(Data-Key, 0x11)
*/
if ((sc->sc_flags & G_ELI_FLAG_AUTH) != 0) {
g_eli_crypto_hmac(mkey, G_ELI_MAXKEYLEN, "\x11", 1,
@@ -209,7 +209,7 @@
/* Initialize encryption keys. */
g_eli_key_init(sc);
- if (sc->sc_flags & G_ELI_FLAG_AUTH) {
+ if ((sc->sc_flags & G_ELI_FLAG_AUTH) != 0) {
/*
* Precalculate SHA256 for HMAC key generation.
* This is expensive operation and we can do it only once now or
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/eli/g_eli_key_cache.c
--- a/head/sys/geom/eli/g_eli_key_cache.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/eli/g_eli_key_cache.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/eli/g_eli_key_cache.c 221953 2011-05-15 12:39:30Z trociny $");
+__FBSDID("$FreeBSD: head/sys/geom/eli/g_eli_key_cache.c 238116 2012-07-04 17:54:17Z pjd $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -91,14 +91,20 @@
static void
g_eli_key_fill(struct g_eli_softc *sc, struct g_eli_key *key, uint64_t keyno)
{
+ const uint8_t *ekey;
struct {
char magic[4];
uint8_t keyno[8];
} __packed hmacdata;
+ if ((sc->sc_flags & G_ELI_FLAG_ENC_IVKEY) != 0)
+ ekey = sc->sc_mkey;
+ else
+ ekey = sc->sc_ekey;
+
bcopy("ekey", hmacdata.magic, 4);
le64enc(hmacdata.keyno, keyno);
- g_eli_crypto_hmac(sc->sc_mkey, G_ELI_MAXKEYLEN, (uint8_t *)&hmacdata,
+ g_eli_crypto_hmac(ekey, G_ELI_MAXKEYLEN, (uint8_t *)&hmacdata,
sizeof(hmacdata), key->gek_key, 0);
key->gek_keyno = keyno;
key->gek_count = 0;
@@ -200,7 +206,7 @@
bcopy(mkey, sc->sc_ekey, G_ELI_DATAKEYLEN);
else {
/*
- * The encryption key is: ekey = HMAC_SHA512(Master-Key, 0x10)
+ * The encryption key is: ekey = HMAC_SHA512(Data-Key, 0x10)
*/
g_eli_crypto_hmac(mkey, G_ELI_MAXKEYLEN, "\x10", 1,
sc->sc_ekey, 0);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/gate/g_gate.c
--- a/head/sys/geom/gate/g_gate.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/gate/g_gate.c Wed Jul 25 16:45:04 2012 +0300
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/gate/g_gate.c 227309 2011-11-07 15:43:11Z ed $");
+__FBSDID("$FreeBSD: head/sys/geom/gate/g_gate.c 238119 2012-07-04 20:16:28Z pjd $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -60,7 +60,7 @@
SYSCTL_DECL(_kern_geom);
static SYSCTL_NODE(_kern_geom, OID_AUTO, gate, CTLFLAG_RW, 0,
- "GEOM_GATE stuff");
+ "GEOM_GATE configuration");
static int g_gate_debug = 0;
TUNABLE_INT("kern.geom.gate.debug", &g_gate_debug);
SYSCTL_INT(_kern_geom_gate, OID_AUTO, debug, CTLFLAG_RW, &g_gate_debug, 0,
@@ -92,6 +92,7 @@
g_gate_destroy(struct g_gate_softc *sc, boolean_t force)
{
struct g_provider *pp;
+ struct g_consumer *cp;
struct g_geom *gp;
struct bio *bp;
@@ -138,6 +139,12 @@
mtx_unlock(&g_gate_units_lock);
mtx_destroy(&sc->sc_queue_mtx);
g_topology_lock();
+ if ((cp = sc->sc_readcons) != NULL) {
+ sc->sc_readcons = NULL;
+ (void)g_access(cp, -1, 0, 0);
+ g_detach(cp);
+ g_destroy_consumer(cp);
+ }
G_GATE_DEBUG(1, "Device %s destroyed.", gp->name);
gp->softc = NULL;
g_wither_geom(gp, ENXIO);
@@ -167,7 +174,7 @@
}
static void
-g_gate_start(struct bio *bp)
+g_gate_queue_io(struct bio *bp)
{
struct g_gate_softc *sc;
@@ -176,27 +183,9 @@
g_io_deliver(bp, ENXIO);
return;
}
- G_GATE_LOGREQ(2, bp, "Request received.");
- switch (bp->bio_cmd) {
- case BIO_READ:
- break;
- case BIO_DELETE:
- case BIO_WRITE:
- case BIO_FLUSH:
- /* XXX: Hack to allow read-only mounts. */
- if ((sc->sc_flags & G_GATE_FLAG_READONLY) != 0) {
- g_io_deliver(bp, EPERM);
- return;
- }
- break;
- case BIO_GETATTR:
- default:
- G_GATE_LOGREQ(2, bp, "Ignoring request.");
- g_io_deliver(bp, EOPNOTSUPP);
- return;
- }
mtx_lock(&sc->sc_queue_mtx);
+
if (sc->sc_queue_size > 0 && sc->sc_queue_count > sc->sc_queue_size) {
mtx_unlock(&sc->sc_queue_mtx);
G_GATE_LOGREQ(1, bp, "Queue full, request canceled.");
@@ -214,6 +203,74 @@
mtx_unlock(&sc->sc_queue_mtx);
}
+static void
+g_gate_done(struct bio *cbp)
+{
+ struct bio *pbp;
+
+ pbp = cbp->bio_parent;
+ if (cbp->bio_error == 0) {
+ pbp->bio_completed = cbp->bio_completed;
+ g_destroy_bio(cbp);
+ pbp->bio_inbed++;
+ g_io_deliver(pbp, 0);
+ } else {
+ /* If direct read failed, pass it through userland daemon. */
+ g_destroy_bio(cbp);
+ pbp->bio_children--;
+ g_gate_queue_io(pbp);
+ }
+}
+
+static void
+g_gate_start(struct bio *pbp)
+{
+ struct g_gate_softc *sc;
+
+ sc = pbp->bio_to->geom->softc;
+ if (sc == NULL || (sc->sc_flags & G_GATE_FLAG_DESTROY) != 0) {
+ g_io_deliver(pbp, ENXIO);
+ return;
+ }
+ G_GATE_LOGREQ(2, pbp, "Request received.");
+ switch (pbp->bio_cmd) {
+ case BIO_READ:
+ if (sc->sc_readcons != NULL) {
+ struct bio *cbp;
+
+ cbp = g_clone_bio(pbp);
+ if (cbp == NULL) {
+ g_io_deliver(pbp, ENOMEM);
+ return;
+ }
+ cbp->bio_done = g_gate_done;
+ cbp->bio_offset = pbp->bio_offset + sc->sc_readoffset;
+ cbp->bio_data = pbp->bio_data;
+ cbp->bio_length = pbp->bio_length;
+ cbp->bio_to = sc->sc_readcons->provider;
+ g_io_request(cbp, sc->sc_readcons);
+ return;
+ }
+ break;
+ case BIO_DELETE:
+ case BIO_WRITE:
+ case BIO_FLUSH:
+ /* XXX: Hack to allow read-only mounts. */
+ if ((sc->sc_flags & G_GATE_FLAG_READONLY) != 0) {
+ g_io_deliver(pbp, EPERM);
+ return;
+ }
+ break;
+ case BIO_GETATTR:
+ default:
+ G_GATE_LOGREQ(2, pbp, "Ignoring request.");
+ g_io_deliver(pbp, EOPNOTSUPP);
+ return;
+ }
+
+ g_gate_queue_io(pbp);
+}
+
static struct g_gate_softc *
g_gate_hold(int unit, const char *name)
{
@@ -312,6 +369,27 @@
}
static void
+g_gate_orphan(struct g_consumer *cp)
+{
+ struct g_gate_softc *sc;
+ struct g_geom *gp;
+
+ g_topology_assert();
+ gp = cp->geom;
+ sc = gp->softc;
+ if (sc == NULL)
+ return;
+ KASSERT(cp == sc->sc_readcons, ("cp=%p sc_readcons=%p", cp,
+ sc->sc_readcons));
+ sc->sc_readcons = NULL;
+ G_GATE_DEBUG(1, "Destroying read consumer on provider %s orphan.",
+ cp->provider->name);
+ (void)g_access(cp, -1, 0, 0);
+ g_detach(cp);
+ g_destroy_consumer(cp);
+}
+
+static void
g_gate_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
struct g_consumer *cp, struct g_provider *pp)
{
@@ -330,6 +408,12 @@
sbuf_printf(sb, "%s<access>%s</access>\n", indent,
"read-write");
}
+ if (sc->sc_readcons != NULL) {
+ sbuf_printf(sb, "%s<read_offset>%jd</read_offset>\n",
+ indent, (intmax_t)sc->sc_readoffset);
+ sbuf_printf(sb, "%s<read_provider>%s</read_provider>\n",
+ indent, sc->sc_readcons->provider->name);
+ }
sbuf_printf(sb, "%s<timeout>%u</timeout>\n", indent, sc->sc_timeout);
sbuf_printf(sb, "%s<info>%s</info>\n", indent, sc->sc_info);
sbuf_printf(sb, "%s<queue_count>%u</queue_count>\n", indent,
@@ -348,15 +432,20 @@
{
struct g_gate_softc *sc;
struct g_geom *gp;
- struct g_provider *pp;
+ struct g_provider *pp, *ropp;
+ struct g_consumer *cp;
char name[NAME_MAX];
int error = 0, unit;
- if (ggio->gctl_mediasize == 0) {
+ if (ggio->gctl_mediasize <= 0) {
G_GATE_DEBUG(1, "Invalid media size.");
return (EINVAL);
}
- if (ggio->gctl_sectorsize > 0 && !powerof2(ggio->gctl_sectorsize)) {
+ if (ggio->gctl_sectorsize <= 0) {
+ G_GATE_DEBUG(1, "Invalid sector size.");
+ return (EINVAL);
+ }
+ if (!powerof2(ggio->gctl_sectorsize)) {
G_GATE_DEBUG(1, "Invalid sector size.");
return (EINVAL);
}
@@ -381,6 +470,31 @@
return (EINVAL);
}
+ g_topology_lock();
+
+ if (ggio->gctl_readprov[0] == '\0') {
+ ropp = NULL;
+ } else {
+ ropp = g_provider_by_name(ggio->gctl_readprov);
+ if (ropp == NULL) {
+ g_topology_unlock();
+ G_GATE_DEBUG(1, "Provider %s doesn't exist.",
+ ggio->gctl_readprov);
+ return (EINVAL);
+ }
+ if ((ggio->gctl_readoffset % ggio->gctl_sectorsize) != 0) {
+ g_topology_unlock();
+ G_GATE_DEBUG(1, "Invalid read offset.");
+ return (EINVAL);
+ }
+ if (ggio->gctl_mediasize + ggio->gctl_readoffset >
+ ropp->mediasize) {
+ g_topology_unlock();
+ G_GATE_DEBUG(1, "Invalid read offset or media size.");
+ return (EINVAL);
+ }
+ }
+
sc = malloc(sizeof(*sc), M_GATE, M_WAITOK | M_ZERO);
sc->sc_flags = (ggio->gctl_flags & G_GATE_USERFLAGS);
strlcpy(sc->sc_info, ggio->gctl_info, sizeof(sc->sc_info));
@@ -394,10 +508,50 @@
sc->sc_queue_size = G_GATE_MAX_QUEUE_SIZE;
sc->sc_timeout = ggio->gctl_timeout;
callout_init(&sc->sc_callout, CALLOUT_MPSAFE);
+
+ gp = g_new_geomf(&g_gate_class, "%s", name);
+ gp->start = g_gate_start;
+ gp->access = g_gate_access;
+ gp->orphan = g_gate_orphan;
+ gp->dumpconf = g_gate_dumpconf;
+ gp->softc = sc;
+
+ if (ropp != NULL) {
+ cp = g_new_consumer(gp);
+ error = g_attach(cp, ropp);
+ if (error != 0) {
+ G_GATE_DEBUG(1, "Unable to attach to %s.", ropp->name);
+ } else {
+ error = g_access(cp, 1, 0, 0);
+ if (error != 0) {
+ G_GATE_DEBUG(1, "Unable to access %s.",
+ ropp->name);
+ g_detach(cp);
+ }
+ }
+ if (error != 0) {
+ g_destroy_consumer(cp);
+ g_destroy_geom(gp);
+ g_topology_unlock();
+ mtx_destroy(&sc->sc_queue_mtx);
+ free(sc, M_GATE);
+ return (error);
+ }
+ sc->sc_readcons = cp;
+ sc->sc_readoffset = ggio->gctl_readoffset;
+ }
+
mtx_lock(&g_gate_units_lock);
sc->sc_unit = g_gate_getunit(ggio->gctl_unit, &error);
if (sc->sc_unit < 0) {
mtx_unlock(&g_gate_units_lock);
+ if (sc->sc_readcons != NULL) {
+ (void)g_access(sc->sc_readcons, -1, 0, 0);
+ g_detach(sc->sc_readcons);
+ g_destroy_consumer(sc->sc_readcons);
+ }
+ g_destroy_geom(gp);
+ g_topology_unlock();
mtx_destroy(&sc->sc_queue_mtx);
free(sc, M_GATE);
return (error);
@@ -415,6 +569,13 @@
if (strcmp(name, g_gate_units[unit]->sc_name) != 0)
continue;
mtx_unlock(&g_gate_units_lock);
+ if (sc->sc_readcons != NULL) {
+ (void)g_access(sc->sc_readcons, -1, 0, 0);
+ g_detach(sc->sc_readcons);
+ g_destroy_consumer(sc->sc_readcons);
+ }
+ g_destroy_geom(gp);
+ g_topology_unlock();
mtx_destroy(&sc->sc_queue_mtx);
free(sc, M_GATE);
return (EEXIST);
@@ -426,17 +587,12 @@
ggio->gctl_unit = sc->sc_unit;
- g_topology_lock();
- gp = g_new_geomf(&g_gate_class, "%s", name);
- gp->start = g_gate_start;
- gp->access = g_gate_access;
- gp->dumpconf = g_gate_dumpconf;
- gp->softc = sc;
pp = g_new_providerf(gp, "%s", name);
pp->mediasize = ggio->gctl_mediasize;
pp->sectorsize = ggio->gctl_sectorsize;
sc->sc_provider = pp;
g_error_provider(pp, 0);
+
g_topology_unlock();
mtx_lock(&g_gate_units_lock);
sc->sc_name = sc->sc_provider->name;
@@ -450,6 +606,98 @@
return (0);
}
+static int
+g_gate_modify(struct g_gate_softc *sc, struct g_gate_ctl_modify *ggio)
+{
+ struct g_provider *pp;
+ struct g_consumer *cp;
+ int error;
+
+ if ((ggio->gctl_modify & GG_MODIFY_MEDIASIZE) != 0) {
+ if (ggio->gctl_mediasize <= 0) {
+ G_GATE_DEBUG(1, "Invalid media size.");
+ return (EINVAL);
+ }
+ pp = sc->sc_provider;
+ if ((ggio->gctl_mediasize % pp->sectorsize) != 0) {
+ G_GATE_DEBUG(1, "Invalid media size.");
+ return (EINVAL);
+ }
+ /* TODO */
+ return (EOPNOTSUPP);
+ }
+
+ if ((ggio->gctl_modify & GG_MODIFY_INFO) != 0)
+ (void)strlcpy(sc->sc_info, ggio->gctl_info, sizeof(sc->sc_info));
+
+ cp = NULL;
+
+ if ((ggio->gctl_modify & GG_MODIFY_READPROV) != 0) {
+ g_topology_lock();
+ if (sc->sc_readcons != NULL) {
+ cp = sc->sc_readcons;
+ sc->sc_readcons = NULL;
+ (void)g_access(cp, -1, 0, 0);
+ g_detach(cp);
+ g_destroy_consumer(cp);
+ }
+ if (ggio->gctl_readprov[0] != '\0') {
+ pp = g_provider_by_name(ggio->gctl_readprov);
+ if (pp == NULL) {
+ g_topology_unlock();
+ G_GATE_DEBUG(1, "Provider %s doesn't exist.",
+ ggio->gctl_readprov);
+ return (EINVAL);
+ }
+ cp = g_new_consumer(sc->sc_provider->geom);
+ error = g_attach(cp, pp);
+ if (error != 0) {
+ G_GATE_DEBUG(1, "Unable to attach to %s.",
+ pp->name);
+ } else {
+ error = g_access(cp, 1, 0, 0);
+ if (error != 0) {
+ G_GATE_DEBUG(1, "Unable to access %s.",
+ pp->name);
+ g_detach(cp);
+ }
+ }
+ if (error != 0) {
+ g_destroy_consumer(cp);
+ g_topology_unlock();
+ return (error);
+ }
+ }
+ } else {
+ cp = sc->sc_readcons;
+ }
+
+ if ((ggio->gctl_modify & GG_MODIFY_READOFFSET) != 0) {
+ if (cp == NULL) {
+ G_GATE_DEBUG(1, "No read provider.");
+ return (EINVAL);
+ }
+ pp = sc->sc_provider;
+ if ((ggio->gctl_readoffset % pp->sectorsize) != 0) {
+ G_GATE_DEBUG(1, "Invalid read offset.");
+ return (EINVAL);
+ }
+ if (pp->mediasize + ggio->gctl_readoffset >
+ cp->provider->mediasize) {
+ G_GATE_DEBUG(1, "Invalid read offset or media size.");
+ return (EINVAL);
+ }
+ sc->sc_readoffset = ggio->gctl_readoffset;
+ }
+
+ if ((ggio->gctl_modify & GG_MODIFY_READPROV) != 0) {
+ sc->sc_readcons = cp;
+ g_topology_unlock();
+ }
+
+ return (0);
+}
+
#define G_GATE_CHECK_VERSION(ggio) do { \
if ((ggio)->gctl_version != G_GATE_VERSION) { \
printf("Version mismatch %d != %d.\n", \
@@ -483,6 +731,18 @@
td->td_pflags &= ~TDP_GEOM;
return (error);
}
+ case G_GATE_CMD_MODIFY:
+ {
+ struct g_gate_ctl_modify *ggio = (void *)addr;
+
+ G_GATE_CHECK_VERSION(ggio);
+ sc = g_gate_hold(ggio->gctl_unit, NULL);
+ if (sc == NULL)
+ return (ENXIO);
+ error = g_gate_modify(sc, ggio);
+ g_gate_release(sc);
+ return (error);
+ }
case G_GATE_CMD_DESTROY:
{
struct g_gate_ctl_destroy *ggio = (void *)addr;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/gate/g_gate.h
--- a/head/sys/geom/gate/g_gate.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/gate/g_gate.h Wed Jul 25 16:45:04 2012 +0300
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/geom/gate/g_gate.h 238119 2012-07-04 20:16:28Z pjd $
*/
#ifndef _G_GATE_H_
@@ -41,7 +41,7 @@
#define G_GATE_MOD_NAME "ggate"
#define G_GATE_CTL_NAME "ggctl"
-#define G_GATE_VERSION 2
+#define G_GATE_VERSION 3
/*
* Maximum number of request that can be stored in
@@ -64,10 +64,11 @@
#define G_GATE_NAME_GIVEN (-2)
#define G_GATE_CMD_CREATE _IOWR('m', 0, struct g_gate_ctl_create)
-#define G_GATE_CMD_DESTROY _IOWR('m', 1, struct g_gate_ctl_destroy)
-#define G_GATE_CMD_CANCEL _IOWR('m', 2, struct g_gate_ctl_cancel)
-#define G_GATE_CMD_START _IOWR('m', 3, struct g_gate_ctl_io)
-#define G_GATE_CMD_DONE _IOWR('m', 4, struct g_gate_ctl_io)
+#define G_GATE_CMD_MODIFY _IOWR('m', 1, struct g_gate_ctl_modify)
+#define G_GATE_CMD_DESTROY _IOWR('m', 2, struct g_gate_ctl_destroy)
+#define G_GATE_CMD_CANCEL _IOWR('m', 3, struct g_gate_ctl_cancel)
+#define G_GATE_CMD_START _IOWR('m', 4, struct g_gate_ctl_io)
+#define G_GATE_CMD_DONE _IOWR('m', 5, struct g_gate_ctl_io)
#define G_GATE_INFOSIZE 2048
@@ -88,6 +89,8 @@
uint32_t sc_queue_count; /* P: sc_queue_mtx */
uint32_t sc_queue_size; /* P: (read-only) */
u_int sc_timeout; /* P: (read-only) */
+ struct g_consumer *sc_readcons; /* P: XXX */
+ off_t sc_readoffset; /* P: XXX */
struct callout sc_callout; /* P: (modified only
from callout
thread) */
@@ -131,9 +134,25 @@
u_int gctl_timeout;
char gctl_name[NAME_MAX];
char gctl_info[G_GATE_INFOSIZE];
+ char gctl_readprov[NAME_MAX];
+ off_t gctl_readoffset;
int gctl_unit; /* in/out */
};
+#define GG_MODIFY_MEDIASIZE 0x01
+#define GG_MODIFY_INFO 0x02
+#define GG_MODIFY_READPROV 0x04
+#define GG_MODIFY_READOFFSET 0x08
+struct g_gate_ctl_modify {
+ u_int gctl_version;
+ int gctl_unit;
+ uint32_t gctl_modify;
+ off_t gctl_mediasize;
+ char gctl_info[G_GATE_INFOSIZE];
+ char gctl_readprov[NAME_MAX];
+ off_t gctl_readoffset;
+};
+
struct g_gate_ctl_destroy {
u_int gctl_version;
int gctl_unit;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/geom.h
--- a/head/sys/geom/geom.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/geom.h Wed Jul 25 16:45:04 2012 +0300
@@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/geom/geom.h 224147 2011-07-17 20:35:30Z pjd $
+ * $FreeBSD: head/sys/geom/geom.h 238559 2012-07-17 22:16:10Z ken $
*/
#ifndef _GEOM_GEOM_H_
@@ -76,8 +76,10 @@
typedef void g_start_t (struct bio *);
typedef void g_spoiled_t (struct g_consumer *);
typedef void g_attrchanged_t (struct g_consumer *, const char *attr);
+typedef void g_provgone_t (struct g_provider *);
typedef void g_dumpconf_t (struct sbuf *, const char *indent, struct g_geom *,
struct g_consumer *, struct g_provider *);
+typedef void g_resize_t(struct g_consumer *cp);
/*
* The g_class structure describes a transformation class. In other words
@@ -106,6 +108,8 @@
g_access_t *access;
g_orphan_t *orphan;
g_ioctl_t *ioctl;
+ g_provgone_t *providergone;
+ g_resize_t *resize;
void *spare1;
void *spare2;
/*
@@ -137,6 +141,8 @@
g_access_t *access;
g_orphan_t *orphan;
g_ioctl_t *ioctl;
+ g_provgone_t *providergone;
+ g_resize_t *resize;
void *spare0;
void *spare1;
void *softc;
@@ -264,6 +270,7 @@
struct g_consumer * g_new_consumer(struct g_geom *gp);
struct g_geom * g_new_geomf(struct g_class *mp, const char *fmt, ...);
struct g_provider * g_new_providerf(struct g_geom *gp, const char *fmt, ...);
+void g_resize_provider(struct g_provider *pp, off_t size);
int g_retaste(struct g_class *mp);
void g_spoil(struct g_provider *pp, struct g_consumer *cp);
int g_std_access(struct g_provider *pp, int dr, int dw, int de);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/geom_aes.c
--- a/head/sys/geom/geom_aes.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/geom_aes.c Wed Jul 25 16:45:04 2012 +0300
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/geom/geom_aes.c 238198 2012-07-07 17:09:44Z trasz $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -241,12 +241,10 @@
g_trace(G_T_TOPOLOGY, "g_aes_orphan(%p/%s)", cp, cp->provider->name);
g_topology_assert();
- KASSERT(cp->provider->error != 0,
- ("g_aes_orphan with error == 0"));
gp = cp->geom;
sc = gp->softc;
- g_wither_geom(gp, cp->provider->error);
+ g_wither_geom(gp, ENXIO);
bzero(sc, sizeof(struct g_aes_softc)); /* destroy evidence */
g_free(sc);
return;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/geom_dev.c
--- a/head/sys/geom/geom_dev.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/geom_dev.c Wed Jul 25 16:45:04 2012 +0300
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/geom_dev.c 227510 2011-11-14 19:32:05Z mav $");
+__FBSDID("$FreeBSD: head/sys/geom/geom_dev.c 238171 2012-07-06 15:46:38Z trasz $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -497,7 +497,7 @@
*
* Called from below when the provider orphaned us.
* - Clear any dump settings.
- * - Destroy the struct cdev *to prevent any more request from coming in. The
+ * - Destroy the struct cdev to prevent any more request from coming in. The
* provider is already marked with an error, so anything which comes in
* in the interrim will be returned immediately.
* - Wait for any outstanding I/O to finish.
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/geom_disk.c
--- a/head/sys/geom/geom_disk.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/geom_disk.c Wed Jul 25 16:45:04 2012 +0300
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/geom_disk.c 227309 2011-11-07 15:43:11Z ed $");
+__FBSDID("$FreeBSD: head/sys/geom/geom_disk.c 238216 2012-07-07 21:28:31Z trasz $");
#include "opt_geom.h"
@@ -48,6 +48,7 @@
#include <sys/malloc.h>
#include <sys/sbuf.h>
#include <sys/sysctl.h>
+#include <sys/taskqueue.h>
#include <sys/devicestat.h>
#include <machine/md_var.h>
@@ -65,6 +66,7 @@
struct sysctl_oid *sysctl_tree;
char led[64];
uint32_t state;
+ struct task resize_task;
};
static struct mtx g_disk_done_mtx;
@@ -75,6 +77,7 @@
static g_start_t g_disk_start;
static g_ioctl_t g_disk_ioctl;
static g_dumpconf_t g_disk_dumpconf;
+static g_provgone_t g_disk_providergone;
static struct g_class g_disk_class = {
.name = "DISK",
@@ -84,6 +87,7 @@
.start = g_disk_start,
.access = g_disk_access,
.ioctl = g_disk_ioctl,
+ .providergone = g_disk_providergone,
.dumpconf = g_disk_dumpconf,
};
@@ -443,6 +447,27 @@
}
static void
+g_disk_resize_task(void *context, int pending)
+{
+ struct g_geom *gp;
+ struct g_provider *pp;
+ struct disk *dp;
+ struct g_disk_softc *sc;
+
+ sc = (struct g_disk_softc *)context;
+ dp = sc->dp;
+ gp = dp->d_geom;
+
+ LIST_FOREACH(pp, &gp->provider, provider) {
+ if (pp->sectorsize != 0 &&
+ pp->sectorsize != dp->d_sectorsize)
+ g_wither_provider(pp, ENXIO);
+ else
+ g_resize_provider(pp, dp->d_mediasize);
+ }
+}
+
+static void
g_disk_create(void *arg, int flag)
{
struct g_geom *gp;
@@ -482,11 +507,39 @@
CTLFLAG_RW | CTLFLAG_TUN, sc->led, sizeof(sc->led),
"LED name");
}
+ TASK_INIT(&sc->resize_task, 0, g_disk_resize_task, sc);
pp->private = sc;
dp->d_geom = gp;
g_error_provider(pp, 0);
}
+/*
+ * We get this callback after all of the consumers have gone away, and just
+ * before the provider is freed. If the disk driver provided a d_gone
+ * callback, let them know that it is okay to free resources -- they won't
+ * be getting any more accesses from GEOM.
+ */
+static void
+g_disk_providergone(struct g_provider *pp)
+{
+ struct disk *dp;
+ struct g_disk_softc *sc;
+
+ sc = (struct g_disk_softc *)pp->geom->softc;
+
+ /*
+ * If the softc is already NULL, then we've probably been through
+ * g_disk_destroy already; there is nothing for us to do anyway.
+ */
+ if (sc == NULL)
+ return;
+
+ dp = sc->dp;
+
+ if (dp->d_gone != NULL)
+ dp->d_gone(dp);
+}
+
static void
g_disk_destroy(void *ptr, int flag)
{
@@ -550,7 +603,7 @@
disk_create(struct disk *dp, int version)
{
- if (version != DISK_VERSION_00 && version != DISK_VERSION_01) {
+ if (version != DISK_VERSION_02) {
printf("WARNING: Attempt to add disk %s%d %s",
dp->d_name, dp->d_unit,
" using incompatible ABI version of disk(9)\n");
@@ -606,6 +659,24 @@
(void)g_attr_changed(pp, attr, flag);
}
+void
+disk_resize(struct disk *dp)
+{
+ struct g_geom *gp;
+ struct g_disk_softc *sc;
+ int error;
+
+ gp = dp->d_geom;
+
+ if (gp == NULL)
+ return;
+
+ sc = gp->softc;
+
+ error = taskqueue_enqueue(taskqueue_thread, &sc->resize_task);
+ KASSERT(error == 0, ("taskqueue_enqueue(9) failed."));
+}
+
static void
g_kern_disks(void *p, int flag __unused)
{
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/geom_disk.h
--- a/head/sys/geom/geom_disk.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/geom_disk.h Wed Jul 25 16:45:04 2012 +0300
@@ -31,7 +31,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/geom/geom_disk.h 223089 2011-06-14 17:10:32Z gibbs $
+ * $FreeBSD: head/sys/geom/geom_disk.h 238216 2012-07-07 21:28:31Z trasz $
*/
#ifndef _GEOM_GEOM_DISK_H_
@@ -50,6 +50,7 @@
typedef int disk_close_t(struct disk *);
typedef void disk_strategy_t(struct bio *bp);
typedef int disk_getattr_t(struct bio *bp);
+typedef void disk_gone_t(struct disk *);
typedef int disk_ioctl_t(struct disk *, u_long cmd, void *data,
int fflag, struct thread *td);
/* NB: disk_ioctl_t SHALL be cast'able to d_ioctl_t */
@@ -77,6 +78,7 @@
disk_ioctl_t *d_ioctl;
dumper_t *d_dump;
disk_getattr_t *d_getattr;
+ disk_gone_t *d_gone;
/* Info fields from driver to geom_disk.c. Valid when open */
u_int d_sectorsize;
@@ -107,10 +109,12 @@
void disk_destroy(struct disk *disk);
void disk_gone(struct disk *disk);
void disk_attr_changed(struct disk *dp, const char *attr, int flag);
+void disk_resize(struct disk *dp);
#define DISK_VERSION_00 0x58561059
#define DISK_VERSION_01 0x5856105a
-#define DISK_VERSION DISK_VERSION_01
+#define DISK_VERSION_02 0x5856105b
+#define DISK_VERSION DISK_VERSION_02
#endif /* _KERNEL */
#endif /* _GEOM_GEOM_DISK_H_ */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/geom_flashmap.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/geom/geom_flashmap.c Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,256 @@
+/*-
+ * Copyright (c) 2012 Semihalf
+ * Copyright (c) 2009 Jakub Klama <jakub.klama at uj.edu.pl>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: head/sys/geom/geom_flashmap.c 235858 2012-05-23 20:51:21Z delphij $");
+
+#include <sys/param.h>
+#include <sys/endian.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/fcntl.h>
+#include <sys/malloc.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/slicer.h>
+
+#include <geom/geom.h>
+#include <geom/geom_slice.h>
+#include <geom/geom_disk.h>
+#include <dev/nand/nand_dev.h>
+
+#define FLASHMAP_CLASS_NAME "Flashmap"
+
+struct g_flashmap_slice {
+ off_t sl_start;
+ off_t sl_end;
+ const char *sl_name;
+
+ STAILQ_ENTRY(g_flashmap_slice) sl_link;
+};
+
+STAILQ_HEAD(g_flashmap_head, g_flashmap_slice);
+
+static void g_flashmap_print(struct g_flashmap_slice *);
+static int g_flashmap_modify(struct g_geom *, const char *,
+ int, struct g_flashmap_head *);
+static int g_flashmap_start(struct bio *);
+static int g_flashmap_ioctl(struct g_provider *, u_long, void *,
+ int, struct thread *);
+static void g_flashmap_dumpconf(struct sbuf *, const char *,
+ struct g_geom *, struct g_consumer *, struct g_provider *);
+static struct g_geom *g_flashmap_taste(struct g_class *,
+ struct g_provider *, int);
+static void g_flashmap_config(struct gctl_req *, struct g_class *,
+ const char *);
+static int g_flashmap_load(device_t, struct g_flashmap_head *);
+
+MALLOC_DECLARE(M_FLASHMAP);
+MALLOC_DEFINE(M_FLASHMAP, "geom_flashmap", "GEOM flash memory slicer class");
+
+static void
+g_flashmap_print(struct g_flashmap_slice *slice)
+{
+
+ printf("%08jx-%08jx: %s (%juKB)\n", (uintmax_t)slice->sl_start,
+ (uintmax_t)slice->sl_end, slice->sl_name,
+ (uintmax_t)(slice->sl_end - slice->sl_start) / 1024);
+}
+
+static int
+g_flashmap_modify(struct g_geom *gp, const char *devname, int secsize,
+ struct g_flashmap_head *slices)
+{
+ struct g_flashmap_slice *slice;
+ int i, error;
+
+ g_topology_assert();
+
+ i = 0;
+ STAILQ_FOREACH(slice, slices, sl_link) {
+ if (bootverbose) {
+ printf("%s: slice ", devname);
+ g_flashmap_print(slice);
+ }
+
+ error = g_slice_config(gp, i++, G_SLICE_CONFIG_CHECK,
+ slice->sl_start,
+ slice->sl_end - slice->sl_start + 1,
+ secsize, "%ss.%s", gp->name, slice->sl_name);
+
+ if (error)
+ return (error);
+ }
+
+ i = 0;
+ STAILQ_FOREACH(slice, slices, sl_link) {
+ error = g_slice_config(gp, i++, G_SLICE_CONFIG_SET,
+ slice->sl_start,
+ slice->sl_end - slice->sl_start + 1,
+ secsize, "%ss.%s", gp->name, slice->sl_name);
+
+ if (error)
+ return (error);
+ }
+
+ return (0);
+}
+
+static int
+g_flashmap_start(struct bio *bp)
+{
+
+ return (0);
+}
+
+static void
+g_flashmap_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
+ struct g_consumer *cp __unused, struct g_provider *pp)
+{
+ struct g_slicer *gsp;
+
+ gsp = gp->softc;
+ g_slice_dumpconf(sb, indent, gp, cp, pp);
+}
+
+static int
+g_flashmap_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag,
+ struct thread *td)
+{
+ struct g_consumer *cp;
+ struct g_geom *gp;
+
+ if (cmd != NAND_IO_GET_CHIP_PARAM)
+ return (ENOIOCTL);
+
+ cp = LIST_FIRST(&pp->geom->consumer);
+ if (cp == NULL)
+ return (ENOIOCTL);
+ gp = cp->provider->geom;
+ if (gp->ioctl == NULL)
+ return (ENOIOCTL);
+
+ return (gp->ioctl(cp->provider, cmd, data, fflag, td));
+}
+
+
+static struct g_geom *
+g_flashmap_taste(struct g_class *mp, struct g_provider *pp, int flags)
+{
+ struct g_geom *gp = NULL;
+ struct g_consumer *cp;
+ struct g_flashmap_head head;
+ struct g_flashmap_slice *slice, *slice_temp;
+ device_t dev;
+ int nslices, size;
+
+ g_trace(G_T_TOPOLOGY, "flashmap_taste(%s,%s)", mp->name, pp->name);
+ g_topology_assert();
+
+ if (flags == G_TF_NORMAL &&
+ !strcmp(pp->geom->class->name, FLASHMAP_CLASS_NAME))
+ return (NULL);
+
+ gp = g_slice_new(mp, FLASH_SLICES_MAX_NUM, pp, &cp, NULL, 0,
+ g_flashmap_start);
+ if (gp == NULL)
+ return (NULL);
+
+ STAILQ_INIT(&head);
+
+ do {
+ size = sizeof(device_t);
+ if (g_io_getattr("NAND::device", cp, &size, &dev))
+ break;
+
+ nslices = g_flashmap_load(dev, &head);
+ if (nslices == 0)
+ break;
+
+ g_flashmap_modify(gp, cp->provider->name,
+ cp->provider->sectorsize, &head);
+ } while (0);
+
+ g_access(cp, -1, 0, 0);
+
+ STAILQ_FOREACH_SAFE(slice, &head, sl_link, slice_temp) {
+ free(slice, M_FLASHMAP);
+ }
+
+ if (LIST_EMPTY(&gp->provider)) {
+ g_slice_spoiled(cp);
+ return (NULL);
+ }
+ return (gp);
+}
+
+static void
+g_flashmap_config(struct gctl_req *req, struct g_class *mp, const char *verb)
+{
+
+ gctl_error(req, "unknown config verb");
+}
+
+static int
+g_flashmap_load(device_t dev, struct g_flashmap_head *head)
+{
+ struct flash_slice *slices;
+ struct g_flashmap_slice *slice;
+ uint32_t i, buf_size;
+ int nslices = 0;
+
+ buf_size = sizeof(struct flash_slice) * FLASH_SLICES_MAX_NUM;
+ slices = malloc(buf_size, M_FLASHMAP, M_WAITOK | M_ZERO);
+ if (flash_fill_slices(dev, slices, &nslices) == 0) {
+ for (i = 0; i < nslices; i++) {
+ slice = malloc(sizeof(struct g_flashmap_slice),
+ M_FLASHMAP, M_WAITOK);
+
+ slice->sl_name = slices[i].label;
+ slice->sl_start = slices[i].base;
+ slice->sl_end = slices[i].base + slices[i].size - 1;
+
+ STAILQ_INSERT_TAIL(head, slice, sl_link);
+ }
+ }
+
+ free(slices, M_FLASHMAP);
+ return (nslices);
+}
+
+static struct g_class g_flashmap_class = {
+ .name = FLASHMAP_CLASS_NAME,
+ .version = G_VERSION,
+ .taste = g_flashmap_taste,
+ .dumpconf = g_flashmap_dumpconf,
+ .ioctl = g_flashmap_ioctl,
+ .ctlreq = g_flashmap_config,
+};
+
+DECLARE_GEOM_CLASS(g_flashmap_class, g_flashmap);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/geom_map.c
--- a/head/sys/geom/geom_map.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/geom_map.c Wed Jul 25 16:45:04 2012 +0300
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/geom_map.c 221500 2011-05-05 14:43:09Z adrian $");
+__FBSDID("$FreeBSD: head/sys/geom/geom_map.c 237875 2012-07-01 05:22:13Z imp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -119,13 +119,13 @@
g_slice_dumpconf(sb, indent, gp, cp, pp);
if (pp != NULL) {
if (indent == NULL) {
- sbuf_printf(sb, " entry %jx", sc->entry[pp->index]);
- sbuf_printf(sb, " dsize %zx", sc->dsize[pp->index]);
+ sbuf_printf(sb, " entry %jd", (intmax_t)sc->entry[pp->index]);
+ sbuf_printf(sb, " dsize %jd", (intmax_t)sc->dsize[pp->index]);
} else {
- sbuf_printf(sb, "%s<entry>%jx</entry>\n", indent,
- sc->entry[pp->index]);
- sbuf_printf(sb, "%s<dsize>%zx</dsize>\n", indent,
- sc->dsize[pp->index]);
+ sbuf_printf(sb, "%s<entry>%jd</entry>\n", indent,
+ (intmax_t)sc->entry[pp->index]);
+ sbuf_printf(sb, "%s<dsize>%jd</dsize>\n", indent,
+ (intmax_t)sc->dsize[pp->index]);
}
}
}
@@ -154,7 +154,7 @@
if (bootverbose) {
printf("MAP: search key \"%s\" from 0x%jx, step 0x%jx\n",
- search_key, search_start, search_step);
+ search_key, (intmax_t)search_start, (intmax_t)search_step);
}
/* error if search_key is empty */
@@ -321,9 +321,10 @@
}
if (bootverbose) {
- printf("MAP: %jxx%zx, data=%jxx%zx "
+ printf("MAP: %jxx%jx, data=%jxx%jx "
"\"/dev/map/%s\"\n",
- start, size, offset, dsize, name);
+ (intmax_t)start, (intmax_t)size, (intmax_t)offset,
+ (intmax_t)dsize, name);
}
sc->offset[i] = start;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/geom_slice.c
--- a/head/sys/geom/geom_slice.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/geom_slice.c Wed Jul 25 16:45:04 2012 +0300
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/geom/geom_slice.c 238198 2012-07-07 17:09:44Z trasz $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -523,10 +523,8 @@
g_trace(G_T_TOPOLOGY, "g_slice_orphan(%p/%s)", cp, cp->provider->name);
g_topology_assert();
- KASSERT(cp->provider->error != 0,
- ("g_slice_orphan with error == 0"));
/* XXX: Not good enough we leak the softc and its suballocations */
g_slice_free(cp->geom->softc);
- g_wither_geom(cp->geom, cp->provider->error);
+ g_wither_geom(cp->geom, ENXIO);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/geom_subr.c
--- a/head/sys/geom/geom_subr.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/geom_subr.c Wed Jul 25 16:45:04 2012 +0300
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/geom_subr.c 223089 2011-06-14 17:10:32Z gibbs $");
+__FBSDID("$FreeBSD: head/sys/geom/geom_subr.c 238565 2012-07-18 07:26:20Z trasz $");
#include "opt_ddb.h"
@@ -68,9 +68,11 @@
char *g_wait_event, *g_wait_up, *g_wait_down, *g_wait_sim;
struct g_hh00 {
- struct g_class *mp;
- int error;
- int post;
+ struct g_class *mp;
+ struct g_provider *pp;
+ off_t size;
+ int error;
+ int post;
};
/*
@@ -351,10 +353,12 @@
gp->start = mp->start;
gp->spoiled = mp->spoiled;
gp->attrchanged = mp->attrchanged;
+ gp->providergone = mp->providergone;
gp->dumpconf = mp->dumpconf;
gp->access = mp->access;
gp->orphan = mp->orphan;
gp->ioctl = mp->ioctl;
+ gp->resize = mp->resize;
return (gp);
}
@@ -600,6 +604,75 @@
pp->error = error;
}
+static void
+g_resize_provider_event(void *arg, int flag)
+{
+ struct g_hh00 *hh;
+ struct g_class *mp;
+ struct g_geom *gp;
+ struct g_provider *pp;
+ struct g_consumer *cp, *cp2;
+ off_t size;
+
+ g_topology_assert();
+ if (g_shutdown)
+ return;
+
+ hh = arg;
+ pp = hh->pp;
+ size = hh->size;
+ g_free(hh);
+
+ G_VALID_PROVIDER(pp);
+ g_trace(G_T_TOPOLOGY, "g_resize_provider_event(%p)", pp);
+
+ LIST_FOREACH_SAFE(cp, &pp->consumers, consumers, cp2) {
+ gp = cp->geom;
+ if (gp->resize == NULL && size < pp->mediasize)
+ cp->geom->orphan(cp);
+ }
+
+ pp->mediasize = size;
+
+ LIST_FOREACH_SAFE(cp, &pp->consumers, consumers, cp2) {
+ gp = cp->geom;
+ if (gp->resize != NULL)
+ gp->resize(cp);
+ }
+
+ /*
+ * After resizing, the previously invalid GEOM class metadata
+ * might become valid. This means we should retaste.
+ */
+ LIST_FOREACH(mp, &g_classes, class) {
+ if (mp->taste == NULL)
+ continue;
+ LIST_FOREACH(cp, &pp->consumers, consumers)
+ if (cp->geom->class == mp)
+ break;
+ if (cp != NULL)
+ continue;
+ mp->taste(mp, pp, 0);
+ g_topology_assert();
+ }
+}
+
+void
+g_resize_provider(struct g_provider *pp, off_t size)
+{
+ struct g_hh00 *hh;
+
+ G_VALID_PROVIDER(pp);
+
+ if (size == pp->mediasize)
+ return;
+
+ hh = g_malloc(sizeof *hh, M_WAITOK | M_ZERO);
+ hh->pp = pp;
+ hh->size = size;
+ g_post_event(g_resize_provider_event, hh, M_WAITOK, NULL);
+}
+
struct g_provider *
g_provider_by_name(char const *arg)
{
@@ -634,6 +707,13 @@
LIST_REMOVE(pp, provider);
gp = pp->geom;
devstat_remove_entry(pp->stat);
+ /*
+ * If a callback was provided, send notification that the provider
+ * is now gone.
+ */
+ if (gp->providergone != NULL)
+ gp->providergone(pp);
+
g_free(pp);
if ((gp->flags & G_GEOM_WITHER))
g_do_wither();
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/label/g_label_ufs.c
--- a/head/sys/geom/label/g_label_ufs.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/label/g_label_ufs.c Wed Jul 25 16:45:04 2012 +0300
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/geom/label/g_label_ufs.c 235989 2012-05-25 10:08:48Z trasz $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -81,7 +81,11 @@
fs = (struct fs *)g_read_data(cp, superblock, SBLOCKSIZE, NULL);
if (fs == NULL)
continue;
- /* Check for magic and make sure things are the right size */
+ /* Check for magic. We also need to check if file system size is equal
+ * to providers size, because sysinstall(8) used to bogusly put first
+ * partition at offset 0 instead of 16, and glabel/ufs would find file
+ * system on slice instead of partition.
+ */
if (fs->fs_magic == FS_UFS1_MAGIC && fs->fs_fsize > 0 &&
pp->mediasize / fs->fs_fsize == fs->fs_old_size) {
/* Valid UFS1. */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/mirror/g_mirror.c
--- a/head/sys/geom/mirror/g_mirror.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/mirror/g_mirror.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/mirror/g_mirror.c 227309 2011-11-07 15:43:11Z ed $");
+__FBSDID("$FreeBSD: head/sys/geom/mirror/g_mirror.c 237930 2012-07-01 15:43:52Z glebius $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -440,7 +440,7 @@
struct g_mirror_metadata *md, int *errorp)
{
struct g_mirror_disk *disk;
- int error;
+ int i, error;
disk = malloc(sizeof(*disk), M_MIRROR, M_NOWAIT | M_ZERO);
if (disk == NULL) {
@@ -455,6 +455,11 @@
disk->d_state = G_MIRROR_DISK_STATE_NONE;
disk->d_priority = md->md_priority;
disk->d_flags = md->md_dflags;
+ error = g_getattr("GEOM::candelete", disk->d_consumer, &i);
+ if (error != 0)
+ goto fail;
+ if (i)
+ disk->d_flags |= G_MIRROR_DISK_FLAG_CANDELETE;
if (md->md_provider[0] != '\0')
disk->d_flags |= G_MIRROR_DISK_FLAG_HARDCODED;
disk->d_sync.ds_consumer = NULL;
@@ -891,7 +896,8 @@
if (pbp->bio_children == pbp->bio_inbed) {
G_MIRROR_LOGREQ(3, pbp, "Request delivered.");
pbp->bio_completed = pbp->bio_length;
- if (pbp->bio_cmd == BIO_WRITE) {
+ if (pbp->bio_cmd == BIO_WRITE ||
+ pbp->bio_cmd == BIO_DELETE) {
bioq_remove(&sc->sc_inflight, pbp);
/* Release delayed sync requests if possible. */
g_mirror_sync_release(sc);
@@ -1084,7 +1090,9 @@
g_mirror_flush(sc, bp);
return;
case BIO_GETATTR:
- if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) {
+ if (g_handleattr_int(bp, "GEOM::candelete", 1))
+ return;
+ else if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) {
g_mirror_kernel_dump(bp);
return;
}
@@ -1631,6 +1639,9 @@
default:
continue;
}
+ if (bp->bio_cmd == BIO_DELETE &&
+ (disk->d_flags & G_MIRROR_DISK_FLAG_CANDELETE) == 0)
+ continue;
cbp = g_clone_bio(bp);
if (cbp == NULL) {
for (cbp = bioq_first(&queue); cbp != NULL;
@@ -1693,6 +1704,8 @@
gp = sc->sc_geom;
if (gp->softc == NULL)
return (1);
+ if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_TASTING) != 0)
+ return (0);
LIST_FOREACH(cp, &gp->consumer, consumer) {
if (g_mirror_is_busy(sc, cp))
return (0);
@@ -3054,6 +3067,7 @@
G_MIRROR_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name);
g_topology_unlock();
sx_xlock(&sc->sc_lock);
+ sc->sc_flags |= G_MIRROR_DEVICE_FLAG_TASTING;
error = g_mirror_add_disk(sc, pp, &md);
if (error != 0) {
G_MIRROR_DEBUG(0, "Cannot add disk %s to %s (error=%d).",
@@ -3066,6 +3080,12 @@
}
gp = NULL;
}
+ sc->sc_flags &= ~G_MIRROR_DEVICE_FLAG_TASTING;
+ if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROY) != 0) {
+ g_mirror_destroy(sc, G_MIRROR_DESTROY_HARD);
+ g_topology_lock();
+ return (NULL);
+ }
sx_xunlock(&sc->sc_lock);
g_topology_lock();
return (gp);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/mirror/g_mirror.h
--- a/head/sys/geom/mirror/g_mirror.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/mirror/g_mirror.h Wed Jul 25 16:45:04 2012 +0300
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/geom/mirror/g_mirror.h 237930 2012-07-01 15:43:52Z glebius $
*/
#ifndef _G_MIRROR_H_
@@ -59,10 +59,12 @@
#define G_MIRROR_DISK_FLAG_INACTIVE 0x0000000000000008ULL
#define G_MIRROR_DISK_FLAG_HARDCODED 0x0000000000000010ULL
#define G_MIRROR_DISK_FLAG_BROKEN 0x0000000000000020ULL
+#define G_MIRROR_DISK_FLAG_CANDELETE 0x0000000000000040ULL
#define G_MIRROR_DISK_FLAG_MASK (G_MIRROR_DISK_FLAG_DIRTY | \
G_MIRROR_DISK_FLAG_SYNCHRONIZING | \
G_MIRROR_DISK_FLAG_FORCE_SYNC | \
- G_MIRROR_DISK_FLAG_INACTIVE)
+ G_MIRROR_DISK_FLAG_INACTIVE | \
+ G_MIRROR_DISK_FLAG_CANDELETE)
#define G_MIRROR_DEVICE_FLAG_NOAUTOSYNC 0x0000000000000001ULL
#define G_MIRROR_DEVICE_FLAG_NOFAILSYNC 0x0000000000000002ULL
@@ -157,6 +159,7 @@
#define G_MIRROR_DEVICE_FLAG_DESTROY 0x0100000000000000ULL
#define G_MIRROR_DEVICE_FLAG_WAIT 0x0200000000000000ULL
#define G_MIRROR_DEVICE_FLAG_DESTROYING 0x0400000000000000ULL
+#define G_MIRROR_DEVICE_FLAG_TASTING 0x0800000000000000ULL
#define G_MIRROR_DEVICE_STATE_STARTING 0
#define G_MIRROR_DEVICE_STATE_RUNNING 1
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/mirror/g_mirror_ctl.c
--- a/head/sys/geom/mirror/g_mirror_ctl.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/mirror/g_mirror_ctl.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/geom/mirror/g_mirror_ctl.c 235600 2012-05-18 09:22:21Z ae $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -560,7 +560,7 @@
const char *name;
char param[16];
int *nargs;
- u_int i;
+ u_int i, active;
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
if (nargs == NULL) {
@@ -587,6 +587,7 @@
"first.");
return;
}
+ active = g_mirror_ndisks(sc, G_MIRROR_DISK_STATE_ACTIVE);
for (i = 1; i < (u_int)*nargs; i++) {
snprintf(param, sizeof(param), "arg%u", i);
name = gctl_get_asciiparam(req, param);
@@ -599,6 +600,16 @@
gctl_error(req, "No such provider: %s.", name);
continue;
}
+ if (disk->d_state == G_MIRROR_DISK_STATE_ACTIVE) {
+ if (active > 1)
+ active--;
+ else {
+ gctl_error(req, "%s: Can't remove the last "
+ "ACTIVE component %s.", sc->sc_geom->name,
+ name);
+ continue;
+ }
+ }
g_mirror_event_send(disk, G_MIRROR_DISK_STATE_DESTROY,
G_MIRROR_EVENT_DONTWAIT);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/mountver/g_mountver.c
--- a/head/sys/geom/mountver/g_mountver.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/mountver/g_mountver.c Wed Jul 25 16:45:04 2012 +0300
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/mountver/g_mountver.c 230643 2012-01-28 14:00:21Z attilio $");
+__FBSDID("$FreeBSD: head/sys/geom/mountver/g_mountver.c 238218 2012-07-07 22:20:47Z trasz $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -59,6 +59,7 @@
static void g_mountver_queue(struct bio *bp);
static void g_mountver_orphan(struct g_consumer *cp);
+static void g_mountver_resize(struct g_consumer *cp);
static int g_mountver_destroy(struct g_geom *gp, boolean_t force);
static g_taste_t g_mountver_taste;
static int g_mountver_destroy_geom(struct gctl_req *req, struct g_class *mp,
@@ -257,6 +258,7 @@
gp->softc = sc;
gp->start = g_mountver_start;
gp->orphan = g_mountver_orphan;
+ gp->resize = g_mountver_resize;
gp->access = g_mountver_access;
gp->dumpconf = g_mountver_dumpconf;
@@ -457,6 +459,18 @@
G_MOUNTVER_DEBUG(0, "%s is offline. Mount verification in progress.", sc->sc_provider_name);
}
+static void
+g_mountver_resize(struct g_consumer *cp)
+{
+ struct g_geom *gp;
+ struct g_provider *pp;
+
+ gp = cp->geom;
+
+ LIST_FOREACH(pp, &gp->provider, provider)
+ g_resize_provider(pp, cp->provider->mediasize);
+}
+
static int
g_mountver_ident_matches(struct g_geom *gp)
{
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/multipath/g_multipath.c
--- a/head/sys/geom/multipath/g_multipath.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/multipath/g_multipath.c Wed Jul 25 16:45:04 2012 +0300
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/multipath/g_multipath.c 234415 2012-04-18 09:42:14Z mav $");
+__FBSDID("$FreeBSD: head/sys/geom/multipath/g_multipath.c 236619 2012-06-05 16:46:34Z mav $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -944,7 +944,7 @@
struct g_geom *gp;
struct g_consumer *cp;
struct g_provider *pp;
- struct g_multipath_metadata *md;
+ struct g_multipath_metadata md;
const char *name;
int error, *val;
void *buf;
@@ -980,14 +980,15 @@
return;
}
g_topology_unlock();
- md = buf = g_malloc(pp->sectorsize, M_WAITOK | M_ZERO);
- strlcpy(md->md_magic, G_MULTIPATH_MAGIC, sizeof(md->md_magic));
- memcpy(md->md_uuid, sc->sc_uuid, sizeof (sc->sc_uuid));
- strlcpy(md->md_name, name, sizeof(md->md_name));
- md->md_version = G_MULTIPATH_VERSION;
- md->md_size = pp->mediasize;
- md->md_sectorsize = pp->sectorsize;
- md->md_active_active = sc->sc_active_active;
+ buf = g_malloc(pp->sectorsize, M_WAITOK | M_ZERO);
+ strlcpy(md.md_magic, G_MULTIPATH_MAGIC, sizeof(md.md_magic));
+ memcpy(md.md_uuid, sc->sc_uuid, sizeof (sc->sc_uuid));
+ strlcpy(md.md_name, name, sizeof(md.md_name));
+ md.md_version = G_MULTIPATH_VERSION;
+ md.md_size = pp->mediasize;
+ md.md_sectorsize = pp->sectorsize;
+ md.md_active_active = sc->sc_active_active;
+ multipath_metadata_encode(&md, buf);
error = g_write_data(cp, pp->mediasize - pp->sectorsize,
buf, pp->sectorsize);
g_topology_lock();
@@ -1313,7 +1314,7 @@
if (sc == NULL)
return;
if (cp != NULL) {
- sbuf_printf(sb, "%s<State>%s</State>", indent,
+ sbuf_printf(sb, "%s<State>%s</State>\n", indent,
(cp->index & MP_NEW) ? "NEW" :
(cp->index & MP_LOST) ? "LOST" :
(cp->index & MP_FAIL) ? "FAIL" :
@@ -1322,17 +1323,17 @@
sc->sc_active_active == 2 ? "READ" : "PASSIVE");
} else {
good = g_multipath_good(gp);
- sbuf_printf(sb, "%s<State>%s</State>", indent,
+ sbuf_printf(sb, "%s<State>%s</State>\n", indent,
good == 0 ? "BROKEN" :
(good != sc->sc_ndisks || sc->sc_ndisks == 1) ?
"DEGRADED" : "OPTIMAL");
}
if (cp == NULL && pp == NULL) {
- sbuf_printf(sb, "%s<UUID>%s</UUID>", indent, sc->sc_uuid);
- sbuf_printf(sb, "%s<Mode>Active/%s</Mode>", indent,
+ sbuf_printf(sb, "%s<UUID>%s</UUID>\n", indent, sc->sc_uuid);
+ sbuf_printf(sb, "%s<Mode>Active/%s</Mode>\n", indent,
sc->sc_active_active == 2 ? "Read" :
sc->sc_active_active == 1 ? "Active" : "Passive");
- sbuf_printf(sb, "%s<Type>%s</Type>", indent,
+ sbuf_printf(sb, "%s<Type>%s</Type>\n", indent,
sc->sc_uuid[0] == 0 ? "MANUAL" : "AUTOMATIC");
}
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/nop/g_nop.c
--- a/head/sys/geom/nop/g_nop.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/nop/g_nop.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/nop/g_nop.c 227309 2011-11-07 15:43:11Z ed $");
+__FBSDID("$FreeBSD: head/sys/geom/nop/g_nop.c 238219 2012-07-07 22:22:13Z trasz $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -72,6 +72,30 @@
}
static void
+g_nop_resize(struct g_consumer *cp)
+{
+ struct g_nop_softc *sc;
+ struct g_geom *gp;
+ struct g_provider *pp;
+ off_t size;
+
+ g_topology_assert();
+
+ gp = cp->geom;
+ sc = gp->softc;
+
+ if (sc->sc_explicitsize != 0)
+ return;
+ if (cp->provider->mediasize < sc->sc_offset) {
+ g_nop_destroy(gp, 1);
+ return;
+ }
+ size = cp->provider->mediasize - sc->sc_offset;
+ LIST_FOREACH(pp, &gp->provider, provider)
+ g_resize_provider(pp, size);
+}
+
+static void
g_nop_start(struct bio *bp)
{
struct g_nop_softc *sc;
@@ -146,6 +170,7 @@
struct g_consumer *cp;
char name[64];
int error;
+ off_t explicitsize;
g_topology_assert();
@@ -165,6 +190,7 @@
gctl_error(req, "Invalid offset for provider %s.", pp->name);
return (EINVAL);
}
+ explicitsize = size;
if (size == 0)
size = pp->mediasize - offset;
if (offset + size > pp->mediasize) {
@@ -192,6 +218,7 @@
gp = g_new_geomf(mp, name);
sc = g_malloc(sizeof(*sc), M_WAITOK);
sc->sc_offset = offset;
+ sc->sc_explicitsize = explicitsize;
sc->sc_error = ioerror;
sc->sc_rfailprob = rfailprob;
sc->sc_wfailprob = wfailprob;
@@ -202,6 +229,7 @@
gp->softc = sc;
gp->start = g_nop_start;
gp->orphan = g_nop_orphan;
+ gp->resize = g_nop_resize;
gp->access = g_nop_access;
gp->dumpconf = g_nop_dumpconf;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/nop/g_nop.h
--- a/head/sys/geom/nop/g_nop.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/nop/g_nop.h Wed Jul 25 16:45:04 2012 +0300
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/geom/nop/g_nop.h 238219 2012-07-07 22:22:13Z trasz $
*/
#ifndef _G_NOP_H_
@@ -57,6 +57,7 @@
struct g_nop_softc {
int sc_error;
off_t sc_offset;
+ off_t sc_explicitsize;
u_int sc_rfailprob;
u_int sc_wfailprob;
uintmax_t sc_reads;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/part/g_part.c
--- a/head/sys/geom/part/g_part.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/part/g_part.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/part/g_part.c 234417 2012-04-18 11:59:03Z marck $");
+__FBSDID("$FreeBSD: head/sys/geom/part/g_part.c 238657 2012-07-20 17:51:20Z trasz $");
#include <sys/param.h>
#include <sys/bio.h>
@@ -83,6 +83,7 @@
{ "fat32", G_PART_ALIAS_MS_FAT32 },
{ "freebsd", G_PART_ALIAS_FREEBSD },
{ "freebsd-boot", G_PART_ALIAS_FREEBSD_BOOT },
+ { "freebsd-nandfs", G_PART_ALIAS_FREEBSD_NANDFS },
{ "freebsd-swap", G_PART_ALIAS_FREEBSD_SWAP },
{ "freebsd-ufs", G_PART_ALIAS_FREEBSD_UFS },
{ "freebsd-vinum", G_PART_ALIAS_FREEBSD_VINUM },
@@ -1256,6 +1257,7 @@
struct sbuf *sb;
quad_t end;
int error;
+ off_t mediasize;
gp = gpp->gpp_geom;
G_PART_TRACE((G_T_TOPOLOGY, "%s(%s)", __func__, gp->name));
@@ -1300,8 +1302,11 @@
pp = entry->gpe_pp;
if ((g_debugflags & 16) == 0 &&
(pp->acr > 0 || pp->acw > 0 || pp->ace > 0)) {
- gctl_error(req, "%d", EBUSY);
- return (EBUSY);
+ if (entry->gpe_end - entry->gpe_start + 1 > gpp->gpp_size) {
+ /* Deny shrinking of an opened partition. */
+ gctl_error(req, "%d", EBUSY);
+ return (EBUSY);
+ }
}
error = G_PART_RESIZE(table, entry, gpp);
@@ -1314,8 +1319,9 @@
entry->gpe_modified = 1;
/* update mediasize of changed provider */
- pp->mediasize = (entry->gpe_end - entry->gpe_start + 1) *
+ mediasize = (entry->gpe_end - entry->gpe_start + 1) *
pp->sectorsize;
+ g_resize_provider(pp, mediasize);
/* Provide feedback if so requested. */
if (gpp->gpp_parms & G_PART_PARM_OUTPUT) {
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/part/g_part.h
--- a/head/sys/geom/part/g_part.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/part/g_part.h Wed Jul 25 16:45:04 2012 +0300
@@ -23,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: head/sys/geom/part/g_part.h 234417 2012-04-18 11:59:03Z marck $
+ * $FreeBSD: head/sys/geom/part/g_part.h 236023 2012-05-25 20:33:34Z marcel $
*/
#ifndef _GEOM_PART_H_
@@ -46,6 +46,7 @@
G_PART_ALIAS_EFI, /* A EFI system partition entry. */
G_PART_ALIAS_FREEBSD, /* A BSD labeled partition entry. */
G_PART_ALIAS_FREEBSD_BOOT, /* A FreeBSD boot partition entry. */
+ G_PART_ALIAS_FREEBSD_NANDFS, /* A FreeBSD nandfs partition entry. */
G_PART_ALIAS_FREEBSD_SWAP, /* A swap partition entry. */
G_PART_ALIAS_FREEBSD_UFS, /* A UFS/UFS2 file system entry. */
G_PART_ALIAS_FREEBSD_VINUM, /* A Vinum partition entry. */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/part/g_part_apm.c
--- a/head/sys/geom/part/g_part_apm.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/part/g_part_apm.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/part/g_part_apm.c 231349 2012-02-10 06:44:30Z ae $");
+__FBSDID("$FreeBSD: head/sys/geom/part/g_part_apm.c 236023 2012-05-25 20:33:34Z marcel $");
#include <sys/param.h>
#include <sys/apm.h>
@@ -159,6 +159,11 @@
strcpy(buf, APM_ENT_TYPE_FREEBSD);
return (0);
}
+ alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_NANDFS);
+ if (!strcasecmp(type, alias)) {
+ strcpy(buf, APM_ENT_TYPE_FREEBSD_NANDFS);
+ return (0);
+ }
alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_SWAP);
if (!strcasecmp(type, alias)) {
strcpy(buf, APM_ENT_TYPE_FREEBSD_SWAP);
@@ -485,6 +490,8 @@
return (g_part_alias_name(G_PART_ALIAS_APPLE_UFS));
if (!strcmp(type, APM_ENT_TYPE_FREEBSD))
return (g_part_alias_name(G_PART_ALIAS_FREEBSD));
+ if (!strcmp(type, APM_ENT_TYPE_FREEBSD_NANDFS))
+ return (g_part_alias_name(G_PART_ALIAS_FREEBSD_NANDFS));
if (!strcmp(type, APM_ENT_TYPE_FREEBSD_SWAP))
return (g_part_alias_name(G_PART_ALIAS_FREEBSD_SWAP));
if (!strcmp(type, APM_ENT_TYPE_FREEBSD_UFS))
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/part/g_part_bsd.c
--- a/head/sys/geom/part/g_part_bsd.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/part/g_part_bsd.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/part/g_part_bsd.c 232680 2012-03-08 01:48:44Z emaste $");
+__FBSDID("$FreeBSD: head/sys/geom/part/g_part_bsd.c 236023 2012-05-25 20:33:34Z marcel $");
#include <sys/param.h>
#include <sys/bio.h>
@@ -126,6 +126,11 @@
*fstype = (u_int)lt;
return (0);
}
+ alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_NANDFS);
+ if (!strcasecmp(type, alias)) {
+ *fstype = FS_NANDFS;
+ return (0);
+ }
alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_SWAP);
if (!strcasecmp(type, alias)) {
*fstype = FS_SWAP;
@@ -444,6 +449,8 @@
entry = (struct g_part_bsd_entry *)baseentry;
type = entry->part.p_fstype;
+ if (type == FS_NANDFS)
+ return (g_part_alias_name(G_PART_ALIAS_FREEBSD_NANDFS));
if (type == FS_SWAP)
return (g_part_alias_name(G_PART_ALIAS_FREEBSD_SWAP));
if (type == FS_BSDFFS)
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/part/g_part_gpt.c
--- a/head/sys/geom/part/g_part_gpt.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/part/g_part_gpt.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/part/g_part_gpt.c 234417 2012-04-18 11:59:03Z marck $");
+__FBSDID("$FreeBSD: head/sys/geom/part/g_part_gpt.c 237057 2012-06-14 11:17:54Z ae $");
#include <sys/param.h>
#include <sys/bio.h>
@@ -155,6 +155,7 @@
static struct uuid gpt_uuid_efi = GPT_ENT_TYPE_EFI;
static struct uuid gpt_uuid_freebsd = GPT_ENT_TYPE_FREEBSD;
static struct uuid gpt_uuid_freebsd_boot = GPT_ENT_TYPE_FREEBSD_BOOT;
+static struct uuid gpt_uuid_freebsd_nandfs = GPT_ENT_TYPE_FREEBSD_NANDFS;
static struct uuid gpt_uuid_freebsd_swap = GPT_ENT_TYPE_FREEBSD_SWAP;
static struct uuid gpt_uuid_freebsd_ufs = GPT_ENT_TYPE_FREEBSD_UFS;
static struct uuid gpt_uuid_freebsd_vinum = GPT_ENT_TYPE_FREEBSD_VINUM;
@@ -195,6 +196,7 @@
{ &gpt_uuid_efi, G_PART_ALIAS_EFI, 0xee },
{ &gpt_uuid_freebsd, G_PART_ALIAS_FREEBSD, 0xa5 },
{ &gpt_uuid_freebsd_boot, G_PART_ALIAS_FREEBSD_BOOT, 0 },
+ { &gpt_uuid_freebsd_nandfs, G_PART_ALIAS_FREEBSD_NANDFS, 0 },
{ &gpt_uuid_freebsd_swap, G_PART_ALIAS_FREEBSD_SWAP, 0 },
{ &gpt_uuid_freebsd_ufs, G_PART_ALIAS_FREEBSD_UFS, 0 },
{ &gpt_uuid_freebsd_vinum, G_PART_ALIAS_FREEBSD_VINUM, 0 },
@@ -339,9 +341,6 @@
disable:
table->bootcamp = 0;
- bzero(table->mbr + DOSPARTOFF, DOSPARTSIZE * NDOSPART);
- gpt_write_mbr_entry(table->mbr, 0, 0xee, 1ull,
- MIN(table->lba[GPT_ELT_SECHDR], UINT32_MAX));
}
static struct gpt_hdr *
@@ -587,10 +586,6 @@
codesz = MIN(codesz, gpp->gpp_codesize);
if (codesz > 0)
bcopy(gpp->gpp_codeptr, table->mbr, codesz);
-
- /* Mark the PMBR active since some BIOS require it. */
- if (!table->bootcamp)
- table->mbr[DOSPARTOFF] = 0x80; /* status */
return (0);
}
@@ -599,7 +594,6 @@
{
struct g_provider *pp;
struct g_part_gpt_table *table;
- quad_t last;
size_t tblsz;
/* We don't nest, which means that our depth should be 0. */
@@ -615,11 +609,6 @@
pp->sectorsize)
return (ENOSPC);
- last = (pp->mediasize / pp->sectorsize) - 1;
-
- le16enc(table->mbr + DOSMAGICOFFSET, DOSMAGIC);
- gpt_write_mbr_entry(table->mbr, 0, 0xee, 1, MIN(last, UINT32_MAX));
-
/* Allocate space for the header */
table->hdr = g_malloc(sizeof(struct gpt_hdr), M_WAITOK | M_ZERO);
@@ -1045,6 +1034,16 @@
if (table->bootcamp)
gpt_update_bootcamp(basetable);
+ /* Update partition entries in the PMBR if Boot Camp disabled. */
+ if (!table->bootcamp) {
+ bzero(table->mbr + DOSPARTOFF, DOSPARTSIZE * NDOSPART);
+ gpt_write_mbr_entry(table->mbr, 0, 0xee, 1,
+ MIN(pp->mediasize / pp->sectorsize - 1, UINT32_MAX));
+ /* Mark the PMBR active since some BIOS require it. */
+ table->mbr[DOSPARTOFF] = 0x80;
+ }
+ le16enc(table->mbr + DOSMAGICOFFSET, DOSMAGIC);
+
/* Write the PMBR */
buf = g_malloc(pp->sectorsize, M_WAITOK | M_ZERO);
bcopy(table->mbr, buf, MBRSIZE);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/part/g_part_vtoc8.c
--- a/head/sys/geom/part/g_part_vtoc8.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/part/g_part_vtoc8.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/part/g_part_vtoc8.c 226522 2011-10-18 20:16:02Z marius $");
+__FBSDID("$FreeBSD: head/sys/geom/part/g_part_vtoc8.c 236023 2012-05-25 20:33:34Z marcel $");
#include <sys/param.h>
#include <sys/bio.h>
@@ -114,6 +114,11 @@
*tag = (uint16_t)lt;
return (0);
}
+ alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_NANDFS);
+ if (!strcasecmp(type, alias)) {
+ *tag = VTOC_TAG_FREEBSD_NANDFS;
+ return (0);
+ }
alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_SWAP);
if (!strcasecmp(type, alias)) {
*tag = VTOC_TAG_FREEBSD_SWAP;
@@ -487,6 +492,8 @@
table = (struct g_part_vtoc8_table *)basetable;
tag = be16dec(&table->vtoc.part[entry->gpe_index - 1].tag);
+ if (tag == VTOC_TAG_FREEBSD_NANDFS)
+ return (g_part_alias_name(G_PART_ALIAS_FREEBSD_NANDFS));
if (tag == VTOC_TAG_FREEBSD_SWAP)
return (g_part_alias_name(G_PART_ALIAS_FREEBSD_SWAP));
if (tag == VTOC_TAG_FREEBSD_UFS)
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/raid/g_raid.c
--- a/head/sys/geom/raid/g_raid.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/raid/g_raid.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/raid/g_raid.c 234458 2012-04-19 12:30:12Z mav $");
+__FBSDID("$FreeBSD: head/sys/geom/raid/g_raid.c 235076 2012-05-06 11:32:36Z mav $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -277,31 +277,87 @@
case G_RAID_VOLUME_RL_RAID1:
return ("RAID1");
case G_RAID_VOLUME_RL_RAID3:
+ if (qual == G_RAID_VOLUME_RLQ_R3P0)
+ return ("RAID3-P0");
+ if (qual == G_RAID_VOLUME_RLQ_R3PN)
+ return ("RAID3-PN");
return ("RAID3");
case G_RAID_VOLUME_RL_RAID4:
+ if (qual == G_RAID_VOLUME_RLQ_R4P0)
+ return ("RAID4-P0");
+ if (qual == G_RAID_VOLUME_RLQ_R4PN)
+ return ("RAID4-PN");
return ("RAID4");
case G_RAID_VOLUME_RL_RAID5:
if (qual == G_RAID_VOLUME_RLQ_R5RA)
- return ("RAID5RA");
+ return ("RAID5-RA");
if (qual == G_RAID_VOLUME_RLQ_R5RS)
- return ("RAID5RS");
+ return ("RAID5-RS");
if (qual == G_RAID_VOLUME_RLQ_R5LA)
- return ("RAID5LA");
+ return ("RAID5-LA");
if (qual == G_RAID_VOLUME_RLQ_R5LS)
- return ("RAID5LS");
+ return ("RAID5-LS");
return ("RAID5");
case G_RAID_VOLUME_RL_RAID6:
+ if (qual == G_RAID_VOLUME_RLQ_R6RA)
+ return ("RAID6-RA");
+ if (qual == G_RAID_VOLUME_RLQ_R6RS)
+ return ("RAID6-RS");
+ if (qual == G_RAID_VOLUME_RLQ_R6LA)
+ return ("RAID6-LA");
+ if (qual == G_RAID_VOLUME_RLQ_R6LS)
+ return ("RAID6-LS");
return ("RAID6");
+ case G_RAID_VOLUME_RL_RAIDMDF:
+ if (qual == G_RAID_VOLUME_RLQ_RMDFRA)
+ return ("RAIDMDF-RA");
+ if (qual == G_RAID_VOLUME_RLQ_RMDFRS)
+ return ("RAIDMDF-RS");
+ if (qual == G_RAID_VOLUME_RLQ_RMDFLA)
+ return ("RAIDMDF-LA");
+ if (qual == G_RAID_VOLUME_RLQ_RMDFLS)
+ return ("RAIDMDF-LS");
+ return ("RAIDMDF");
case G_RAID_VOLUME_RL_RAID1E:
+ if (qual == G_RAID_VOLUME_RLQ_R1EA)
+ return ("RAID1E-A");
+ if (qual == G_RAID_VOLUME_RLQ_R1EO)
+ return ("RAID1E-O");
return ("RAID1E");
case G_RAID_VOLUME_RL_SINGLE:
return ("SINGLE");
case G_RAID_VOLUME_RL_CONCAT:
return ("CONCAT");
case G_RAID_VOLUME_RL_RAID5E:
+ if (qual == G_RAID_VOLUME_RLQ_R5ERA)
+ return ("RAID5E-RA");
+ if (qual == G_RAID_VOLUME_RLQ_R5ERS)
+ return ("RAID5E-RS");
+ if (qual == G_RAID_VOLUME_RLQ_R5ELA)
+ return ("RAID5E-LA");
+ if (qual == G_RAID_VOLUME_RLQ_R5ELS)
+ return ("RAID5E-LS");
return ("RAID5E");
case G_RAID_VOLUME_RL_RAID5EE:
+ if (qual == G_RAID_VOLUME_RLQ_R5EERA)
+ return ("RAID5EE-RA");
+ if (qual == G_RAID_VOLUME_RLQ_R5EERS)
+ return ("RAID5EE-RS");
+ if (qual == G_RAID_VOLUME_RLQ_R5EELA)
+ return ("RAID5EE-LA");
+ if (qual == G_RAID_VOLUME_RLQ_R5EELS)
+ return ("RAID5EE-LS");
return ("RAID5EE");
+ case G_RAID_VOLUME_RL_RAID5R:
+ if (qual == G_RAID_VOLUME_RLQ_R5RRA)
+ return ("RAID5R-RA");
+ if (qual == G_RAID_VOLUME_RLQ_R5RRS)
+ return ("RAID5R-RS");
+ if (qual == G_RAID_VOLUME_RLQ_R5RLA)
+ return ("RAID5R-LA");
+ if (qual == G_RAID_VOLUME_RLQ_R5RLS)
+ return ("RAID5R-LS");
+ return ("RAID5E");
default:
return ("UNKNOWN");
}
@@ -317,37 +373,111 @@
*level = G_RAID_VOLUME_RL_RAID0;
else if (strcasecmp(str, "RAID1") == 0)
*level = G_RAID_VOLUME_RL_RAID1;
- else if (strcasecmp(str, "RAID3") == 0)
+ else if (strcasecmp(str, "RAID3-P0") == 0) {
*level = G_RAID_VOLUME_RL_RAID3;
- else if (strcasecmp(str, "RAID4") == 0)
+ *qual = G_RAID_VOLUME_RLQ_R3P0;
+ } else if (strcasecmp(str, "RAID3-PN") == 0 ||
+ strcasecmp(str, "RAID3") == 0) {
+ *level = G_RAID_VOLUME_RL_RAID3;
+ *qual = G_RAID_VOLUME_RLQ_R3PN;
+ } else if (strcasecmp(str, "RAID4-P0") == 0) {
*level = G_RAID_VOLUME_RL_RAID4;
- else if (strcasecmp(str, "RAID5RA") == 0) {
+ *qual = G_RAID_VOLUME_RLQ_R4P0;
+ } else if (strcasecmp(str, "RAID4-PN") == 0 ||
+ strcasecmp(str, "RAID4") == 0) {
+ *level = G_RAID_VOLUME_RL_RAID4;
+ *qual = G_RAID_VOLUME_RLQ_R4PN;
+ } else if (strcasecmp(str, "RAID5-RA") == 0) {
*level = G_RAID_VOLUME_RL_RAID5;
*qual = G_RAID_VOLUME_RLQ_R5RA;
- } else if (strcasecmp(str, "RAID5RS") == 0) {
+ } else if (strcasecmp(str, "RAID5-RS") == 0) {
*level = G_RAID_VOLUME_RL_RAID5;
*qual = G_RAID_VOLUME_RLQ_R5RS;
} else if (strcasecmp(str, "RAID5") == 0 ||
- strcasecmp(str, "RAID5LA") == 0) {
+ strcasecmp(str, "RAID5-LA") == 0) {
*level = G_RAID_VOLUME_RL_RAID5;
*qual = G_RAID_VOLUME_RLQ_R5LA;
- } else if (strcasecmp(str, "RAID5LS") == 0) {
+ } else if (strcasecmp(str, "RAID5-LS") == 0) {
*level = G_RAID_VOLUME_RL_RAID5;
*qual = G_RAID_VOLUME_RLQ_R5LS;
- } else if (strcasecmp(str, "RAID6") == 0)
+ } else if (strcasecmp(str, "RAID6-RA") == 0) {
*level = G_RAID_VOLUME_RL_RAID6;
- else if (strcasecmp(str, "RAID10") == 0 ||
- strcasecmp(str, "RAID1E") == 0)
+ *qual = G_RAID_VOLUME_RLQ_R6RA;
+ } else if (strcasecmp(str, "RAID6-RS") == 0) {
+ *level = G_RAID_VOLUME_RL_RAID6;
+ *qual = G_RAID_VOLUME_RLQ_R6RS;
+ } else if (strcasecmp(str, "RAID6") == 0 ||
+ strcasecmp(str, "RAID6-LA") == 0) {
+ *level = G_RAID_VOLUME_RL_RAID6;
+ *qual = G_RAID_VOLUME_RLQ_R6LA;
+ } else if (strcasecmp(str, "RAID6-LS") == 0) {
+ *level = G_RAID_VOLUME_RL_RAID6;
+ *qual = G_RAID_VOLUME_RLQ_R6LS;
+ } else if (strcasecmp(str, "RAIDMDF-RA") == 0) {
+ *level = G_RAID_VOLUME_RL_RAIDMDF;
+ *qual = G_RAID_VOLUME_RLQ_RMDFRA;
+ } else if (strcasecmp(str, "RAIDMDF-RS") == 0) {
+ *level = G_RAID_VOLUME_RL_RAIDMDF;
+ *qual = G_RAID_VOLUME_RLQ_RMDFRS;
+ } else if (strcasecmp(str, "RAIDMDF") == 0 ||
+ strcasecmp(str, "RAIDMDF-LA") == 0) {
+ *level = G_RAID_VOLUME_RL_RAIDMDF;
+ *qual = G_RAID_VOLUME_RLQ_RMDFLA;
+ } else if (strcasecmp(str, "RAIDMDF-LS") == 0) {
+ *level = G_RAID_VOLUME_RL_RAIDMDF;
+ *qual = G_RAID_VOLUME_RLQ_RMDFLS;
+ } else if (strcasecmp(str, "RAID10") == 0 ||
+ strcasecmp(str, "RAID1E") == 0 ||
+ strcasecmp(str, "RAID1E-A") == 0) {
*level = G_RAID_VOLUME_RL_RAID1E;
- else if (strcasecmp(str, "SINGLE") == 0)
+ *qual = G_RAID_VOLUME_RLQ_R1EA;
+ } else if (strcasecmp(str, "RAID1E-O") == 0) {
+ *level = G_RAID_VOLUME_RL_RAID1E;
+ *qual = G_RAID_VOLUME_RLQ_R1EO;
+ } else if (strcasecmp(str, "SINGLE") == 0)
*level = G_RAID_VOLUME_RL_SINGLE;
else if (strcasecmp(str, "CONCAT") == 0)
*level = G_RAID_VOLUME_RL_CONCAT;
- else if (strcasecmp(str, "RAID5E") == 0)
+ else if (strcasecmp(str, "RAID5E-RA") == 0) {
*level = G_RAID_VOLUME_RL_RAID5E;
- else if (strcasecmp(str, "RAID5EE") == 0)
+ *qual = G_RAID_VOLUME_RLQ_R5ERA;
+ } else if (strcasecmp(str, "RAID5E-RS") == 0) {
+ *level = G_RAID_VOLUME_RL_RAID5E;
+ *qual = G_RAID_VOLUME_RLQ_R5ERS;
+ } else if (strcasecmp(str, "RAID5E") == 0 ||
+ strcasecmp(str, "RAID5E-LA") == 0) {
+ *level = G_RAID_VOLUME_RL_RAID5E;
+ *qual = G_RAID_VOLUME_RLQ_R5ELA;
+ } else if (strcasecmp(str, "RAID5E-LS") == 0) {
+ *level = G_RAID_VOLUME_RL_RAID5E;
+ *qual = G_RAID_VOLUME_RLQ_R5ELS;
+ } else if (strcasecmp(str, "RAID5EE-RA") == 0) {
*level = G_RAID_VOLUME_RL_RAID5EE;
- else
+ *qual = G_RAID_VOLUME_RLQ_R5EERA;
+ } else if (strcasecmp(str, "RAID5EE-RS") == 0) {
+ *level = G_RAID_VOLUME_RL_RAID5EE;
+ *qual = G_RAID_VOLUME_RLQ_R5EERS;
+ } else if (strcasecmp(str, "RAID5EE") == 0 ||
+ strcasecmp(str, "RAID5EE-LA") == 0) {
+ *level = G_RAID_VOLUME_RL_RAID5EE;
+ *qual = G_RAID_VOLUME_RLQ_R5EELA;
+ } else if (strcasecmp(str, "RAID5EE-LS") == 0) {
+ *level = G_RAID_VOLUME_RL_RAID5EE;
+ *qual = G_RAID_VOLUME_RLQ_R5EELS;
+ } else if (strcasecmp(str, "RAID5R-RA") == 0) {
+ *level = G_RAID_VOLUME_RL_RAID5R;
+ *qual = G_RAID_VOLUME_RLQ_R5RRA;
+ } else if (strcasecmp(str, "RAID5R-RS") == 0) {
+ *level = G_RAID_VOLUME_RL_RAID5R;
+ *qual = G_RAID_VOLUME_RLQ_R5RRS;
+ } else if (strcasecmp(str, "RAID5R") == 0 ||
+ strcasecmp(str, "RAID5R-LA") == 0) {
+ *level = G_RAID_VOLUME_RL_RAID5R;
+ *qual = G_RAID_VOLUME_RLQ_R5RLA;
+ } else if (strcasecmp(str, "RAID5R-LS") == 0) {
+ *level = G_RAID_VOLUME_RL_RAID5R;
+ *qual = G_RAID_VOLUME_RLQ_R5RLS;
+ } else
return (-1);
return (0);
}
@@ -1693,8 +1823,8 @@
sc->sc_flags = 0;
TAILQ_INIT(&sc->sc_volumes);
TAILQ_INIT(&sc->sc_disks);
- sx_init(&sc->sc_lock, "gmirror:lock");
- mtx_init(&sc->sc_queue_mtx, "gmirror:queue", NULL, MTX_DEF);
+ sx_init(&sc->sc_lock, "graid:lock");
+ mtx_init(&sc->sc_queue_mtx, "graid:queue", NULL, MTX_DEF);
TAILQ_INIT(&sc->sc_events);
bioq_init(&sc->sc_queue);
gp->softc = sc;
@@ -1726,6 +1856,7 @@
vol->v_state = G_RAID_VOLUME_S_STARTING;
vol->v_raid_level = G_RAID_VOLUME_RL_UNKNOWN;
vol->v_raid_level_qualifier = G_RAID_VOLUME_RLQ_UNKNOWN;
+ vol->v_rotate_parity = 1;
bioq_init(&vol->v_inflight);
bioq_init(&vol->v_locked);
LIST_INIT(&vol->v_locks);
@@ -2013,7 +2144,7 @@
g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__, mp->name, pp->name);
G_RAID_DEBUG(2, "Tasting provider %s.", pp->name);
- gp = g_new_geomf(mp, "mirror:taste");
+ gp = g_new_geomf(mp, "raid:taste");
/*
* This orphan function should be never called.
*/
@@ -2043,7 +2174,8 @@
}
int
-g_raid_create_node_format(const char *format, struct g_geom **gp)
+g_raid_create_node_format(const char *format, struct gctl_req *req,
+ struct g_geom **gp)
{
struct g_raid_md_class *class;
struct g_raid_md_object *obj;
@@ -2061,7 +2193,7 @@
obj = (void *)kobj_create((kobj_class_t)class, M_RAID,
M_WAITOK);
obj->mdo_class = class;
- status = G_RAID_MD_CREATE(obj, &g_raid_class, gp);
+ status = G_RAID_MD_CREATE_REQ(obj, &g_raid_class, req, gp);
if (status != G_RAID_MD_TASTE_NEW)
kobj_delete((kobj_t)obj, M_RAID);
return (status);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/raid/g_raid.h
--- a/head/sys/geom/raid/g_raid.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/raid/g_raid.h Wed Jul 25 16:45:04 2012 +0300
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/geom/raid/g_raid.h 234458 2012-04-19 12:30:12Z mav $
+ * $FreeBSD: head/sys/geom/raid/g_raid.h 235076 2012-05-06 11:32:36Z mav $
*/
#ifndef _G_RAID_H_
@@ -219,18 +219,48 @@
#define G_RAID_VOLUME_RL_RAID4 0x04
#define G_RAID_VOLUME_RL_RAID5 0x05
#define G_RAID_VOLUME_RL_RAID6 0x06
+#define G_RAID_VOLUME_RL_RAIDMDF 0x07
#define G_RAID_VOLUME_RL_RAID1E 0x11
#define G_RAID_VOLUME_RL_SINGLE 0x0f
#define G_RAID_VOLUME_RL_CONCAT 0x1f
#define G_RAID_VOLUME_RL_RAID5E 0x15
#define G_RAID_VOLUME_RL_RAID5EE 0x25
+#define G_RAID_VOLUME_RL_RAID5R 0x35
#define G_RAID_VOLUME_RL_UNKNOWN 0xff
#define G_RAID_VOLUME_RLQ_NONE 0x00
+#define G_RAID_VOLUME_RLQ_R1SM 0x00
+#define G_RAID_VOLUME_RLQ_R1MM 0x01
+#define G_RAID_VOLUME_RLQ_R3P0 0x00
+#define G_RAID_VOLUME_RLQ_R3PN 0x01
+#define G_RAID_VOLUME_RLQ_R4P0 0x00
+#define G_RAID_VOLUME_RLQ_R4PN 0x01
#define G_RAID_VOLUME_RLQ_R5RA 0x00
#define G_RAID_VOLUME_RLQ_R5RS 0x01
#define G_RAID_VOLUME_RLQ_R5LA 0x02
#define G_RAID_VOLUME_RLQ_R5LS 0x03
+#define G_RAID_VOLUME_RLQ_R6RA 0x00
+#define G_RAID_VOLUME_RLQ_R6RS 0x01
+#define G_RAID_VOLUME_RLQ_R6LA 0x02
+#define G_RAID_VOLUME_RLQ_R6LS 0x03
+#define G_RAID_VOLUME_RLQ_RMDFRA 0x00
+#define G_RAID_VOLUME_RLQ_RMDFRS 0x01
+#define G_RAID_VOLUME_RLQ_RMDFLA 0x02
+#define G_RAID_VOLUME_RLQ_RMDFLS 0x03
+#define G_RAID_VOLUME_RLQ_R1EA 0x00
+#define G_RAID_VOLUME_RLQ_R1EO 0x01
+#define G_RAID_VOLUME_RLQ_R5ERA 0x00
+#define G_RAID_VOLUME_RLQ_R5ERS 0x01
+#define G_RAID_VOLUME_RLQ_R5ELA 0x02
+#define G_RAID_VOLUME_RLQ_R5ELS 0x03
+#define G_RAID_VOLUME_RLQ_R5EERA 0x00
+#define G_RAID_VOLUME_RLQ_R5EERS 0x01
+#define G_RAID_VOLUME_RLQ_R5EELA 0x02
+#define G_RAID_VOLUME_RLQ_R5EELS 0x03
+#define G_RAID_VOLUME_RLQ_R5RRA 0x00
+#define G_RAID_VOLUME_RLQ_R5RRS 0x01
+#define G_RAID_VOLUME_RLQ_R5RLA 0x02
+#define G_RAID_VOLUME_RLQ_R5RLS 0x03
#define G_RAID_VOLUME_RLQ_UNKNOWN 0xff
struct g_raid_volume;
@@ -248,7 +278,13 @@
u_int v_raid_level; /* Array RAID level. */
u_int v_raid_level_qualifier; /* RAID level det. */
u_int v_disks_count; /* Number of disks in array. */
+ u_int v_mdf_pdisks; /* Number of parity disks
+ in RAIDMDF array. */
+ uint16_t v_mdf_polynomial; /* Polynomial for RAIDMDF. */
+ uint8_t v_mdf_method; /* Generation method for RAIDMDF. */
u_int v_strip_size; /* Array strip size. */
+ u_int v_rotate_parity; /* Rotate RAID5R parity
+ after numer of stripes. */
u_int v_sectorsize; /* Volume sector size. */
off_t v_mediasize; /* Volume media size. */
struct bio_queue_head v_inflight; /* In-flight write requests. */
@@ -352,7 +388,8 @@
struct g_raid_softc * g_raid_create_node(struct g_class *mp,
const char *name, struct g_raid_md_object *md);
-int g_raid_create_node_format(const char *format, struct g_geom **gp);
+int g_raid_create_node_format(const char *format, struct gctl_req *req,
+ struct g_geom **gp);
struct g_raid_volume * g_raid_create_volume(struct g_raid_softc *sc,
const char *name, int id);
struct g_raid_disk * g_raid_create_disk(struct g_raid_softc *sc);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/raid/g_raid_ctl.c
--- a/head/sys/geom/raid/g_raid_ctl.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/raid/g_raid_ctl.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/geom/raid/g_raid_ctl.c 234940 2012-05-03 05:32:56Z mav $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -88,7 +88,7 @@
gctl_error(req, "No format recieved.");
return;
}
- crstatus = g_raid_create_node_format(format, &geom);
+ crstatus = g_raid_create_node_format(format, req, &geom);
if (crstatus == G_RAID_MD_TASTE_FAIL) {
gctl_error(req, "Failed to create array with format '%s'.",
format);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/raid/g_raid_md_if.m
--- a/head/sys/geom/raid/g_raid_md_if.m Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/raid/g_raid_md_if.m Wed Jul 25 16:45:04 2012 +0300
@@ -23,7 +23,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
-# $FreeBSD$
+# $FreeBSD: head/sys/geom/raid/g_raid_md_if.m 234940 2012-05-03 05:32:56Z mav $
#include <sys/param.h>
#include <sys/lock.h>
@@ -49,13 +49,22 @@
# Default implementations of methods.
CODE {
static int
- g_raid_md_create_default(struct g_raid_md_object *md)
+ g_raid_md_create_default(struct g_raid_md_object *md,
+ struct g_class *mp, struct g_geom **gp)
{
return (G_RAID_MD_TASTE_FAIL);
}
static int
+ g_raid_md_create_req_default(struct g_raid_md_object *md,
+ struct g_class *mp, struct gctl_req *req, struct g_geom **gp)
+ {
+
+ return (G_RAID_MD_CREATE(md, mp, gp));
+ }
+
+ static int
g_raid_md_ctl_default(struct g_raid_md_object *md,
struct gctl_req *req)
{
@@ -95,6 +104,14 @@
struct g_geom **gp;
} DEFAULT g_raid_md_create_default;
+# create_req() - create new node from scratch, with request argument.
+METHOD int create_req {
+ struct g_raid_md_object *md;
+ struct g_class *mp;
+ struct gctl_req *req;
+ struct g_geom **gp;
+} DEFAULT g_raid_md_create_req_default;
+
# taste() - taste disk and, if needed, create new node.
METHOD int taste {
struct g_raid_md_object *md;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/raid/md_ddf.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/geom/raid/md_ddf.c Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,3068 @@
+/*-
+ * Copyright (c) 2012 Alexander Motin <mav at 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 AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: head/sys/geom/raid/md_ddf.c 235096 2012-05-06 16:41:27Z mav $");
+
+#include <sys/param.h>
+#include <sys/bio.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/kobj.h>
+#include <sys/limits.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+#include <sys/clock.h>
+#include <geom/geom.h>
+#include "geom/raid/g_raid.h"
+#include "geom/raid/md_ddf.h"
+#include "g_raid_md_if.h"
+
+static MALLOC_DEFINE(M_MD_DDF, "md_ddf_data", "GEOM_RAID DDF metadata");
+
+#define DDF_MAX_DISKS_HARD 128
+
+#define DDF_MAX_DISKS 16
+#define DDF_MAX_VDISKS 7
+#define DDF_MAX_PARTITIONS 1
+
+#define DECADE (3600*24*(365*10+2)) /* 10 years in seconds. */
+
+struct ddf_meta {
+ u_int sectorsize;
+ u_int bigendian;
+ struct ddf_header *hdr;
+ struct ddf_cd_record *cdr;
+ struct ddf_pd_record *pdr;
+ struct ddf_vd_record *vdr;
+ void *cr;
+ struct ddf_pdd_record *pdd;
+ struct ddf_bbm_log *bbm;
+};
+
+struct ddf_vol_meta {
+ u_int sectorsize;
+ u_int bigendian;
+ struct ddf_header *hdr;
+ struct ddf_cd_record *cdr;
+ struct ddf_vd_entry *vde;
+ struct ddf_vdc_record *vdc;
+ struct ddf_vdc_record *bvdc[DDF_MAX_DISKS_HARD];
+};
+
+struct g_raid_md_ddf_perdisk {
+ struct ddf_meta pd_meta;
+};
+
+struct g_raid_md_ddf_pervolume {
+ struct ddf_vol_meta pv_meta;
+ int pv_started;
+ struct callout pv_start_co; /* STARTING state timer. */
+};
+
+struct g_raid_md_ddf_object {
+ struct g_raid_md_object mdio_base;
+ u_int mdio_bigendian;
+ struct ddf_meta mdio_meta;
+ int mdio_starting;
+ struct callout mdio_start_co; /* STARTING state timer. */
+ int mdio_started;
+ struct root_hold_token *mdio_rootmount; /* Root mount delay token. */
+};
+
+static g_raid_md_create_req_t g_raid_md_create_req_ddf;
+static g_raid_md_taste_t g_raid_md_taste_ddf;
+static g_raid_md_event_t g_raid_md_event_ddf;
+static g_raid_md_volume_event_t g_raid_md_volume_event_ddf;
+static g_raid_md_ctl_t g_raid_md_ctl_ddf;
+static g_raid_md_write_t g_raid_md_write_ddf;
+static g_raid_md_fail_disk_t g_raid_md_fail_disk_ddf;
+static g_raid_md_free_disk_t g_raid_md_free_disk_ddf;
+static g_raid_md_free_volume_t g_raid_md_free_volume_ddf;
+static g_raid_md_free_t g_raid_md_free_ddf;
+
+static kobj_method_t g_raid_md_ddf_methods[] = {
+ KOBJMETHOD(g_raid_md_create_req, g_raid_md_create_req_ddf),
+ KOBJMETHOD(g_raid_md_taste, g_raid_md_taste_ddf),
+ KOBJMETHOD(g_raid_md_event, g_raid_md_event_ddf),
+ KOBJMETHOD(g_raid_md_volume_event, g_raid_md_volume_event_ddf),
+ KOBJMETHOD(g_raid_md_ctl, g_raid_md_ctl_ddf),
+ KOBJMETHOD(g_raid_md_write, g_raid_md_write_ddf),
+ KOBJMETHOD(g_raid_md_fail_disk, g_raid_md_fail_disk_ddf),
+ KOBJMETHOD(g_raid_md_free_disk, g_raid_md_free_disk_ddf),
+ KOBJMETHOD(g_raid_md_free_volume, g_raid_md_free_volume_ddf),
+ KOBJMETHOD(g_raid_md_free, g_raid_md_free_ddf),
+ { 0, 0 }
+};
+
+static struct g_raid_md_class g_raid_md_ddf_class = {
+ "DDF",
+ g_raid_md_ddf_methods,
+ sizeof(struct g_raid_md_ddf_object),
+ .mdc_priority = 100
+};
+
+#define GET8(m, f) ((m)->f)
+#define GET16(m, f) ((m)->bigendian ? be16dec(&(m)->f) : le16dec(&(m)->f))
+#define GET32(m, f) ((m)->bigendian ? be32dec(&(m)->f) : le32dec(&(m)->f))
+#define GET64(m, f) ((m)->bigendian ? be64dec(&(m)->f) : le64dec(&(m)->f))
+#define GET8D(m, f) (f)
+#define GET16D(m, f) ((m)->bigendian ? be16dec(&f) : le16dec(&f))
+#define GET32D(m, f) ((m)->bigendian ? be32dec(&f) : le32dec(&f))
+#define GET64D(m, f) ((m)->bigendian ? be64dec(&f) : le64dec(&f))
+#define GET8P(m, f) (*(f))
+#define GET16P(m, f) ((m)->bigendian ? be16dec(f) : le16dec(f))
+#define GET32P(m, f) ((m)->bigendian ? be32dec(f) : le32dec(f))
+#define GET64P(m, f) ((m)->bigendian ? be64dec(f) : le64dec(f))
+
+#define SET8P(m, f, v) \
+ (*(f) = (v))
+#define SET16P(m, f, v) \
+ do { \
+ if ((m)->bigendian) \
+ be16enc((f), (v)); \
+ else \
+ le16enc((f), (v)); \
+ } while (0)
+#define SET32P(m, f, v) \
+ do { \
+ if ((m)->bigendian) \
+ be32enc((f), (v)); \
+ else \
+ le32enc((f), (v)); \
+ } while (0)
+#define SET64P(m, f, v) \
+ do { \
+ if ((m)->bigendian) \
+ be64enc((f), (v)); \
+ else \
+ le64enc((f), (v)); \
+ } while (0)
+#define SET8(m, f, v) SET8P((m), &((m)->f), (v))
+#define SET16(m, f, v) SET16P((m), &((m)->f), (v))
+#define SET32(m, f, v) SET32P((m), &((m)->f), (v))
+#define SET64(m, f, v) SET64P((m), &((m)->f), (v))
+#define SET8D(m, f, v) SET8P((m), &(f), (v))
+#define SET16D(m, f, v) SET16P((m), &(f), (v))
+#define SET32D(m, f, v) SET32P((m), &(f), (v))
+#define SET64D(m, f, v) SET64P((m), &(f), (v))
+
+#define GETCRNUM(m) (GET32((m), hdr->cr_length) / \
+ GET16((m), hdr->Configuration_Record_Length))
+
+#define GETVDCPTR(m, n) ((struct ddf_vdc_record *)((uint8_t *)(m)->cr + \
+ (n) * GET16((m), hdr->Configuration_Record_Length) * \
+ (m)->sectorsize))
+
+#define GETSAPTR(m, n) ((struct ddf_sa_record *)((uint8_t *)(m)->cr + \
+ (n) * GET16((m), hdr->Configuration_Record_Length) * \
+ (m)->sectorsize))
+
+static int
+isff(uint8_t *buf, int size)
+{
+ int i;
+
+ for (i = 0; i < size; i++)
+ if (buf[i] != 0xff)
+ return (0);
+ return (1);
+}
+
+static void
+print_guid(uint8_t *buf)
+{
+ int i, ascii;
+
+ ascii = 1;
+ for (i = 0; i < 24; i++) {
+ if (buf[i] != 0 && (buf[i] < ' ' || buf[i] > 127)) {
+ ascii = 0;
+ break;
+ }
+ }
+ if (ascii) {
+ printf("'%.24s'", buf);
+ } else {
+ for (i = 0; i < 24; i++)
+ printf("%02x", buf[i]);
+ }
+}
+
+static void
+g_raid_md_ddf_print(struct ddf_meta *meta)
+{
+ struct ddf_vdc_record *vdc;
+ struct ddf_vuc_record *vuc;
+ struct ddf_sa_record *sa;
+ uint64_t *val2;
+ uint32_t val;
+ int i, j, k, num, num2;
+
+ if (g_raid_debug < 1)
+ return;
+
+ printf("********* DDF Metadata *********\n");
+ printf("**** Header ****\n");
+ printf("DDF_Header_GUID ");
+ print_guid(meta->hdr->DDF_Header_GUID);
+ printf("\n");
+ printf("DDF_rev %8.8s\n", (char *)&meta->hdr->DDF_rev[0]);
+ printf("Sequence_Number 0x%08x\n", GET32(meta, hdr->Sequence_Number));
+ printf("TimeStamp 0x%08x\n", GET32(meta, hdr->TimeStamp));
+ printf("Open_Flag 0x%02x\n", GET16(meta, hdr->Open_Flag));
+ printf("Foreign_Flag 0x%02x\n", GET16(meta, hdr->Foreign_Flag));
+ printf("Diskgrouping 0x%02x\n", GET16(meta, hdr->Diskgrouping));
+ printf("Primary_Header_LBA %ju\n", GET64(meta, hdr->Primary_Header_LBA));
+ printf("Secondary_Header_LBA %ju\n", GET64(meta, hdr->Secondary_Header_LBA));
+ printf("WorkSpace_Length %u\n", GET32(meta, hdr->WorkSpace_Length));
+ printf("WorkSpace_LBA %ju\n", GET64(meta, hdr->WorkSpace_LBA));
+ printf("Max_PD_Entries %u\n", GET16(meta, hdr->Max_PD_Entries));
+ printf("Max_VD_Entries %u\n", GET16(meta, hdr->Max_VD_Entries));
+ printf("Max_Partitions %u\n", GET16(meta, hdr->Max_Partitions));
+ printf("Configuration_Record_Length %u\n", GET16(meta, hdr->Configuration_Record_Length));
+ printf("Max_Primary_Element_Entries %u\n", GET16(meta, hdr->Max_Primary_Element_Entries));
+ printf("Controller Data %u:%u\n", GET32(meta, hdr->cd_section), GET32(meta, hdr->cd_length));
+ printf("Physical Disk %u:%u\n", GET32(meta, hdr->pdr_section), GET32(meta, hdr->pdr_length));
+ printf("Virtual Disk %u:%u\n", GET32(meta, hdr->vdr_section), GET32(meta, hdr->vdr_length));
+ printf("Configuration Recs %u:%u\n", GET32(meta, hdr->cr_section), GET32(meta, hdr->cr_length));
+ printf("Physical Disk Recs %u:%u\n", GET32(meta, hdr->pdd_section), GET32(meta, hdr->pdd_length));
+ printf("BBM Log %u:%u\n", GET32(meta, hdr->bbmlog_section), GET32(meta, hdr->bbmlog_length));
+ printf("Diagnostic Space %u:%u\n", GET32(meta, hdr->Diagnostic_Space), GET32(meta, hdr->Diagnostic_Space_Length));
+ printf("Vendor_Specific_Logs %u:%u\n", GET32(meta, hdr->Vendor_Specific_Logs), GET32(meta, hdr->Vendor_Specific_Logs_Length));
+ printf("**** Controler Data ****\n");
+ printf("Controller_GUID ");
+ print_guid(meta->cdr->Controller_GUID);
+ printf("\n");
+ printf("Controller_Type 0x%04x%04x 0x%04x%04x\n",
+ GET16(meta, cdr->Controller_Type.Vendor_ID),
+ GET16(meta, cdr->Controller_Type.Device_ID),
+ GET16(meta, cdr->Controller_Type.SubVendor_ID),
+ GET16(meta, cdr->Controller_Type.SubDevice_ID));
+ printf("Product_ID '%.16s'\n", (char *)&meta->cdr->Product_ID[0]);
+ printf("**** Physical Disk Records ****\n");
+ printf("Populated_PDEs %u\n", GET16(meta, pdr->Populated_PDEs));
+ printf("Max_PDE_Supported %u\n", GET16(meta, pdr->Max_PDE_Supported));
+ for (j = 0; j < GET16(meta, pdr->Populated_PDEs); j++) {
+ if (isff(meta->pdr->entry[j].PD_GUID, 24))
+ continue;
+ if (GET32(meta, pdr->entry[j].PD_Reference) == 0xffffffff)
+ continue;
+ printf("PD_GUID ");
+ print_guid(meta->pdr->entry[j].PD_GUID);
+ printf("\n");
+ printf("PD_Reference 0x%08x\n",
+ GET32(meta, pdr->entry[j].PD_Reference));
+ printf("PD_Type 0x%04x\n",
+ GET16(meta, pdr->entry[j].PD_Type));
+ printf("PD_State 0x%04x\n",
+ GET16(meta, pdr->entry[j].PD_State));
+ printf("Configured_Size %ju\n",
+ GET64(meta, pdr->entry[j].Configured_Size));
+ printf("Block_Size %u\n",
+ GET16(meta, pdr->entry[j].Block_Size));
+ }
+ printf("**** Virtual Disk Records ****\n");
+ printf("Populated_VDEs %u\n", GET16(meta, vdr->Populated_VDEs));
+ printf("Max_VDE_Supported %u\n", GET16(meta, vdr->Max_VDE_Supported));
+ for (j = 0; j < GET16(meta, vdr->Populated_VDEs); j++) {
+ if (isff(meta->vdr->entry[j].VD_GUID, 24))
+ continue;
+ printf("VD_GUID ");
+ print_guid(meta->vdr->entry[j].VD_GUID);
+ printf("\n");
+ printf("VD_Number 0x%04x\n",
+ GET16(meta, vdr->entry[j].VD_Number));
+ printf("VD_Type 0x%04x\n",
+ GET16(meta, vdr->entry[j].VD_Type));
+ printf("VD_State 0x%02x\n",
+ GET8(meta, vdr->entry[j].VD_State));
+ printf("Init_State 0x%02x\n",
+ GET8(meta, vdr->entry[j].Init_State));
+ printf("Drive_Failures_Remaining %u\n",
+ GET8(meta, vdr->entry[j].Drive_Failures_Remaining));
+ printf("VD_Name '%.16s'\n",
+ (char *)&meta->vdr->entry[j].VD_Name);
+ }
+ printf("**** Configuration Records ****\n");
+ num = GETCRNUM(meta);
+ for (j = 0; j < num; j++) {
+ vdc = GETVDCPTR(meta, j);
+ val = GET32D(meta, vdc->Signature);
+ switch (val) {
+ case DDF_VDCR_SIGNATURE:
+ printf("** Virtual Disk Configuration **\n");
+ printf("VD_GUID ");
+ print_guid(vdc->VD_GUID);
+ printf("\n");
+ printf("Timestamp 0x%08x\n",
+ GET32D(meta, vdc->Timestamp));
+ printf("Sequence_Number 0x%08x\n",
+ GET32D(meta, vdc->Sequence_Number));
+ printf("Primary_Element_Count %u\n",
+ GET16D(meta, vdc->Primary_Element_Count));
+ printf("Stripe_Size %u\n",
+ GET8D(meta, vdc->Stripe_Size));
+ printf("Primary_RAID_Level 0x%02x\n",
+ GET8D(meta, vdc->Primary_RAID_Level));
+ printf("RLQ 0x%02x\n",
+ GET8D(meta, vdc->RLQ));
+ printf("Secondary_Element_Count %u\n",
+ GET8D(meta, vdc->Secondary_Element_Count));
+ printf("Secondary_Element_Seq %u\n",
+ GET8D(meta, vdc->Secondary_Element_Seq));
+ printf("Secondary_RAID_Level 0x%02x\n",
+ GET8D(meta, vdc->Secondary_RAID_Level));
+ printf("Block_Count %ju\n",
+ GET64D(meta, vdc->Block_Count));
+ printf("VD_Size %ju\n",
+ GET64D(meta, vdc->VD_Size));
+ printf("Block_Size %u\n",
+ GET16D(meta, vdc->Block_Size));
+ printf("Rotate_Parity_count %u\n",
+ GET8D(meta, vdc->Rotate_Parity_count));
+ printf("Associated_Spare_Disks");
+ for (i = 0; i < 8; i++) {
+ if (GET32D(meta, vdc->Associated_Spares[i]) != 0xffffffff)
+ printf(" 0x%08x", GET32D(meta, vdc->Associated_Spares[i]));
+ }
+ printf("\n");
+ printf("Cache_Flags %016jx\n",
+ GET64D(meta, vdc->Cache_Flags));
+ printf("BG_Rate %u\n",
+ GET8D(meta, vdc->BG_Rate));
+ printf("MDF_Parity_Disks %u\n",
+ GET8D(meta, vdc->MDF_Parity_Disks));
+ printf("MDF_Parity_Generator_Polynomial 0x%04x\n",
+ GET16D(meta, vdc->MDF_Parity_Generator_Polynomial));
+ printf("MDF_Constant_Generation_Method 0x%02x\n",
+ GET8D(meta, vdc->MDF_Constant_Generation_Method));
+ printf("Physical_Disks ");
+ num2 = GET16D(meta, vdc->Primary_Element_Count);
+ val2 = (uint64_t *)&(vdc->Physical_Disk_Sequence[GET16(meta, hdr->Max_Primary_Element_Entries)]);
+ for (i = 0; i < num2; i++)
+ printf(" 0x%08x @ %ju",
+ GET32D(meta, vdc->Physical_Disk_Sequence[i]),
+ GET64P(meta, val2 + i));
+ printf("\n");
+ break;
+ case DDF_VUCR_SIGNATURE:
+ printf("** Vendor Unique Configuration **\n");
+ vuc = (struct ddf_vuc_record *)vdc;
+ printf("VD_GUID ");
+ print_guid(vuc->VD_GUID);
+ printf("\n");
+ break;
+ case DDF_SA_SIGNATURE:
+ printf("** Spare Assignment Configuration **\n");
+ sa = (struct ddf_sa_record *)vdc;
+ printf("Timestamp 0x%08x\n",
+ GET32D(meta, sa->Timestamp));
+ printf("Spare_Type 0x%02x\n",
+ GET8D(meta, sa->Spare_Type));
+ printf("Populated_SAEs %u\n",
+ GET16D(meta, sa->Populated_SAEs));
+ printf("MAX_SAE_Supported %u\n",
+ GET16D(meta, sa->MAX_SAE_Supported));
+ for (i = 0; i < GET16D(meta, sa->Populated_SAEs); i++) {
+ if (isff(sa->entry[i].VD_GUID, 24))
+ continue;
+ printf("VD_GUID ");
+ for (k = 0; k < 24; k++)
+ printf("%02x", sa->entry[i].VD_GUID[k]);
+ printf("\n");
+ printf("Secondary_Element %u\n",
+ GET16D(meta, sa->entry[i].Secondary_Element));
+ }
+ break;
+ case 0x00000000:
+ case 0xFFFFFFFF:
+ break;
+ default:
+ printf("Unknown configuration signature %08x\n", val);
+ break;
+ }
+ }
+ printf("**** Physical Disk Data ****\n");
+ printf("PD_GUID ");
+ print_guid(meta->pdd->PD_GUID);
+ printf("\n");
+ printf("PD_Reference 0x%08x\n",
+ GET32(meta, pdd->PD_Reference));
+ printf("Forced_Ref_Flag 0x%02x\n",
+ GET8(meta, pdd->Forced_Ref_Flag));
+ printf("Forced_PD_GUID_Flag 0x%02x\n",
+ GET8(meta, pdd->Forced_PD_GUID_Flag));
+}
+
+static int
+ddf_meta_find_pd(struct ddf_meta *meta, uint8_t *GUID, uint32_t PD_Reference)
+{
+ int i;
+
+ for (i = 0; i < GET16(meta, pdr->Populated_PDEs); i++) {
+ if (GUID != NULL) {
+ if (memcmp(meta->pdr->entry[i].PD_GUID, GUID, 24) == 0)
+ return (i);
+ } else if (PD_Reference != 0xffffffff) {
+ if (GET32(meta, pdr->entry[i].PD_Reference) == PD_Reference)
+ return (i);
+ } else
+ if (isff(meta->pdr->entry[i].PD_GUID, 24))
+ return (i);
+ }
+ if (GUID == NULL && PD_Reference == 0xffffffff) {
+ if (i >= GET16(meta, pdr->Max_PDE_Supported))
+ return (-1);
+ SET16(meta, pdr->Populated_PDEs, i + 1);
+ return (i);
+ }
+ return (-1);
+}
+
+static int
+ddf_meta_find_vd(struct ddf_meta *meta, uint8_t *GUID)
+{
+ int i;
+
+ for (i = 0; i < GET16(meta, vdr->Populated_VDEs); i++) {
+ if (GUID != NULL) {
+ if (memcmp(meta->vdr->entry[i].VD_GUID, GUID, 24) == 0)
+ return (i);
+ } else
+ if (isff(meta->vdr->entry[i].VD_GUID, 24))
+ return (i);
+ }
+ if (GUID == NULL) {
+ if (i >= GET16(meta, vdr->Max_VDE_Supported))
+ return (-1);
+ SET16(meta, vdr->Populated_VDEs, i + 1);
+ return (i);
+ }
+ return (-1);
+}
+
+static struct ddf_vdc_record *
+ddf_meta_find_vdc(struct ddf_meta *meta, uint8_t *GUID)
+{
+ struct ddf_vdc_record *vdc;
+ int i, num;
+
+ num = GETCRNUM(meta);
+ for (i = 0; i < num; i++) {
+ vdc = GETVDCPTR(meta, i);
+ if (GUID != NULL) {
+ if (GET32D(meta, vdc->Signature) == DDF_VDCR_SIGNATURE &&
+ memcmp(vdc->VD_GUID, GUID, 24) == 0)
+ return (vdc);
+ } else
+ if (GET32D(meta, vdc->Signature) == 0xffffffff ||
+ GET32D(meta, vdc->Signature) == 0)
+ return (vdc);
+ }
+ return (NULL);
+}
+
+static int
+ddf_meta_count_vdc(struct ddf_meta *meta, uint8_t *GUID)
+{
+ struct ddf_vdc_record *vdc;
+ int i, num, cnt;
+
+ cnt = 0;
+ num = GETCRNUM(meta);
+ for (i = 0; i < num; i++) {
+ vdc = GETVDCPTR(meta, i);
+ if (GET32D(meta, vdc->Signature) != DDF_VDCR_SIGNATURE)
+ continue;
+ if (GUID == NULL || memcmp(vdc->VD_GUID, GUID, 24) == 0)
+ cnt++;
+ }
+ return (cnt);
+}
+
+static int
+ddf_meta_find_disk(struct ddf_vol_meta *vmeta, uint32_t PD_Reference,
+ int *bvdp, int *posp)
+{
+ int i, bvd, pos;
+
+ i = 0;
+ for (bvd = 0; bvd < GET16(vmeta, vdc->Secondary_Element_Count); bvd++) {
+ if (vmeta->bvdc[bvd] == NULL) {
+ i += GET16(vmeta, vdc->Primary_Element_Count); // XXX
+ continue;
+ }
+ for (pos = 0; pos < GET16(vmeta, bvdc[bvd]->Primary_Element_Count);
+ pos++, i++) {
+ if (GET32(vmeta, bvdc[bvd]->Physical_Disk_Sequence[pos]) ==
+ PD_Reference) {
+ if (bvdp != NULL)
+ *bvdp = bvd;
+ if (posp != NULL)
+ *posp = pos;
+ return (i);
+ }
+ }
+ }
+ return (-1);
+}
+
+static struct ddf_sa_record *
+ddf_meta_find_sa(struct ddf_meta *meta, int create)
+{
+ struct ddf_sa_record *sa;
+ int i, num;
+
+ num = GETCRNUM(meta);
+ for (i = 0; i < num; i++) {
+ sa = GETSAPTR(meta, i);
+ if (GET32D(meta, sa->Signature) == DDF_SA_SIGNATURE)
+ return (sa);
+ }
+ if (create) {
+ for (i = 0; i < num; i++) {
+ sa = GETSAPTR(meta, i);
+ if (GET32D(meta, sa->Signature) == 0xffffffff ||
+ GET32D(meta, sa->Signature) == 0)
+ return (sa);
+ }
+ }
+ return (NULL);
+}
+
+static void
+ddf_meta_create(struct g_raid_disk *disk, struct ddf_meta *sample)
+{
+ struct timespec ts;
+ struct clocktime ct;
+ struct g_raid_md_ddf_perdisk *pd;
+ struct g_raid_md_ddf_object *mdi;
+ struct ddf_meta *meta;
+ struct ddf_pd_entry *pde;
+ off_t anchorlba;
+ u_int ss, pos, size;
+ int len, error;
+ char serial_buffer[24];
+
+ if (sample->hdr == NULL)
+ sample = NULL;
+
+ mdi = (struct g_raid_md_ddf_object *)disk->d_softc->sc_md;
+ pd = (struct g_raid_md_ddf_perdisk *)disk->d_md_data;
+ meta = &pd->pd_meta;
+ ss = disk->d_consumer->provider->sectorsize;
+ anchorlba = disk->d_consumer->provider->mediasize / ss - 1;
+
+ meta->sectorsize = ss;
+ meta->bigendian = sample ? sample->bigendian : mdi->mdio_bigendian;
+ getnanotime(&ts);
+ clock_ts_to_ct(&ts, &ct);
+
+ /* Header */
+ meta->hdr = malloc(ss, M_MD_DDF, M_WAITOK);
+ memset(meta->hdr, 0xff, ss);
+ if (sample) {
+ memcpy(meta->hdr, sample->hdr, sizeof(struct ddf_header));
+ if (ss != sample->sectorsize) {
+ SET32(meta, hdr->WorkSpace_Length,
+ (GET32(sample, hdr->WorkSpace_Length) *
+ sample->sectorsize + ss - 1) / ss);
+ SET16(meta, hdr->Configuration_Record_Length,
+ (GET16(sample, hdr->Configuration_Record_Length) *
+ sample->sectorsize + ss - 1) / ss);
+ SET32(meta, hdr->cd_length,
+ (GET32(sample, hdr->cd_length) *
+ sample->sectorsize + ss - 1) / ss);
+ SET32(meta, hdr->pdr_length,
+ (GET32(sample, hdr->pdr_length) *
+ sample->sectorsize + ss - 1) / ss);
+ SET32(meta, hdr->vdr_length,
+ (GET32(sample, hdr->vdr_length) *
+ sample->sectorsize + ss - 1) / ss);
+ SET32(meta, hdr->cr_length,
+ (GET32(sample, hdr->cr_length) *
+ sample->sectorsize + ss - 1) / ss);
+ SET32(meta, hdr->pdd_length,
+ (GET32(sample, hdr->pdd_length) *
+ sample->sectorsize + ss - 1) / ss);
+ SET32(meta, hdr->bbmlog_length,
+ (GET32(sample, hdr->bbmlog_length) *
+ sample->sectorsize + ss - 1) / ss);
+ SET32(meta, hdr->Diagnostic_Space,
+ (GET32(sample, hdr->bbmlog_length) *
+ sample->sectorsize + ss - 1) / ss);
+ SET32(meta, hdr->Vendor_Specific_Logs,
+ (GET32(sample, hdr->bbmlog_length) *
+ sample->sectorsize + ss - 1) / ss);
+ }
+ } else {
+ SET32(meta, hdr->Signature, DDF_HEADER_SIGNATURE);
+ snprintf(meta->hdr->DDF_Header_GUID, 25, "FreeBSD %08x%08x",
+ (u_int)(ts.tv_sec - DECADE), arc4random());
+ memcpy(meta->hdr->DDF_rev, "02.00.00", 8);
+ SET32(meta, hdr->TimeStamp, (ts.tv_sec - DECADE));
+ SET32(meta, hdr->WorkSpace_Length, 16 * 1024 * 1024 / ss);
+ SET16(meta, hdr->Max_PD_Entries, DDF_MAX_DISKS - 1);
+ SET16(meta, hdr->Max_VD_Entries, DDF_MAX_VDISKS);
+ SET16(meta, hdr->Max_Partitions, DDF_MAX_PARTITIONS);
+ SET16(meta, hdr->Max_Primary_Element_Entries, DDF_MAX_DISKS);
+ SET16(meta, hdr->Configuration_Record_Length,
+ (sizeof(struct ddf_vdc_record) +
+ (4 + 8) * GET16(meta, hdr->Max_Primary_Element_Entries) +
+ ss - 1) / ss);
+ SET32(meta, hdr->cd_length,
+ (sizeof(struct ddf_cd_record) + ss - 1) / ss);
+ SET32(meta, hdr->pdr_length,
+ (sizeof(struct ddf_pd_record) +
+ sizeof(struct ddf_pd_entry) *
+ GET16(meta, hdr->Max_PD_Entries) + ss - 1) / ss);
+ SET32(meta, hdr->vdr_length,
+ (sizeof(struct ddf_vd_record) +
+ sizeof(struct ddf_vd_entry) *
+ GET16(meta, hdr->Max_VD_Entries) + ss - 1) / ss);
+ SET32(meta, hdr->cr_length,
+ GET16(meta, hdr->Configuration_Record_Length) *
+ (GET16(meta, hdr->Max_Partitions) + 1));
+ SET32(meta, hdr->pdd_length,
+ (sizeof(struct ddf_pdd_record) + ss - 1) / ss);
+ SET32(meta, hdr->bbmlog_length, 0);
+ SET32(meta, hdr->Diagnostic_Space_Length, 0);
+ SET32(meta, hdr->Vendor_Specific_Logs_Length, 0);
+ }
+ pos = 1;
+ SET32(meta, hdr->cd_section, pos);
+ pos += GET32(meta, hdr->cd_length);
+ SET32(meta, hdr->pdr_section, pos);
+ pos += GET32(meta, hdr->pdr_length);
+ SET32(meta, hdr->vdr_section, pos);
+ pos += GET32(meta, hdr->vdr_length);
+ SET32(meta, hdr->cr_section, pos);
+ pos += GET32(meta, hdr->cr_length);
+ SET32(meta, hdr->pdd_section, pos);
+ pos += GET32(meta, hdr->pdd_length);
+ SET32(meta, hdr->bbmlog_section,
+ GET32(meta, hdr->bbmlog_length) != 0 ? pos : 0xffffffff);
+ pos += GET32(meta, hdr->bbmlog_length);
+ SET32(meta, hdr->Diagnostic_Space,
+ GET32(meta, hdr->Diagnostic_Space_Length) != 0 ? pos : 0xffffffff);
+ pos += GET32(meta, hdr->Diagnostic_Space_Length);
+ SET32(meta, hdr->Vendor_Specific_Logs,
+ GET32(meta, hdr->Vendor_Specific_Logs_Length) != 0 ? pos : 0xffffffff);
+ pos += min(GET32(meta, hdr->Vendor_Specific_Logs_Length), 1);
+ SET64(meta, hdr->Primary_Header_LBA,
+ anchorlba - pos);
+ SET64(meta, hdr->Secondary_Header_LBA,
+ 0xffffffffffffffffULL);
+ SET64(meta, hdr->WorkSpace_LBA,
+ anchorlba + 1 - 32 * 1024 * 1024 / ss);
+
+ /* Controller Data */
+ size = GET32(meta, hdr->cd_length) * ss;
+ meta->cdr = malloc(size, M_MD_DDF, M_WAITOK);
+ memset(meta->cdr, 0xff, size);
+ SET32(meta, cdr->Signature, DDF_CONTROLLER_DATA_SIGNATURE);
+ memcpy(meta->cdr->Controller_GUID, "FreeBSD GEOM RAID SERIAL", 24);
+ memcpy(meta->cdr->Product_ID, "FreeBSD GEOMRAID", 16);
+
+ /* Physical Drive Records. */
+ size = GET32(meta, hdr->pdr_length) * ss;
+ meta->pdr = malloc(size, M_MD_DDF, M_WAITOK);
+ memset(meta->pdr, 0xff, size);
+ SET32(meta, pdr->Signature, DDF_PDR_SIGNATURE);
+ SET16(meta, pdr->Populated_PDEs, 1);
+ SET16(meta, pdr->Max_PDE_Supported,
+ GET16(meta, hdr->Max_PD_Entries));
+
+ pde = &meta->pdr->entry[0];
+ len = sizeof(serial_buffer);
+ error = g_io_getattr("GEOM::ident", disk->d_consumer, &len, serial_buffer);
+ if (error == 0 && (len = strlen (serial_buffer)) >= 6 && len <= 20)
+ snprintf(pde->PD_GUID, 25, "DISK%20s", serial_buffer);
+ else
+ snprintf(pde->PD_GUID, 25, "DISK%04d%02d%02d%08x%04x",
+ ct.year, ct.mon, ct.day,
+ arc4random(), arc4random() & 0xffff);
+ SET32D(meta, pde->PD_Reference, arc4random());
+ SET16D(meta, pde->PD_Type, DDF_PDE_GUID_FORCE);
+ SET16D(meta, pde->PD_State, 0);
+ SET64D(meta, pde->Configured_Size,
+ anchorlba + 1 - 32 * 1024 * 1024 / ss);
+ SET16D(meta, pde->Block_Size, ss);
+
+ /* Virtual Drive Records. */
+ size = GET32(meta, hdr->vdr_length) * ss;
+ meta->vdr = malloc(size, M_MD_DDF, M_WAITOK);
+ memset(meta->vdr, 0xff, size);
+ SET32(meta, vdr->Signature, DDF_VD_RECORD_SIGNATURE);
+ SET32(meta, vdr->Populated_VDEs, 0);
+ SET16(meta, vdr->Max_VDE_Supported,
+ GET16(meta, hdr->Max_VD_Entries));
+
+ /* Configuration Records. */
+ size = GET32(meta, hdr->cr_length) * ss;
+ meta->cr = malloc(size, M_MD_DDF, M_WAITOK);
+ memset(meta->cr, 0xff, size);
+
+ /* Physical Disk Data. */
+ size = GET32(meta, hdr->pdd_length) * ss;
+ meta->pdd = malloc(size, M_MD_DDF, M_WAITOK);
+ memset(meta->pdd, 0xff, size);
+ SET32(meta, pdd->Signature, DDF_PDD_SIGNATURE);
+ memcpy(meta->pdd->PD_GUID, pde->PD_GUID, 24);
+ SET32(meta, pdd->PD_Reference, GET32D(meta, pde->PD_Reference));
+ SET8(meta, pdd->Forced_Ref_Flag, DDF_PDD_FORCED_REF);
+ SET8(meta, pdd->Forced_PD_GUID_Flag, DDF_PDD_FORCED_GUID);
+
+ /* Bad Block Management Log. */
+ if (GET32(meta, hdr->bbmlog_length) != 0) {
+ size = GET32(meta, hdr->bbmlog_length) * ss;
+ meta->bbm = malloc(size, M_MD_DDF, M_WAITOK);
+ memset(meta->bbm, 0xff, size);
+ SET32(meta, bbm->Signature, DDF_BBML_SIGNATURE);
+ SET32(meta, bbm->Entry_Count, 0);
+ SET32(meta, bbm->Spare_Block_Count, 0);
+ }
+}
+
+static void
+ddf_meta_copy(struct ddf_meta *dst, struct ddf_meta *src)
+{
+ struct ddf_header *hdr;
+ u_int ss;
+
+ hdr = src->hdr;
+ dst->bigendian = src->bigendian;
+ ss = dst->sectorsize = src->sectorsize;
+ dst->hdr = malloc(ss, M_MD_DDF, M_WAITOK);
+ memcpy(dst->hdr, src->hdr, ss);
+ dst->cdr = malloc(GET32(src, hdr->cd_length) * ss, M_MD_DDF, M_WAITOK);
+ memcpy(dst->cdr, src->cdr, GET32(src, hdr->cd_length) * ss);
+ dst->pdr = malloc(GET32(src, hdr->pdr_length) * ss, M_MD_DDF, M_WAITOK);
+ memcpy(dst->pdr, src->pdr, GET32(src, hdr->pdr_length) * ss);
+ dst->vdr = malloc(GET32(src, hdr->vdr_length) * ss, M_MD_DDF, M_WAITOK);
+ memcpy(dst->vdr, src->vdr, GET32(src, hdr->vdr_length) * ss);
+ dst->cr = malloc(GET32(src, hdr->cr_length) * ss, M_MD_DDF, M_WAITOK);
+ memcpy(dst->cr, src->cr, GET32(src, hdr->cr_length) * ss);
+ dst->pdd = malloc(GET32(src, hdr->pdd_length) * ss, M_MD_DDF, M_WAITOK);
+ memcpy(dst->pdd, src->pdd, GET32(src, hdr->pdd_length) * ss);
+ if (src->bbm != NULL) {
+ dst->bbm = malloc(GET32(src, hdr->bbmlog_length) * ss, M_MD_DDF, M_WAITOK);
+ memcpy(dst->bbm, src->bbm, GET32(src, hdr->bbmlog_length) * ss);
+ }
+}
+
+static void
+ddf_meta_update(struct ddf_meta *meta, struct ddf_meta *src)
+{
+ struct ddf_pd_entry *pde, *spde;
+ int i, j;
+
+ for (i = 0; i < GET16(src, pdr->Populated_PDEs); i++) {
+ spde = &src->pdr->entry[i];
+ if (isff(spde->PD_GUID, 24))
+ continue;
+ j = ddf_meta_find_pd(meta, NULL,
+ GET32(src, pdr->entry[i].PD_Reference));
+ if (j < 0) {
+ j = ddf_meta_find_pd(meta, NULL, 0xffffffff);
+ pde = &meta->pdr->entry[j];
+ memcpy(pde, spde, sizeof(*pde));
+ } else {
+ pde = &meta->pdr->entry[j];
+ SET16D(meta, pde->PD_State,
+ GET16D(meta, pde->PD_State) |
+ GET16D(src, pde->PD_State));
+ }
+ }
+}
+
+static void
+ddf_meta_free(struct ddf_meta *meta)
+{
+
+ if (meta->hdr != NULL) {
+ free(meta->hdr, M_MD_DDF);
+ meta->hdr = NULL;
+ }
+ if (meta->cdr != NULL) {
+ free(meta->cdr, M_MD_DDF);
+ meta->cdr = NULL;
+ }
+ if (meta->pdr != NULL) {
+ free(meta->pdr, M_MD_DDF);
+ meta->pdr = NULL;
+ }
+ if (meta->vdr != NULL) {
+ free(meta->vdr, M_MD_DDF);
+ meta->vdr = NULL;
+ }
+ if (meta->cr != NULL) {
+ free(meta->cr, M_MD_DDF);
+ meta->cr = NULL;
+ }
+ if (meta->pdd != NULL) {
+ free(meta->pdd, M_MD_DDF);
+ meta->pdd = NULL;
+ }
+ if (meta->bbm != NULL) {
+ free(meta->bbm, M_MD_DDF);
+ meta->bbm = NULL;
+ }
+}
+
+static void
+ddf_vol_meta_create(struct ddf_vol_meta *meta, struct ddf_meta *sample)
+{
+ struct timespec ts;
+ struct clocktime ct;
+ struct ddf_header *hdr;
+ u_int ss, size;
+
+ hdr = sample->hdr;
+ meta->bigendian = sample->bigendian;
+ ss = meta->sectorsize = sample->sectorsize;
+ meta->hdr = malloc(ss, M_MD_DDF, M_WAITOK);
+ memcpy(meta->hdr, sample->hdr, ss);
+ meta->cdr = malloc(GET32(sample, hdr->cd_length) * ss, M_MD_DDF, M_WAITOK);
+ memcpy(meta->cdr, sample->cdr, GET32(sample, hdr->cd_length) * ss);
+ meta->vde = malloc(sizeof(struct ddf_vd_entry), M_MD_DDF, M_WAITOK);
+ memset(meta->vde, 0xff, sizeof(struct ddf_vd_entry));
+ getnanotime(&ts);
+ clock_ts_to_ct(&ts, &ct);
+ snprintf(meta->vde->VD_GUID, 25, "FreeBSD%04d%02d%02d%08x%01x",
+ ct.year, ct.mon, ct.day,
+ arc4random(), arc4random() & 0xf);
+ size = GET16(sample, hdr->Configuration_Record_Length) * ss;
+ meta->vdc = malloc(size, M_MD_DDF, M_WAITOK);
+ memset(meta->vdc, 0xff, size);
+ SET32(meta, vdc->Signature, DDF_VDCR_SIGNATURE);
+ memcpy(meta->vdc->VD_GUID, meta->vde->VD_GUID, 24);
+ SET32(meta, vdc->Sequence_Number, 0);
+}
+
+static void
+ddf_vol_meta_update(struct ddf_vol_meta *dst, struct ddf_meta *src,
+ uint8_t *GUID, int started)
+{
+ struct ddf_header *hdr;
+ struct ddf_vd_entry *vde;
+ struct ddf_vdc_record *vdc;
+ int vnew, bvnew, bvd, size;
+ u_int ss;
+
+ hdr = src->hdr;
+ vde = &src->vdr->entry[ddf_meta_find_vd(src, GUID)];
+ vdc = ddf_meta_find_vdc(src, GUID);
+ bvd = GET8D(src, vdc->Secondary_Element_Seq);
+ size = GET16(src, hdr->Configuration_Record_Length) * src->sectorsize;
+
+ if (dst->vdc == NULL ||
+ (!started && ((int32_t)(GET32D(src, vdc->Sequence_Number) -
+ GET32(dst, vdc->Sequence_Number))) > 0))
+ vnew = 1;
+ else
+ vnew = 0;
+
+ if (dst->bvdc[bvd] == NULL ||
+ (!started && ((int32_t)(GET32D(src, vdc->Sequence_Number) -
+ GET32(dst, bvdc[bvd]->Sequence_Number))) > 0))
+ bvnew = 1;
+ else
+ bvnew = 0;
+
+ if (vnew) {
+ dst->bigendian = src->bigendian;
+ ss = dst->sectorsize = src->sectorsize;
+ if (dst->hdr != NULL)
+ free(dst->hdr, M_MD_DDF);
+ dst->hdr = malloc(ss, M_MD_DDF, M_WAITOK);
+ memcpy(dst->hdr, src->hdr, ss);
+ if (dst->cdr != NULL)
+ free(dst->cdr, M_MD_DDF);
+ dst->cdr = malloc(GET32(src, hdr->cd_length) * ss, M_MD_DDF, M_WAITOK);
+ memcpy(dst->cdr, src->cdr, GET32(src, hdr->cd_length) * ss);
+ if (dst->vde != NULL)
+ free(dst->vde, M_MD_DDF);
+ dst->vde = malloc(sizeof(struct ddf_vd_entry), M_MD_DDF, M_WAITOK);
+ memcpy(dst->vde, vde, sizeof(struct ddf_vd_entry));
+ if (dst->vdc != NULL)
+ free(dst->vdc, M_MD_DDF);
+ dst->vdc = malloc(size, M_MD_DDF, M_WAITOK);
+ memcpy(dst->vdc, vdc, size);
+ }
+ if (bvnew) {
+ if (dst->bvdc[bvd] != NULL)
+ free(dst->bvdc[bvd], M_MD_DDF);
+ dst->bvdc[bvd] = malloc(size, M_MD_DDF, M_WAITOK);
+ memcpy(dst->bvdc[bvd], vdc, size);
+ }
+}
+
+static void
+ddf_vol_meta_free(struct ddf_vol_meta *meta)
+{
+ int i;
+
+ if (meta->hdr != NULL) {
+ free(meta->hdr, M_MD_DDF);
+ meta->hdr = NULL;
+ }
+ if (meta->cdr != NULL) {
+ free(meta->cdr, M_MD_DDF);
+ meta->cdr = NULL;
+ }
+ if (meta->vde != NULL) {
+ free(meta->vde, M_MD_DDF);
+ meta->vde = NULL;
+ }
+ if (meta->vdc != NULL) {
+ free(meta->vdc, M_MD_DDF);
+ meta->vdc = NULL;
+ }
+ for (i = 0; i < DDF_MAX_DISKS_HARD; i++) {
+ if (meta->bvdc[i] != NULL) {
+ free(meta->bvdc[i], M_MD_DDF);
+ meta->bvdc[i] = NULL;
+ }
+ }
+}
+
+static int
+ddf_meta_unused_range(struct ddf_meta *meta, off_t *off, off_t *size)
+{
+ struct ddf_vdc_record *vdc;
+ off_t beg[32], end[32], beg1, end1;
+ uint64_t *offp;
+ int i, j, n, num, pos;
+ uint32_t ref;
+
+ *off = 0;
+ *size = 0;
+ ref = GET32(meta, pdd->PD_Reference);
+ pos = ddf_meta_find_pd(meta, NULL, ref);
+ beg[0] = 0;
+ end[0] = GET64(meta, pdr->entry[pos].Configured_Size);
+ n = 1;
+ num = GETCRNUM(meta);
+ for (i = 0; i < num; i++) {
+ vdc = GETVDCPTR(meta, i);
+ if (GET32D(meta, vdc->Signature) != DDF_VDCR_SIGNATURE)
+ continue;
+ for (pos = 0; pos < GET16D(meta, vdc->Primary_Element_Count); pos++)
+ if (GET32D(meta, vdc->Physical_Disk_Sequence[pos]) == ref)
+ break;
+ if (pos == GET16D(meta, vdc->Primary_Element_Count))
+ continue;
+ offp = (uint64_t *)&(vdc->Physical_Disk_Sequence[
+ GET16(meta, hdr->Max_Primary_Element_Entries)]);
+ beg1 = GET64P(meta, offp + pos);
+ end1 = beg1 + GET64D(meta, vdc->Block_Count);
+ for (j = 0; j < n; j++) {
+ if (beg[j] >= end1 || end[j] <= beg1 )
+ continue;
+ if (beg[j] < beg1 && end[j] > end1) {
+ beg[n] = end1;
+ end[n] = end[j];
+ end[j] = beg1;
+ n++;
+ } else if (beg[j] < beg1)
+ end[j] = beg1;
+ else
+ beg[j] = end1;
+ }
+ }
+ for (j = 0; j < n; j++) {
+ if (end[j] - beg[j] > *size) {
+ *off = beg[j];
+ *size = end[j] - beg[j];
+ }
+ }
+ return ((*size > 0) ? 1 : 0);
+}
+
+static void
+ddf_meta_get_name(struct ddf_meta *meta, int num, char *buf)
+{
+ const char *b;
+ int i;
+
+ b = meta->vdr->entry[num].VD_Name;
+ for (i = 15; i >= 0; i--)
+ if (b[i] != 0x20)
+ break;
+ memcpy(buf, b, i + 1);
+ buf[i + 1] = 0;
+}
+
+static void
+ddf_meta_put_name(struct ddf_vol_meta *meta, char *buf)
+{
+ int len;
+
+ len = min(strlen(buf), 16);
+ memset(meta->vde->VD_Name, 0x20, 16);
+ memcpy(meta->vde->VD_Name, buf, len);
+}
+
+static int
+ddf_meta_read(struct g_consumer *cp, struct ddf_meta *meta)
+{
+ struct g_provider *pp;
+ struct ddf_header *ahdr, *hdr;
+ char *abuf, *buf;
+ off_t plba, slba, lba;
+ int error, len, i;
+ u_int ss;
+ uint32_t val;
+
+ ddf_meta_free(meta);
+ pp = cp->provider;
+ ss = meta->sectorsize = pp->sectorsize;
+ /* Read anchor block. */
+ abuf = g_read_data(cp, pp->mediasize - ss, ss, &error);
+ if (abuf == NULL) {
+ G_RAID_DEBUG(1, "Cannot read metadata from %s (error=%d).",
+ pp->name, error);
+ return (error);
+ }
+ ahdr = (struct ddf_header *)abuf;
+
+ /* Check if this is an DDF RAID struct */
+ if (be32dec(&ahdr->Signature) == DDF_HEADER_SIGNATURE)
+ meta->bigendian = 1;
+ else if (le32dec(&ahdr->Signature) == DDF_HEADER_SIGNATURE)
+ meta->bigendian = 0;
+ else {
+ G_RAID_DEBUG(1, "DDF signature check failed on %s", pp->name);
+ error = EINVAL;
+ goto done;
+ }
+ if (ahdr->Header_Type != DDF_HEADER_ANCHOR) {
+ G_RAID_DEBUG(1, "DDF header type check failed on %s", pp->name);
+ error = EINVAL;
+ goto done;
+ }
+ meta->hdr = ahdr;
+ plba = GET64(meta, hdr->Primary_Header_LBA);
+ slba = GET64(meta, hdr->Secondary_Header_LBA);
+ val = GET32(meta, hdr->CRC);
+ SET32(meta, hdr->CRC, 0xffffffff);
+ meta->hdr = NULL;
+ if (crc32(ahdr, ss) != val) {
+ G_RAID_DEBUG(1, "DDF CRC mismatch on %s", pp->name);
+ error = EINVAL;
+ goto done;
+ }
+ if ((plba + 6) * ss >= pp->mediasize) {
+ G_RAID_DEBUG(1, "DDF primary header LBA is wrong on %s", pp->name);
+ error = EINVAL;
+ goto done;
+ }
+ if (slba != -1 && (slba + 6) * ss >= pp->mediasize) {
+ G_RAID_DEBUG(1, "DDF secondary header LBA is wrong on %s", pp->name);
+ error = EINVAL;
+ goto done;
+ }
+ lba = plba;
+
+doread:
+ error = 0;
+ ddf_meta_free(meta);
+
+ /* Read header block. */
+ buf = g_read_data(cp, lba * ss, ss, &error);
+ if (buf == NULL) {
+readerror:
+ G_RAID_DEBUG(1, "DDF %s metadata read error on %s (error=%d).",
+ (lba == plba) ? "primary" : "secondary", pp->name, error);
+ if (lba == plba && slba != -1) {
+ lba = slba;
+ goto doread;
+ }
+ G_RAID_DEBUG(1, "DDF metadata read error on %s.", pp->name);
+ goto done;
+ }
+ meta->hdr = malloc(ss, M_MD_DDF, M_WAITOK);
+ memcpy(meta->hdr, buf, ss);
+ g_free(buf);
+ hdr = meta->hdr;
+ val = GET32(meta, hdr->CRC);
+ SET32(meta, hdr->CRC, 0xffffffff);
+ if (hdr->Signature != ahdr->Signature ||
+ crc32(meta->hdr, ss) != val ||
+ memcmp(hdr->DDF_Header_GUID, ahdr->DDF_Header_GUID, 24) ||
+ GET64(meta, hdr->Primary_Header_LBA) != plba ||
+ GET64(meta, hdr->Secondary_Header_LBA) != slba) {
+hdrerror:
+ G_RAID_DEBUG(1, "DDF %s metadata check failed on %s",
+ (lba == plba) ? "primary" : "secondary", pp->name);
+ if (lba == plba && slba != -1) {
+ lba = slba;
+ goto doread;
+ }
+ G_RAID_DEBUG(1, "DDF metadata check failed on %s", pp->name);
+ error = EINVAL;
+ goto done;
+ }
+ if ((lba == plba && hdr->Header_Type != DDF_HEADER_PRIMARY) ||
+ (lba == slba && hdr->Header_Type != DDF_HEADER_SECONDARY))
+ goto hdrerror;
+ len = 1;
+ len = max(len, GET32(meta, hdr->cd_section) + GET32(meta, hdr->cd_length));
+ len = max(len, GET32(meta, hdr->pdr_section) + GET32(meta, hdr->pdr_length));
+ len = max(len, GET32(meta, hdr->vdr_section) + GET32(meta, hdr->vdr_length));
+ len = max(len, GET32(meta, hdr->cr_section) + GET32(meta, hdr->cr_length));
+ len = max(len, GET32(meta, hdr->pdd_section) + GET32(meta, hdr->pdd_length));
+ if ((val = GET32(meta, hdr->bbmlog_section)) != 0xffffffff)
+ len = max(len, val + GET32(meta, hdr->bbmlog_length));
+ if ((val = GET32(meta, hdr->Diagnostic_Space)) != 0xffffffff)
+ len = max(len, val + GET32(meta, hdr->Diagnostic_Space_Length));
+ if ((val = GET32(meta, hdr->Vendor_Specific_Logs)) != 0xffffffff)
+ len = max(len, val + GET32(meta, hdr->Vendor_Specific_Logs_Length));
+ if ((plba + len) * ss >= pp->mediasize)
+ goto hdrerror;
+ if (slba != -1 && (slba + len) * ss >= pp->mediasize)
+ goto hdrerror;
+ /* Workaround for Adaptec implementation. */
+ if (GET16(meta, hdr->Max_Primary_Element_Entries) == 0xffff) {
+ SET16(meta, hdr->Max_Primary_Element_Entries,
+ min(GET16(meta, hdr->Max_PD_Entries),
+ (GET16(meta, hdr->Configuration_Record_Length) * ss - 512) / 12));
+ }
+
+ /* Read controller data. */
+ buf = g_read_data(cp, (lba + GET32(meta, hdr->cd_section)) * ss,
+ GET32(meta, hdr->cd_length) * ss, &error);
+ if (buf == NULL)
+ goto readerror;
+ meta->cdr = malloc(GET32(meta, hdr->cd_length) * ss, M_MD_DDF, M_WAITOK);
+ memcpy(meta->cdr, buf, GET32(meta, hdr->cd_length) * ss);
+ g_free(buf);
+ if (GET32(meta, cdr->Signature) != DDF_CONTROLLER_DATA_SIGNATURE)
+ goto hdrerror;
+
+ /* Read physical disk records. */
+ buf = g_read_data(cp, (lba + GET32(meta, hdr->pdr_section)) * ss,
+ GET32(meta, hdr->pdr_length) * ss, &error);
+ if (buf == NULL)
+ goto readerror;
+ meta->pdr = malloc(GET32(meta, hdr->pdr_length) * ss, M_MD_DDF, M_WAITOK);
+ memcpy(meta->pdr, buf, GET32(meta, hdr->pdr_length) * ss);
+ g_free(buf);
+ if (GET32(meta, pdr->Signature) != DDF_PDR_SIGNATURE)
+ goto hdrerror;
+
+ /* Read virtual disk records. */
+ buf = g_read_data(cp, (lba + GET32(meta, hdr->vdr_section)) * ss,
+ GET32(meta, hdr->vdr_length) * ss, &error);
+ if (buf == NULL)
+ goto readerror;
+ meta->vdr = malloc(GET32(meta, hdr->vdr_length) * ss, M_MD_DDF, M_WAITOK);
+ memcpy(meta->vdr, buf, GET32(meta, hdr->vdr_length) * ss);
+ g_free(buf);
+ if (GET32(meta, vdr->Signature) != DDF_VD_RECORD_SIGNATURE)
+ goto hdrerror;
+
+ /* Read configuration records. */
+ buf = g_read_data(cp, (lba + GET32(meta, hdr->cr_section)) * ss,
+ GET32(meta, hdr->cr_length) * ss, &error);
+ if (buf == NULL)
+ goto readerror;
+ meta->cr = malloc(GET32(meta, hdr->cr_length) * ss, M_MD_DDF, M_WAITOK);
+ memcpy(meta->cr, buf, GET32(meta, hdr->cr_length) * ss);
+ g_free(buf);
+
+ /* Read physical disk data. */
+ buf = g_read_data(cp, (lba + GET32(meta, hdr->pdd_section)) * ss,
+ GET32(meta, hdr->pdd_length) * ss, &error);
+ if (buf == NULL)
+ goto readerror;
+ meta->pdd = malloc(GET32(meta, hdr->pdd_length) * ss, M_MD_DDF, M_WAITOK);
+ memcpy(meta->pdd, buf, GET32(meta, hdr->pdd_length) * ss);
+ g_free(buf);
+ if (GET32(meta, pdd->Signature) != DDF_PDD_SIGNATURE)
+ goto hdrerror;
+ i = ddf_meta_find_pd(meta, NULL, GET32(meta, pdd->PD_Reference));
+ if (i < 0)
+ goto hdrerror;
+
+ /* Read BBM Log. */
+ if (GET32(meta, hdr->bbmlog_section) != 0xffffffff &&
+ GET32(meta, hdr->bbmlog_length) != 0) {
+ buf = g_read_data(cp, (lba + GET32(meta, hdr->bbmlog_section)) * ss,
+ GET32(meta, hdr->bbmlog_length) * ss, &error);
+ if (buf == NULL)
+ goto readerror;
+ meta->bbm = malloc(GET32(meta, hdr->bbmlog_length) * ss, M_MD_DDF, M_WAITOK);
+ memcpy(meta->bbm, buf, GET32(meta, hdr->bbmlog_length) * ss);
+ g_free(buf);
+ if (GET32(meta, bbm->Signature) != DDF_BBML_SIGNATURE)
+ goto hdrerror;
+ }
+
+done:
+ g_free(abuf);
+ if (error != 0)
+ ddf_meta_free(meta);
+ return (error);
+}
+
+static int
+ddf_meta_write(struct g_consumer *cp, struct ddf_meta *meta)
+{
+ struct g_provider *pp;
+ struct ddf_vdc_record *vdc;
+ off_t alba, plba, slba, lba;
+ u_int ss, size;
+ int error, i, num;
+
+ pp = cp->provider;
+ ss = pp->sectorsize;
+ lba = alba = pp->mediasize / ss - 1;
+ plba = GET64(meta, hdr->Primary_Header_LBA);
+ slba = GET64(meta, hdr->Secondary_Header_LBA);
+
+next:
+ SET8(meta, hdr->Header_Type, (lba == alba) ? DDF_HEADER_ANCHOR :
+ (lba == plba) ? DDF_HEADER_PRIMARY : DDF_HEADER_SECONDARY);
+ SET32(meta, hdr->CRC, 0xffffffff);
+ SET32(meta, hdr->CRC, crc32(meta->hdr, ss));
+ error = g_write_data(cp, lba * ss, meta->hdr, ss);
+ if (error != 0) {
+err:
+ G_RAID_DEBUG(1, "Cannot write metadata to %s (error=%d).",
+ pp->name, error);
+ if (lba != alba)
+ goto done;
+ }
+ if (lba == alba) {
+ lba = plba;
+ goto next;
+ }
+
+ size = GET32(meta, hdr->cd_length) * ss;
+ SET32(meta, cdr->CRC, 0xffffffff);
+ SET32(meta, cdr->CRC, crc32(meta->cdr, size));
+ error = g_write_data(cp, (lba + GET32(meta, hdr->cd_section)) * ss,
+ meta->cdr, size);
+ if (error != 0)
+ goto err;
+
+ size = GET32(meta, hdr->pdr_length) * ss;
+ SET32(meta, pdr->CRC, 0xffffffff);
+ SET32(meta, pdr->CRC, crc32(meta->pdr, size));
+ error = g_write_data(cp, (lba + GET32(meta, hdr->pdr_section)) * ss,
+ meta->pdr, size);
+ if (error != 0)
+ goto err;
+
+ size = GET32(meta, hdr->vdr_length) * ss;
+ SET32(meta, vdr->CRC, 0xffffffff);
+ SET32(meta, vdr->CRC, crc32(meta->vdr, size));
+ error = g_write_data(cp, (lba + GET32(meta, hdr->vdr_section)) * ss,
+ meta->vdr, size);
+ if (error != 0)
+ goto err;
+
+ size = GET16(meta, hdr->Configuration_Record_Length) * ss;
+ num = GETCRNUM(meta);
+ for (i = 0; i < num; i++) {
+ vdc = GETVDCPTR(meta, i);
+ SET32D(meta, vdc->CRC, 0xffffffff);
+ SET32D(meta, vdc->CRC, crc32(vdc, size));
+ }
+ error = g_write_data(cp, (lba + GET32(meta, hdr->cr_section)) * ss,
+ meta->cr, size * num);
+ if (error != 0)
+ goto err;
+
+ size = GET32(meta, hdr->pdd_length) * ss;
+ SET32(meta, pdd->CRC, 0xffffffff);
+ SET32(meta, pdd->CRC, crc32(meta->pdd, size));
+ error = g_write_data(cp, (lba + GET32(meta, hdr->pdd_section)) * ss,
+ meta->pdd, size);
+ if (error != 0)
+ goto err;
+
+ if (GET32(meta, hdr->bbmlog_length) != 0) {
+ size = GET32(meta, hdr->bbmlog_length) * ss;
+ SET32(meta, bbm->CRC, 0xffffffff);
+ SET32(meta, bbm->CRC, crc32(meta->bbm, size));
+ error = g_write_data(cp,
+ (lba + GET32(meta, hdr->bbmlog_section)) * ss,
+ meta->bbm, size);
+ if (error != 0)
+ goto err;
+ }
+
+done:
+ if (lba == plba && slba != -1) {
+ lba = slba;
+ goto next;
+ }
+
+ return (error);
+}
+
+static int
+ddf_meta_erase(struct g_consumer *cp)
+{
+ struct g_provider *pp;
+ char *buf;
+ int error;
+
+ pp = cp->provider;
+ buf = malloc(pp->sectorsize, M_MD_DDF, M_WAITOK | M_ZERO);
+ error = g_write_data(cp, pp->mediasize - pp->sectorsize,
+ buf, pp->sectorsize);
+ if (error != 0) {
+ G_RAID_DEBUG(1, "Cannot erase metadata on %s (error=%d).",
+ pp->name, error);
+ }
+ free(buf, M_MD_DDF);
+ return (error);
+}
+
+static struct g_raid_volume *
+g_raid_md_ddf_get_volume(struct g_raid_softc *sc, uint8_t *GUID)
+{
+ struct g_raid_volume *vol;
+ struct g_raid_md_ddf_pervolume *pv;
+
+ TAILQ_FOREACH(vol, &sc->sc_volumes, v_next) {
+ pv = vol->v_md_data;
+ if (memcmp(pv->pv_meta.vde->VD_GUID, GUID, 24) == 0)
+ break;
+ }
+ return (vol);
+}
+
+static struct g_raid_disk *
+g_raid_md_ddf_get_disk(struct g_raid_softc *sc, uint8_t *GUID, uint32_t id)
+{
+ struct g_raid_disk *disk;
+ struct g_raid_md_ddf_perdisk *pd;
+ struct ddf_meta *meta;
+
+ TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
+ pd = (struct g_raid_md_ddf_perdisk *)disk->d_md_data;
+ meta = &pd->pd_meta;
+ if (GUID != NULL) {
+ if (memcmp(meta->pdd->PD_GUID, GUID, 24) == 0)
+ break;
+ } else {
+ if (GET32(meta, pdd->PD_Reference) == id)
+ break;
+ }
+ }
+ return (disk);
+}
+
+static int
+g_raid_md_ddf_purge_volumes(struct g_raid_softc *sc)
+{
+ struct g_raid_volume *vol, *tvol;
+ struct g_raid_md_ddf_pervolume *pv;
+ int i, res;
+
+ res = 0;
+ TAILQ_FOREACH_SAFE(vol, &sc->sc_volumes, v_next, tvol) {
+ pv = vol->v_md_data;
+ if (vol->v_stopping)
+ continue;
+ for (i = 0; i < vol->v_disks_count; i++) {
+ if (vol->v_subdisks[i].sd_state != G_RAID_SUBDISK_S_NONE)
+ break;
+ }
+ if (i >= vol->v_disks_count) {
+ g_raid_destroy_volume(vol);
+ res = 1;
+ }
+ }
+ return (res);
+}
+
+static int
+g_raid_md_ddf_purge_disks(struct g_raid_softc *sc)
+{
+#if 0
+ struct g_raid_disk *disk, *tdisk;
+ struct g_raid_volume *vol;
+ struct g_raid_md_ddf_perdisk *pd;
+ int i, j, res;
+
+ res = 0;
+ TAILQ_FOREACH_SAFE(disk, &sc->sc_disks, d_next, tdisk) {
+ if (disk->d_state == G_RAID_DISK_S_SPARE)
+ continue;
+ pd = (struct g_raid_md_ddf_perdisk *)disk->d_md_data;
+
+ /* Scan for deleted volumes. */
+ for (i = 0; i < pd->pd_subdisks; ) {
+ vol = g_raid_md_ddf_get_volume(sc,
+ pd->pd_meta[i]->volume_id);
+ if (vol != NULL && !vol->v_stopping) {
+ i++;
+ continue;
+ }
+ free(pd->pd_meta[i], M_MD_DDF);
+ for (j = i; j < pd->pd_subdisks - 1; j++)
+ pd->pd_meta[j] = pd->pd_meta[j + 1];
+ pd->pd_meta[DDF_MAX_SUBDISKS - 1] = NULL;
+ pd->pd_subdisks--;
+ pd->pd_updated = 1;
+ }
+
+ /* If there is no metadata left - erase and delete disk. */
+ if (pd->pd_subdisks == 0) {
+ ddf_meta_erase(disk->d_consumer);
+ g_raid_destroy_disk(disk);
+ res = 1;
+ }
+ }
+ return (res);
+#endif
+ return (0);
+}
+
+static int
+g_raid_md_ddf_supported(int level, int qual, int disks, int force)
+{
+
+ if (disks > DDF_MAX_DISKS_HARD)
+ return (0);
+ switch (level) {
+ case G_RAID_VOLUME_RL_RAID0:
+ if (qual != G_RAID_VOLUME_RLQ_NONE)
+ return (0);
+ if (disks < 1)
+ return (0);
+ if (!force && disks < 2)
+ return (0);
+ break;
+ case G_RAID_VOLUME_RL_RAID1:
+ if (disks < 1)
+ return (0);
+ if (qual == G_RAID_VOLUME_RLQ_R1SM) {
+ if (!force && disks != 2)
+ return (0);
+ } else if (qual == G_RAID_VOLUME_RLQ_R1MM) {
+ if (!force && disks != 3)
+ return (0);
+ } else
+ return (0);
+ break;
+ case G_RAID_VOLUME_RL_RAID3:
+ if (qual != G_RAID_VOLUME_RLQ_R3P0 &&
+ qual != G_RAID_VOLUME_RLQ_R3PN)
+ return (0);
+ if (disks < 3)
+ return (0);
+ break;
+ case G_RAID_VOLUME_RL_RAID4:
+ if (qual != G_RAID_VOLUME_RLQ_R4P0 &&
+ qual != G_RAID_VOLUME_RLQ_R4PN)
+ return (0);
+ if (disks < 3)
+ return (0);
+ break;
+ case G_RAID_VOLUME_RL_RAID5:
+ if (qual != G_RAID_VOLUME_RLQ_R5RA &&
+ qual != G_RAID_VOLUME_RLQ_R5RS &&
+ qual != G_RAID_VOLUME_RLQ_R5LA &&
+ qual != G_RAID_VOLUME_RLQ_R5LS)
+ return (0);
+ if (disks < 3)
+ return (0);
+ break;
+ case G_RAID_VOLUME_RL_RAID6:
+ if (qual != G_RAID_VOLUME_RLQ_R6RA &&
+ qual != G_RAID_VOLUME_RLQ_R6RS &&
+ qual != G_RAID_VOLUME_RLQ_R6LA &&
+ qual != G_RAID_VOLUME_RLQ_R6LS)
+ return (0);
+ if (disks < 4)
+ return (0);
+ break;
+ case G_RAID_VOLUME_RL_RAIDMDF:
+ if (qual != G_RAID_VOLUME_RLQ_RMDFRA &&
+ qual != G_RAID_VOLUME_RLQ_RMDFRS &&
+ qual != G_RAID_VOLUME_RLQ_RMDFLA &&
+ qual != G_RAID_VOLUME_RLQ_RMDFLS)
+ return (0);
+ if (disks < 4)
+ return (0);
+ break;
+ case G_RAID_VOLUME_RL_RAID1E:
+ if (qual != G_RAID_VOLUME_RLQ_R1EA &&
+ qual != G_RAID_VOLUME_RLQ_R1EO)
+ return (0);
+ if (disks < 3)
+ return (0);
+ break;
+ case G_RAID_VOLUME_RL_SINGLE:
+ if (qual != G_RAID_VOLUME_RLQ_NONE)
+ return (0);
+ if (disks != 1)
+ return (0);
+ break;
+ case G_RAID_VOLUME_RL_CONCAT:
+ if (qual != G_RAID_VOLUME_RLQ_NONE)
+ return (0);
+ if (disks < 2)
+ return (0);
+ break;
+ case G_RAID_VOLUME_RL_RAID5E:
+ if (qual != G_RAID_VOLUME_RLQ_R5ERA &&
+ qual != G_RAID_VOLUME_RLQ_R5ERS &&
+ qual != G_RAID_VOLUME_RLQ_R5ELA &&
+ qual != G_RAID_VOLUME_RLQ_R5ELS)
+ return (0);
+ if (disks < 4)
+ return (0);
+ break;
+ case G_RAID_VOLUME_RL_RAID5EE:
+ if (qual != G_RAID_VOLUME_RLQ_R5EERA &&
+ qual != G_RAID_VOLUME_RLQ_R5EERS &&
+ qual != G_RAID_VOLUME_RLQ_R5EELA &&
+ qual != G_RAID_VOLUME_RLQ_R5EELS)
+ return (0);
+ if (disks < 4)
+ return (0);
+ break;
+ case G_RAID_VOLUME_RL_RAID5R:
+ if (qual != G_RAID_VOLUME_RLQ_R5RRA &&
+ qual != G_RAID_VOLUME_RLQ_R5RRS &&
+ qual != G_RAID_VOLUME_RLQ_R5RLA &&
+ qual != G_RAID_VOLUME_RLQ_R5RLS)
+ return (0);
+ if (disks < 3)
+ return (0);
+ break;
+ default:
+ return (0);
+ }
+ return (1);
+}
+
+static int
+g_raid_md_ddf_start_disk(struct g_raid_disk *disk, struct g_raid_volume *vol)
+{
+ struct g_raid_softc *sc;
+ struct g_raid_subdisk *sd;
+ struct g_raid_md_ddf_perdisk *pd;
+ struct g_raid_md_ddf_pervolume *pv;
+ struct g_raid_md_ddf_object *mdi;
+ struct ddf_vol_meta *vmeta;
+ struct ddf_meta *pdmeta, *gmeta;
+ struct ddf_vdc_record *vdc1;
+ struct ddf_sa_record *sa;
+ off_t size, eoff = 0, esize = 0;
+ uint64_t *val2;
+ int disk_pos, md_disk_bvd = -1, md_disk_pos = -1, md_pde_pos;
+ int i, resurrection = 0;
+ uint32_t reference;
+
+ sc = disk->d_softc;
+ mdi = (struct g_raid_md_ddf_object *)sc->sc_md;
+ pd = (struct g_raid_md_ddf_perdisk *)disk->d_md_data;
+ pdmeta = &pd->pd_meta;
+ reference = GET32(&pd->pd_meta, pdd->PD_Reference);
+
+ pv = vol->v_md_data;
+ vmeta = &pv->pv_meta;
+ gmeta = &mdi->mdio_meta;
+
+ /* Find disk position in metadata by it's reference. */
+ disk_pos = ddf_meta_find_disk(vmeta, reference,
+ &md_disk_bvd, &md_disk_pos);
+ md_pde_pos = ddf_meta_find_pd(gmeta, NULL, reference);
+
+ if (disk_pos < 0) {
+ G_RAID_DEBUG1(1, sc,
+ "Disk %s is not a present part of the volume %s",
+ g_raid_get_diskname(disk), vol->v_name);
+
+ /* Failed stale disk is useless for us. */
+ if ((GET16(gmeta, pdr->entry[md_pde_pos].PD_State) & DDF_PDE_PFA) != 0) {
+ g_raid_change_disk_state(disk, G_RAID_DISK_S_STALE_FAILED);
+ return (0);
+ }
+
+ /* If disk has some metadata for this volume - erase. */
+ if ((vdc1 = ddf_meta_find_vdc(pdmeta, vmeta->vdc->VD_GUID)) != NULL)
+ SET32D(pdmeta, vdc1->Signature, 0xffffffff);
+
+ /* If we are in the start process, that's all for now. */
+ if (!pv->pv_started)
+ goto nofit;
+ /*
+ * If we have already started - try to get use of the disk.
+ * Try to replace OFFLINE disks first, then FAILED.
+ */
+ if (ddf_meta_count_vdc(&pd->pd_meta, NULL) >=
+ GET16(&pd->pd_meta, hdr->Max_Partitions)) {
+ G_RAID_DEBUG1(1, sc, "No free partitions on disk %s",
+ g_raid_get_diskname(disk));
+ goto nofit;
+ }
+ ddf_meta_unused_range(&pd->pd_meta, &eoff, &esize);
+ if (esize == 0) {
+ G_RAID_DEBUG1(1, sc, "No free space on disk %s",
+ g_raid_get_diskname(disk));
+ goto nofit;
+ }
+ eoff *= pd->pd_meta.sectorsize;
+ esize *= pd->pd_meta.sectorsize;
+ size = INT64_MAX;
+ for (i = 0; i < vol->v_disks_count; i++) {
+ sd = &vol->v_subdisks[i];
+ if (sd->sd_state != G_RAID_SUBDISK_S_NONE)
+ size = sd->sd_size;
+ if (sd->sd_state <= G_RAID_SUBDISK_S_FAILED &&
+ (disk_pos < 0 ||
+ vol->v_subdisks[i].sd_state < sd->sd_state))
+ disk_pos = i;
+ }
+ if (disk_pos >= 0 &&
+ vol->v_raid_level != G_RAID_VOLUME_RL_CONCAT &&
+ esize < size) {
+ G_RAID_DEBUG1(1, sc, "Disk %s free space "
+ "is too small (%ju < %ju)",
+ g_raid_get_diskname(disk), esize, size);
+ disk_pos = -1;
+ }
+ if (disk_pos >= 0) {
+ if (vol->v_raid_level != G_RAID_VOLUME_RL_CONCAT)
+ esize = size;
+ md_disk_bvd = disk_pos / GET16(vmeta, vdc->Primary_Element_Count); // XXX
+ md_disk_pos = disk_pos % GET16(vmeta, vdc->Primary_Element_Count); // XXX
+ } else {
+nofit:
+ if (disk->d_state == G_RAID_DISK_S_NONE)
+ g_raid_change_disk_state(disk,
+ G_RAID_DISK_S_STALE);
+ return (0);
+ }
+
+ /*
+ * If spare is committable, delete spare record.
+ * Othersize, mark it active and leave there.
+ */
+ sa = ddf_meta_find_sa(&pd->pd_meta, 0);
+ if (sa != NULL) {
+ if ((GET8D(&pd->pd_meta, sa->Spare_Type) &
+ DDF_SAR_TYPE_REVERTIBLE) == 0) {
+ SET32D(&pd->pd_meta, sa->Signature, 0xffffffff);
+ } else {
+ SET8D(&pd->pd_meta, sa->Spare_Type,
+ GET8D(&pd->pd_meta, sa->Spare_Type) |
+ DDF_SAR_TYPE_ACTIVE);
+ }
+ }
+
+ G_RAID_DEBUG1(1, sc, "Disk %s takes pos %d in the volume %s",
+ g_raid_get_diskname(disk), disk_pos, vol->v_name);
+ resurrection = 1;
+ }
+
+ sd = &vol->v_subdisks[disk_pos];
+
+ if (resurrection && sd->sd_disk != NULL) {
+ g_raid_change_disk_state(sd->sd_disk,
+ G_RAID_DISK_S_STALE_FAILED);
+ TAILQ_REMOVE(&sd->sd_disk->d_subdisks,
+ sd, sd_next);
+ }
+ vol->v_subdisks[disk_pos].sd_disk = disk;
+ TAILQ_INSERT_TAIL(&disk->d_subdisks, sd, sd_next);
+
+ /* Welcome the new disk. */
+ if (resurrection)
+ g_raid_change_disk_state(disk, G_RAID_DISK_S_ACTIVE);
+ else if (GET8(gmeta, pdr->entry[md_pde_pos].PD_State) & DDF_PDE_PFA)
+ g_raid_change_disk_state(disk, G_RAID_DISK_S_FAILED);
+ else
+ g_raid_change_disk_state(disk, G_RAID_DISK_S_ACTIVE);
+
+ if (resurrection) {
+ sd->sd_offset = eoff;
+ sd->sd_size = esize;
+ } else if (pdmeta->cr != NULL &&
+ (vdc1 = ddf_meta_find_vdc(pdmeta, vmeta->vdc->VD_GUID)) != NULL) {
+ val2 = (uint64_t *)&(vdc1->Physical_Disk_Sequence[GET16(vmeta, hdr->Max_Primary_Element_Entries)]);
+ sd->sd_offset = (off_t)GET64P(pdmeta, val2 + md_disk_pos) * 512;
+ sd->sd_size = (off_t)GET64D(pdmeta, vdc1->Block_Count) * 512;
+ }
+
+ if (resurrection) {
+ /* Stale disk, almost same as new. */
+ g_raid_change_subdisk_state(sd,
+ G_RAID_SUBDISK_S_NEW);
+ } else if (GET8(gmeta, pdr->entry[md_pde_pos].PD_State) & DDF_PDE_PFA) {
+ /* Failed disk. */
+ g_raid_change_subdisk_state(sd,
+ G_RAID_SUBDISK_S_FAILED);
+ } else if ((GET8(gmeta, pdr->entry[md_pde_pos].PD_State) &
+ (DDF_PDE_FAILED | DDF_PDE_REBUILD)) != 0) {
+ /* Rebuilding disk. */
+ g_raid_change_subdisk_state(sd,
+ G_RAID_SUBDISK_S_REBUILD);
+ sd->sd_rebuild_pos = 0;
+ } else if ((GET8(vmeta, vde->VD_State) & DDF_VDE_DIRTY) != 0 ||
+ (GET8(vmeta, vde->Init_State) & DDF_VDE_INIT_MASK) !=
+ DDF_VDE_INIT_FULL) {
+ /* Stale disk or dirty volume (unclean shutdown). */
+ g_raid_change_subdisk_state(sd,
+ G_RAID_SUBDISK_S_STALE);
+ } else {
+ /* Up to date disk. */
+ g_raid_change_subdisk_state(sd,
+ G_RAID_SUBDISK_S_ACTIVE);
+ }
+ g_raid_event_send(sd, G_RAID_SUBDISK_E_NEW,
+ G_RAID_EVENT_SUBDISK);
+
+ return (resurrection);
+}
+
+static void
+g_raid_md_ddf_refill(struct g_raid_softc *sc)
+{
+ struct g_raid_volume *vol;
+ struct g_raid_subdisk *sd;
+ struct g_raid_disk *disk;
+ struct g_raid_md_object *md;
+ struct g_raid_md_ddf_perdisk *pd;
+ struct g_raid_md_ddf_pervolume *pv;
+ int update, updated, i, bad;
+
+ md = sc->sc_md;
+restart:
+ updated = 0;
+ TAILQ_FOREACH(vol, &sc->sc_volumes, v_next) {
+ pv = vol->v_md_data;
+ if (!pv->pv_started || vol->v_stopping)
+ continue;
+
+ /* Search for subdisk that needs replacement. */
+ bad = 0;
+ for (i = 0; i < vol->v_disks_count; i++) {
+ sd = &vol->v_subdisks[i];
+ if (sd->sd_state == G_RAID_SUBDISK_S_NONE ||
+ sd->sd_state == G_RAID_SUBDISK_S_FAILED)
+ bad = 1;
+ }
+ if (!bad)
+ continue;
+
+ G_RAID_DEBUG1(1, sc, "Volume %s is not complete, "
+ "trying to refill.", vol->v_name);
+
+ TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
+ /* Skip failed. */
+ if (disk->d_state < G_RAID_DISK_S_SPARE)
+ continue;
+ /* Skip already used by this volume. */
+ for (i = 0; i < vol->v_disks_count; i++) {
+ sd = &vol->v_subdisks[i];
+ if (sd->sd_disk == disk)
+ break;
+ }
+ if (i < vol->v_disks_count)
+ continue;
+
+ /* Try to use disk if it has empty extents. */
+ pd = disk->d_md_data;
+ if (ddf_meta_count_vdc(&pd->pd_meta, NULL) <
+ GET16(&pd->pd_meta, hdr->Max_Partitions)) {
+ update = g_raid_md_ddf_start_disk(disk, vol);
+ } else
+ update = 0;
+ if (update) {
+ updated = 1;
+ g_raid_md_write_ddf(md, vol, NULL, disk);
+ break;
+ }
+ }
+ }
+ if (updated)
+ goto restart;
+}
+
+static void
+g_raid_md_ddf_start(struct g_raid_volume *vol)
+{
+ struct g_raid_softc *sc;
+ struct g_raid_subdisk *sd;
+ struct g_raid_disk *disk;
+ struct g_raid_md_object *md;
+ struct g_raid_md_ddf_perdisk *pd;
+ struct g_raid_md_ddf_pervolume *pv;
+ struct g_raid_md_ddf_object *mdi;
+ struct ddf_vol_meta *vmeta;
+ struct ddf_vdc_record *vdc;
+ uint64_t *val2;
+ int i, j, bvd;
+
+ sc = vol->v_softc;
+ md = sc->sc_md;
+ mdi = (struct g_raid_md_ddf_object *)md;
+ pv = vol->v_md_data;
+ vmeta = &pv->pv_meta;
+ vdc = vmeta->vdc;
+
+ vol->v_raid_level = GET8(vmeta, vdc->Primary_RAID_Level);
+ vol->v_raid_level_qualifier = GET8(vmeta, vdc->RLQ);
+ if (GET8(vmeta, vdc->Secondary_Element_Count) > 1 &&
+ vol->v_raid_level == G_RAID_VOLUME_RL_RAID1 &&
+ GET8(vmeta, vdc->Secondary_RAID_Level) == 0)
+ vol->v_raid_level = G_RAID_VOLUME_RL_RAID1E;
+ vol->v_sectorsize = GET16(vmeta, vdc->Block_Size);
+ if (vol->v_sectorsize == 0xffff)
+ vol->v_sectorsize = vmeta->sectorsize;
+ vol->v_strip_size = vol->v_sectorsize << GET8(vmeta, vdc->Stripe_Size);
+ vol->v_disks_count = GET16(vmeta, vdc->Primary_Element_Count) *
+ GET8(vmeta, vdc->Secondary_Element_Count);
+ vol->v_mdf_pdisks = GET8(vmeta, vdc->MDF_Parity_Disks);
+ vol->v_mdf_polynomial = GET16(vmeta, vdc->MDF_Parity_Generator_Polynomial);
+ vol->v_mdf_method = GET8(vmeta, vdc->MDF_Constant_Generation_Method);
+ if (GET8(vmeta, vdc->Rotate_Parity_count) > 31)
+ vol->v_rotate_parity = 1;
+ else
+ vol->v_rotate_parity = 1 << GET8(vmeta, vdc->Rotate_Parity_count);
+ vol->v_mediasize = GET64(vmeta, vdc->VD_Size) * vol->v_sectorsize;
+ for (i = 0, j = 0, bvd = 0; i < vol->v_disks_count; i++, j++) {
+ if (j == GET16(vmeta, vdc->Primary_Element_Count)) {
+ j = 0;
+ bvd++;
+ }
+ sd = &vol->v_subdisks[i];
+ if (vmeta->bvdc[bvd] == NULL) {
+ sd->sd_offset = 0;
+ sd->sd_size = GET64(vmeta, vdc->Block_Count) *
+ vol->v_sectorsize;
+ continue;
+ }
+ val2 = (uint64_t *)&(vmeta->bvdc[bvd]->Physical_Disk_Sequence[
+ GET16(vmeta, hdr->Max_Primary_Element_Entries)]);
+ sd->sd_offset = GET64P(vmeta, val2 + j) * vol->v_sectorsize;
+ sd->sd_size = GET64(vmeta, bvdc[bvd]->Block_Count) *
+ vol->v_sectorsize;
+ }
+ g_raid_start_volume(vol);
+
+ /* Make all disks found till the moment take their places. */
+ TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
+ pd = (struct g_raid_md_ddf_perdisk *)disk->d_md_data;
+ if (ddf_meta_find_vdc(&pd->pd_meta, vmeta->vdc->VD_GUID) != NULL)
+ g_raid_md_ddf_start_disk(disk, vol);
+ }
+
+ pv->pv_started = 1;
+ mdi->mdio_starting--;
+ callout_stop(&pv->pv_start_co);
+ G_RAID_DEBUG1(0, sc, "Volume started.");
+ g_raid_md_write_ddf(md, vol, NULL, NULL);
+
+ /* Pickup any STALE/SPARE disks to refill array if needed. */
+ g_raid_md_ddf_refill(sc);
+
+ g_raid_event_send(vol, G_RAID_VOLUME_E_START, G_RAID_EVENT_VOLUME);
+}
+
+static void
+g_raid_ddf_go(void *arg)
+{
+ struct g_raid_volume *vol;
+ struct g_raid_softc *sc;
+ struct g_raid_md_ddf_pervolume *pv;
+
+ vol = arg;
+ pv = vol->v_md_data;
+ sc = vol->v_softc;
+ if (!pv->pv_started) {
+ G_RAID_DEBUG1(0, sc, "Force volume start due to timeout.");
+ g_raid_event_send(vol, G_RAID_VOLUME_E_STARTMD,
+ G_RAID_EVENT_VOLUME);
+ }
+}
+
+static void
+g_raid_md_ddf_new_disk(struct g_raid_disk *disk)
+{
+ struct g_raid_softc *sc;
+ struct g_raid_md_object *md;
+ struct g_raid_md_ddf_perdisk *pd;
+ struct g_raid_md_ddf_pervolume *pv;
+ struct g_raid_md_ddf_object *mdi;
+ struct g_raid_volume *vol;
+ struct ddf_meta *pdmeta;
+ struct ddf_vol_meta *vmeta;
+ struct ddf_vdc_record *vdc;
+ struct ddf_vd_entry *vde;
+ int i, j, k, num, have, need, cnt, spare;
+ uint32_t val;
+ char buf[17];
+
+ sc = disk->d_softc;
+ md = sc->sc_md;
+ mdi = (struct g_raid_md_ddf_object *)md;
+ pd = (struct g_raid_md_ddf_perdisk *)disk->d_md_data;
+ pdmeta = &pd->pd_meta;
+ spare = -1;
+
+ if (mdi->mdio_meta.hdr == NULL)
+ ddf_meta_copy(&mdi->mdio_meta, pdmeta);
+ else
+ ddf_meta_update(&mdi->mdio_meta, pdmeta);
+
+ num = GETCRNUM(pdmeta);
+ for (j = 0; j < num; j++) {
+ vdc = GETVDCPTR(pdmeta, j);
+ val = GET32D(pdmeta, vdc->Signature);
+
+ if (val == DDF_SA_SIGNATURE && spare == -1)
+ spare = 1;
+
+ if (val != DDF_VDCR_SIGNATURE)
+ continue;
+ spare = 0;
+ k = ddf_meta_find_vd(pdmeta, vdc->VD_GUID);
+ if (k < 0)
+ continue;
+ vde = &pdmeta->vdr->entry[k];
+
+ /* Look for volume with matching ID. */
+ vol = g_raid_md_ddf_get_volume(sc, vdc->VD_GUID);
+ if (vol == NULL) {
+ ddf_meta_get_name(pdmeta, k, buf);
+ vol = g_raid_create_volume(sc, buf,
+ GET16D(pdmeta, vde->VD_Number));
+ pv = malloc(sizeof(*pv), M_MD_DDF, M_WAITOK | M_ZERO);
+ vol->v_md_data = pv;
+ callout_init(&pv->pv_start_co, 1);
+ callout_reset(&pv->pv_start_co,
+ g_raid_start_timeout * hz,
+ g_raid_ddf_go, vol);
+ mdi->mdio_starting++;
+ } else
+ pv = vol->v_md_data;
+
+ /* If we haven't started yet - check metadata freshness. */
+ vmeta = &pv->pv_meta;
+ ddf_vol_meta_update(vmeta, pdmeta, vdc->VD_GUID, pv->pv_started);
+ }
+
+ if (spare == 1) {
+ g_raid_change_disk_state(disk, G_RAID_DISK_S_SPARE);
+ g_raid_md_ddf_refill(sc);
+ }
+
+ TAILQ_FOREACH(vol, &sc->sc_volumes, v_next) {
+ pv = vol->v_md_data;
+ vmeta = &pv->pv_meta;
+
+ if (ddf_meta_find_vdc(pdmeta, vmeta->vdc->VD_GUID) == NULL)
+ continue;
+
+ if (pv->pv_started) {
+ if (g_raid_md_ddf_start_disk(disk, vol))
+ g_raid_md_write_ddf(md, vol, NULL, NULL);
+ continue;
+ }
+
+ /* If we collected all needed disks - start array. */
+ need = 0;
+ have = 0;
+ for (k = 0; k < GET8(vmeta, vdc->Secondary_Element_Count); k++) {
+ if (vmeta->bvdc[k] == NULL) {
+ need += GET16(vmeta, vdc->Primary_Element_Count);
+ continue;
+ }
+ cnt = GET16(vmeta, bvdc[k]->Primary_Element_Count);
+ need += cnt;
+ for (i = 0; i < cnt; i++) {
+ val = GET32(vmeta, bvdc[k]->Physical_Disk_Sequence[i]);
+ if (g_raid_md_ddf_get_disk(sc, NULL, val) != NULL)
+ have++;
+ }
+ }
+ G_RAID_DEBUG1(1, sc, "Volume %s now has %d of %d disks",
+ vol->v_name, have, need);
+ if (have == need)
+ g_raid_md_ddf_start(vol);
+ }
+}
+
+static int
+g_raid_md_create_req_ddf(struct g_raid_md_object *md, struct g_class *mp,
+ struct gctl_req *req, struct g_geom **gp)
+{
+ struct g_geom *geom;
+ struct g_raid_softc *sc;
+ struct g_raid_md_ddf_object *mdi, *mdi1;
+ char name[16];
+ const char *fmtopt;
+ int be = 1;
+
+ mdi = (struct g_raid_md_ddf_object *)md;
+ fmtopt = gctl_get_asciiparam(req, "fmtopt");
+ if (fmtopt == NULL || strcasecmp(fmtopt, "BE") == 0)
+ be = 1;
+ else if (strcasecmp(fmtopt, "LE") == 0)
+ be = 0;
+ else {
+ gctl_error(req, "Incorrect fmtopt argument.");
+ return (G_RAID_MD_TASTE_FAIL);
+ }
+
+ /* Search for existing node. */
+ LIST_FOREACH(geom, &mp->geom, geom) {
+ sc = geom->softc;
+ if (sc == NULL)
+ continue;
+ if (sc->sc_stopping != 0)
+ continue;
+ if (sc->sc_md->mdo_class != md->mdo_class)
+ continue;
+ mdi1 = (struct g_raid_md_ddf_object *)sc->sc_md;
+ if (mdi1->mdio_bigendian != be)
+ continue;
+ break;
+ }
+ if (geom != NULL) {
+ *gp = geom;
+ return (G_RAID_MD_TASTE_EXISTING);
+ }
+
+ /* Create new one if not found. */
+ mdi->mdio_bigendian = be;
+ snprintf(name, sizeof(name), "DDF%s", be ? "" : "-LE");
+ sc = g_raid_create_node(mp, name, md);
+ if (sc == NULL)
+ return (G_RAID_MD_TASTE_FAIL);
+ md->mdo_softc = sc;
+ *gp = sc->sc_geom;
+ return (G_RAID_MD_TASTE_NEW);
+}
+
+static int
+g_raid_md_taste_ddf(struct g_raid_md_object *md, struct g_class *mp,
+ struct g_consumer *cp, struct g_geom **gp)
+{
+ struct g_consumer *rcp;
+ struct g_provider *pp;
+ struct g_raid_softc *sc;
+ struct g_raid_disk *disk;
+ struct ddf_meta meta;
+ struct g_raid_md_ddf_perdisk *pd;
+ struct g_raid_md_ddf_object *mdi;
+ struct g_geom *geom;
+ int error, result, len, be;
+ char name[16];
+
+ G_RAID_DEBUG(1, "Tasting DDF on %s", cp->provider->name);
+ mdi = (struct g_raid_md_ddf_object *)md;
+ pp = cp->provider;
+
+ /* Read metadata from device. */
+ if (g_access(cp, 1, 0, 0) != 0)
+ return (G_RAID_MD_TASTE_FAIL);
+ g_topology_unlock();
+ bzero(&meta, sizeof(meta));
+ error = ddf_meta_read(cp, &meta);
+ g_topology_lock();
+ g_access(cp, -1, 0, 0);
+ if (error != 0)
+ return (G_RAID_MD_TASTE_FAIL);
+ be = meta.bigendian;
+
+ /* Metadata valid. Print it. */
+ g_raid_md_ddf_print(&meta);
+
+ /* Search for matching node. */
+ sc = NULL;
+ LIST_FOREACH(geom, &mp->geom, geom) {
+ sc = geom->softc;
+ if (sc == NULL)
+ continue;
+ if (sc->sc_stopping != 0)
+ continue;
+ if (sc->sc_md->mdo_class != md->mdo_class)
+ continue;
+ mdi = (struct g_raid_md_ddf_object *)sc->sc_md;
+ if (mdi->mdio_bigendian != be)
+ continue;
+ break;
+ }
+
+ /* Found matching node. */
+ if (geom != NULL) {
+ G_RAID_DEBUG(1, "Found matching array %s", sc->sc_name);
+ result = G_RAID_MD_TASTE_EXISTING;
+
+ } else { /* Not found matching node -- create one. */
+ result = G_RAID_MD_TASTE_NEW;
+ mdi->mdio_bigendian = be;
+ snprintf(name, sizeof(name), "DDF%s", be ? "" : "-LE");
+ sc = g_raid_create_node(mp, name, md);
+ md->mdo_softc = sc;
+ geom = sc->sc_geom;
+ }
+
+ rcp = g_new_consumer(geom);
+ g_attach(rcp, pp);
+ if (g_access(rcp, 1, 1, 1) != 0)
+ ; //goto fail1;
+
+ g_topology_unlock();
+ sx_xlock(&sc->sc_lock);
+
+ pd = malloc(sizeof(*pd), M_MD_DDF, M_WAITOK | M_ZERO);
+ pd->pd_meta = meta;
+ disk = g_raid_create_disk(sc);
+ disk->d_md_data = (void *)pd;
+ disk->d_consumer = rcp;
+ rcp->private = disk;
+
+ /* Read kernel dumping information. */
+ disk->d_kd.offset = 0;
+ disk->d_kd.length = OFF_MAX;
+ len = sizeof(disk->d_kd);
+ error = g_io_getattr("GEOM::kerneldump", rcp, &len, &disk->d_kd);
+ if (disk->d_kd.di.dumper == NULL)
+ G_RAID_DEBUG1(2, sc, "Dumping not supported by %s: %d.",
+ rcp->provider->name, error);
+
+ g_raid_md_ddf_new_disk(disk);
+
+ sx_xunlock(&sc->sc_lock);
+ g_topology_lock();
+ *gp = geom;
+ return (result);
+}
+
+static int
+g_raid_md_event_ddf(struct g_raid_md_object *md,
+ struct g_raid_disk *disk, u_int event)
+{
+ struct g_raid_softc *sc;
+
+ sc = md->mdo_softc;
+ if (disk == NULL)
+ return (-1);
+ switch (event) {
+ case G_RAID_DISK_E_DISCONNECTED:
+ /* Delete disk. */
+ g_raid_change_disk_state(disk, G_RAID_DISK_S_NONE);
+ g_raid_destroy_disk(disk);
+ g_raid_md_ddf_purge_volumes(sc);
+
+ /* Write updated metadata to all disks. */
+ g_raid_md_write_ddf(md, NULL, NULL, NULL);
+
+ /* Check if anything left. */
+ if (g_raid_ndisks(sc, -1) == 0)
+ g_raid_destroy_node(sc, 0);
+ else
+ g_raid_md_ddf_refill(sc);
+ return (0);
+ }
+ return (-2);
+}
+
+static int
+g_raid_md_volume_event_ddf(struct g_raid_md_object *md,
+ struct g_raid_volume *vol, u_int event)
+{
+ struct g_raid_md_ddf_pervolume *pv;
+
+ pv = (struct g_raid_md_ddf_pervolume *)vol->v_md_data;
+ switch (event) {
+ case G_RAID_VOLUME_E_STARTMD:
+ if (!pv->pv_started)
+ g_raid_md_ddf_start(vol);
+ return (0);
+ }
+ return (-2);
+}
+
+static int
+g_raid_md_ctl_ddf(struct g_raid_md_object *md,
+ struct gctl_req *req)
+{
+ struct g_raid_softc *sc;
+ struct g_raid_volume *vol, *vol1;
+ struct g_raid_subdisk *sd;
+ struct g_raid_disk *disk, *disks[DDF_MAX_DISKS_HARD];
+ struct g_raid_md_ddf_perdisk *pd;
+ struct g_raid_md_ddf_pervolume *pv;
+ struct g_raid_md_ddf_object *mdi;
+ struct ddf_sa_record *sa;
+ struct g_consumer *cp;
+ struct g_provider *pp;
+ char arg[16];
+ const char *verb, *volname, *levelname, *diskname;
+ char *tmp;
+ int *nargs, *force;
+ off_t size, sectorsize, strip, offs[DDF_MAX_DISKS_HARD], esize;
+ intmax_t *sizearg, *striparg;
+ int i, numdisks, len, level, qual;
+ int error;
+
+ sc = md->mdo_softc;
+ mdi = (struct g_raid_md_ddf_object *)md;
+ verb = gctl_get_param(req, "verb", NULL);
+ nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
+ error = 0;
+
+ if (strcmp(verb, "label") == 0) {
+
+ if (*nargs < 4) {
+ gctl_error(req, "Invalid number of arguments.");
+ return (-1);
+ }
+ volname = gctl_get_asciiparam(req, "arg1");
+ if (volname == NULL) {
+ gctl_error(req, "No volume name.");
+ return (-2);
+ }
+ levelname = gctl_get_asciiparam(req, "arg2");
+ if (levelname == NULL) {
+ gctl_error(req, "No RAID level.");
+ return (-3);
+ }
+ if (g_raid_volume_str2level(levelname, &level, &qual)) {
+ gctl_error(req, "Unknown RAID level '%s'.", levelname);
+ return (-4);
+ }
+ numdisks = *nargs - 3;
+ force = gctl_get_paraml(req, "force", sizeof(*force));
+ if (!g_raid_md_ddf_supported(level, qual, numdisks,
+ force ? *force : 0)) {
+ gctl_error(req, "Unsupported RAID level "
+ "(0x%02x/0x%02x), or number of disks (%d).",
+ level, qual, numdisks);
+ return (-5);
+ }
+
+ /* Search for disks, connect them and probe. */
+ size = INT64_MAX;
+ sectorsize = 0;
+ bzero(disks, sizeof(disks));
+ bzero(offs, sizeof(offs));
+ for (i = 0; i < numdisks; i++) {
+ snprintf(arg, sizeof(arg), "arg%d", i + 3);
+ diskname = gctl_get_asciiparam(req, arg);
+ if (diskname == NULL) {
+ gctl_error(req, "No disk name (%s).", arg);
+ error = -6;
+ break;
+ }
+ if (strcmp(diskname, "NONE") == 0)
+ continue;
+
+ TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
+ if (disk->d_consumer != NULL &&
+ disk->d_consumer->provider != NULL &&
+ strcmp(disk->d_consumer->provider->name,
+ diskname) == 0)
+ break;
+ }
+ if (disk != NULL) {
+ if (disk->d_state != G_RAID_DISK_S_ACTIVE) {
+ gctl_error(req, "Disk '%s' is in a "
+ "wrong state (%s).", diskname,
+ g_raid_disk_state2str(disk->d_state));
+ error = -7;
+ break;
+ }
+ pd = disk->d_md_data;
+ if (ddf_meta_count_vdc(&pd->pd_meta, NULL) >=
+ GET16(&pd->pd_meta, hdr->Max_Partitions)) {
+ gctl_error(req, "No free partitions "
+ "on disk '%s'.",
+ diskname);
+ error = -7;
+ break;
+ }
+ pp = disk->d_consumer->provider;
+ disks[i] = disk;
+ ddf_meta_unused_range(&pd->pd_meta,
+ &offs[i], &esize);
+ offs[i] *= pp->sectorsize;
+ size = MIN(size, (off_t)esize * pp->sectorsize);
+ sectorsize = MAX(sectorsize, pp->sectorsize);
+ continue;
+ }
+
+ g_topology_lock();
+ cp = g_raid_open_consumer(sc, diskname);
+ if (cp == NULL) {
+ gctl_error(req, "Can't open disk '%s'.",
+ diskname);
+ g_topology_unlock();
+ error = -8;
+ break;
+ }
+ pp = cp->provider;
+ pd = malloc(sizeof(*pd), M_MD_DDF, M_WAITOK | M_ZERO);
+ disk = g_raid_create_disk(sc);
+ disk->d_md_data = (void *)pd;
+ disk->d_consumer = cp;
+ disks[i] = disk;
+ cp->private = disk;
+ ddf_meta_create(disk, &mdi->mdio_meta);
+ if (mdi->mdio_meta.hdr == NULL)
+ ddf_meta_copy(&mdi->mdio_meta, &pd->pd_meta);
+ else
+ ddf_meta_update(&mdi->mdio_meta, &pd->pd_meta);
+ g_topology_unlock();
+
+ /* Read kernel dumping information. */
+ disk->d_kd.offset = 0;
+ disk->d_kd.length = OFF_MAX;
+ len = sizeof(disk->d_kd);
+ g_io_getattr("GEOM::kerneldump", cp, &len, &disk->d_kd);
+ if (disk->d_kd.di.dumper == NULL)
+ G_RAID_DEBUG1(2, sc,
+ "Dumping not supported by %s.",
+ cp->provider->name);
+
+ /* Reserve some space for metadata. */
+ size = MIN(size, GET64(&pd->pd_meta,
+ pdr->entry[0].Configured_Size) * pp->sectorsize);
+ sectorsize = MAX(sectorsize, pp->sectorsize);
+ }
+ if (error != 0) {
+ for (i = 0; i < numdisks; i++) {
+ if (disks[i] != NULL &&
+ disks[i]->d_state == G_RAID_DISK_S_NONE)
+ g_raid_destroy_disk(disks[i]);
+ }
+ return (error);
+ }
+
+ if (sectorsize <= 0) {
+ gctl_error(req, "Can't get sector size.");
+ return (-8);
+ }
+
+ /* Handle size argument. */
+ len = sizeof(*sizearg);
+ sizearg = gctl_get_param(req, "size", &len);
+ if (sizearg != NULL && len == sizeof(*sizearg) &&
+ *sizearg > 0) {
+ if (*sizearg > size) {
+ gctl_error(req, "Size too big %lld > %lld.",
+ (long long)*sizearg, (long long)size);
+ return (-9);
+ }
+ size = *sizearg;
+ }
+
+ /* Handle strip argument. */
+ strip = 131072;
+ len = sizeof(*striparg);
+ striparg = gctl_get_param(req, "strip", &len);
+ if (striparg != NULL && len == sizeof(*striparg) &&
+ *striparg > 0) {
+ if (*striparg < sectorsize) {
+ gctl_error(req, "Strip size too small.");
+ return (-10);
+ }
+ if (*striparg % sectorsize != 0) {
+ gctl_error(req, "Incorrect strip size.");
+ return (-11);
+ }
+ strip = *striparg;
+ }
+
+ /* Round size down to strip or sector. */
+ if (level == G_RAID_VOLUME_RL_RAID1 ||
+ level == G_RAID_VOLUME_RL_RAID3 ||
+ level == G_RAID_VOLUME_RL_SINGLE ||
+ level == G_RAID_VOLUME_RL_CONCAT)
+ size -= (size % sectorsize);
+ else if (level == G_RAID_VOLUME_RL_RAID1E &&
+ (numdisks & 1) != 0)
+ size -= (size % (2 * strip));
+ else
+ size -= (size % strip);
+ if (size <= 0) {
+ gctl_error(req, "Size too small.");
+ return (-13);
+ }
+
+ /* We have all we need, create things: volume, ... */
+ pv = malloc(sizeof(*pv), M_MD_DDF, M_WAITOK | M_ZERO);
+ ddf_vol_meta_create(&pv->pv_meta, &mdi->mdio_meta);
+ pv->pv_started = 1;
+ vol = g_raid_create_volume(sc, volname, -1);
+ vol->v_md_data = pv;
+ vol->v_raid_level = level;
+ vol->v_raid_level_qualifier = qual;
+ vol->v_strip_size = strip;
+ vol->v_disks_count = numdisks;
+ if (level == G_RAID_VOLUME_RL_RAID0 ||
+ level == G_RAID_VOLUME_RL_CONCAT ||
+ level == G_RAID_VOLUME_RL_SINGLE)
+ vol->v_mediasize = size * numdisks;
+ else if (level == G_RAID_VOLUME_RL_RAID1)
+ vol->v_mediasize = size;
+ else if (level == G_RAID_VOLUME_RL_RAID3 ||
+ level == G_RAID_VOLUME_RL_RAID4 ||
+ level == G_RAID_VOLUME_RL_RAID5)
+ vol->v_mediasize = size * (numdisks - 1);
+ else if (level == G_RAID_VOLUME_RL_RAID5R) {
+ vol->v_mediasize = size * (numdisks - 1);
+ vol->v_rotate_parity = 1024;
+ } else if (level == G_RAID_VOLUME_RL_RAID6 ||
+ level == G_RAID_VOLUME_RL_RAID5E ||
+ level == G_RAID_VOLUME_RL_RAID5EE)
+ vol->v_mediasize = size * (numdisks - 2);
+ else if (level == G_RAID_VOLUME_RL_RAIDMDF) {
+ if (numdisks < 5)
+ vol->v_mdf_pdisks = 2;
+ else
+ vol->v_mdf_pdisks = 3;
+ vol->v_mdf_polynomial = 0x11d;
+ vol->v_mdf_method = 0x00;
+ vol->v_mediasize = size * (numdisks - vol->v_mdf_pdisks);
+ } else { /* RAID1E */
+ vol->v_mediasize = ((size * numdisks) / strip / 2) *
+ strip;
+ }
+ vol->v_sectorsize = sectorsize;
+ g_raid_start_volume(vol);
+
+ /* , and subdisks. */
+ for (i = 0; i < numdisks; i++) {
+ disk = disks[i];
+ sd = &vol->v_subdisks[i];
+ sd->sd_disk = disk;
+ sd->sd_offset = offs[i];
+ sd->sd_size = size;
+ if (disk == NULL)
+ continue;
+ TAILQ_INSERT_TAIL(&disk->d_subdisks, sd, sd_next);
+ g_raid_change_disk_state(disk,
+ G_RAID_DISK_S_ACTIVE);
+ g_raid_change_subdisk_state(sd,
+ G_RAID_SUBDISK_S_ACTIVE);
+ g_raid_event_send(sd, G_RAID_SUBDISK_E_NEW,
+ G_RAID_EVENT_SUBDISK);
+ }
+
+ /* Write metadata based on created entities. */
+ G_RAID_DEBUG1(0, sc, "Array started.");
+ g_raid_md_write_ddf(md, vol, NULL, NULL);
+
+ /* Pickup any STALE/SPARE disks to refill array if needed. */
+ g_raid_md_ddf_refill(sc);
+
+ g_raid_event_send(vol, G_RAID_VOLUME_E_START,
+ G_RAID_EVENT_VOLUME);
+ return (0);
+ }
+ if (strcmp(verb, "add") == 0) {
+
+ gctl_error(req, "`add` command is not applicable, "
+ "use `label` instead.");
+ return (-99);
+ }
+ if (strcmp(verb, "delete") == 0) {
+
+ /* Full node destruction. */
+ if (*nargs == 1) {
+ /* Check if some volume is still open. */
+ force = gctl_get_paraml(req, "force", sizeof(*force));
+ if (force != NULL && *force == 0 &&
+ g_raid_nopens(sc) != 0) {
+ gctl_error(req, "Some volume is still open.");
+ return (-4);
+ }
+
+ TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
+ if (disk->d_consumer)
+ ddf_meta_erase(disk->d_consumer);
+ }
+ g_raid_destroy_node(sc, 0);
+ return (0);
+ }
+
+ /* Destroy specified volume. If it was last - all node. */
+ if (*nargs != 2) {
+ gctl_error(req, "Invalid number of arguments.");
+ return (-1);
+ }
+ volname = gctl_get_asciiparam(req, "arg1");
+ if (volname == NULL) {
+ gctl_error(req, "No volume name.");
+ return (-2);
+ }
+
+ /* Search for volume. */
+ TAILQ_FOREACH(vol, &sc->sc_volumes, v_next) {
+ if (strcmp(vol->v_name, volname) == 0)
+ break;
+ }
+ if (vol == NULL) {
+ i = strtol(volname, &tmp, 10);
+ if (verb != volname && tmp[0] == 0) {
+ TAILQ_FOREACH(vol, &sc->sc_volumes, v_next) {
+ if (vol->v_global_id == i)
+ break;
+ }
+ }
+ }
+ if (vol == NULL) {
+ gctl_error(req, "Volume '%s' not found.", volname);
+ return (-3);
+ }
+
+ /* Check if volume is still open. */
+ force = gctl_get_paraml(req, "force", sizeof(*force));
+ if (force != NULL && *force == 0 &&
+ vol->v_provider_open != 0) {
+ gctl_error(req, "Volume is still open.");
+ return (-4);
+ }
+
+ /* Destroy volume and potentially node. */
+ i = 0;
+ TAILQ_FOREACH(vol1, &sc->sc_volumes, v_next)
+ i++;
+ if (i >= 2) {
+ g_raid_destroy_volume(vol);
+ g_raid_md_ddf_purge_disks(sc);
+ g_raid_md_write_ddf(md, NULL, NULL, NULL);
+ } else {
+ TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
+ if (disk->d_consumer)
+ ddf_meta_erase(disk->d_consumer);
+ }
+ g_raid_destroy_node(sc, 0);
+ }
+ return (0);
+ }
+ if (strcmp(verb, "remove") == 0 ||
+ strcmp(verb, "fail") == 0) {
+ if (*nargs < 2) {
+ gctl_error(req, "Invalid number of arguments.");
+ return (-1);
+ }
+ for (i = 1; i < *nargs; i++) {
+ snprintf(arg, sizeof(arg), "arg%d", i);
+ diskname = gctl_get_asciiparam(req, arg);
+ if (diskname == NULL) {
+ gctl_error(req, "No disk name (%s).", arg);
+ error = -2;
+ break;
+ }
+ if (strncmp(diskname, "/dev/", 5) == 0)
+ diskname += 5;
+
+ TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
+ if (disk->d_consumer != NULL &&
+ disk->d_consumer->provider != NULL &&
+ strcmp(disk->d_consumer->provider->name,
+ diskname) == 0)
+ break;
+ }
+ if (disk == NULL) {
+ gctl_error(req, "Disk '%s' not found.",
+ diskname);
+ error = -3;
+ break;
+ }
+
+ if (strcmp(verb, "fail") == 0) {
+ g_raid_md_fail_disk_ddf(md, NULL, disk);
+ continue;
+ }
+
+ /* Erase metadata on deleting disk and destroy it. */
+ ddf_meta_erase(disk->d_consumer);
+ g_raid_destroy_disk(disk);
+ }
+ g_raid_md_ddf_purge_volumes(sc);
+
+ /* Write updated metadata to remaining disks. */
+ g_raid_md_write_ddf(md, NULL, NULL, NULL);
+
+ /* Check if anything left. */
+ if (g_raid_ndisks(sc, -1) == 0)
+ g_raid_destroy_node(sc, 0);
+ else
+ g_raid_md_ddf_refill(sc);
+ return (error);
+ }
+ if (strcmp(verb, "insert") == 0) {
+ if (*nargs < 2) {
+ gctl_error(req, "Invalid number of arguments.");
+ return (-1);
+ }
+ for (i = 1; i < *nargs; i++) {
+ /* Get disk name. */
+ snprintf(arg, sizeof(arg), "arg%d", i);
+ diskname = gctl_get_asciiparam(req, arg);
+ if (diskname == NULL) {
+ gctl_error(req, "No disk name (%s).", arg);
+ error = -3;
+ break;
+ }
+
+ /* Try to find provider with specified name. */
+ g_topology_lock();
+ cp = g_raid_open_consumer(sc, diskname);
+ if (cp == NULL) {
+ gctl_error(req, "Can't open disk '%s'.",
+ diskname);
+ g_topology_unlock();
+ error = -4;
+ break;
+ }
+ pp = cp->provider;
+ g_topology_unlock();
+
+ pd = malloc(sizeof(*pd), M_MD_DDF, M_WAITOK | M_ZERO);
+
+ disk = g_raid_create_disk(sc);
+ disk->d_consumer = cp;
+ disk->d_md_data = (void *)pd;
+ cp->private = disk;
+
+ /* Read kernel dumping information. */
+ disk->d_kd.offset = 0;
+ disk->d_kd.length = OFF_MAX;
+ len = sizeof(disk->d_kd);
+ g_io_getattr("GEOM::kerneldump", cp, &len, &disk->d_kd);
+ if (disk->d_kd.di.dumper == NULL)
+ G_RAID_DEBUG1(2, sc,
+ "Dumping not supported by %s.",
+ cp->provider->name);
+
+ /* Welcome the "new" disk. */
+ g_raid_change_disk_state(disk, G_RAID_DISK_S_SPARE);
+ ddf_meta_create(disk, &mdi->mdio_meta);
+ sa = ddf_meta_find_sa(&pd->pd_meta, 1);
+ if (sa != NULL) {
+ SET32D(&pd->pd_meta, sa->Signature,
+ DDF_SA_SIGNATURE);
+ SET8D(&pd->pd_meta, sa->Spare_Type, 0);
+ SET16D(&pd->pd_meta, sa->Populated_SAEs, 0);
+ SET16D(&pd->pd_meta, sa->MAX_SAE_Supported,
+ (GET16(&pd->pd_meta, hdr->Configuration_Record_Length) *
+ pd->pd_meta.sectorsize -
+ sizeof(struct ddf_sa_record)) /
+ sizeof(struct ddf_sa_entry));
+ }
+ if (mdi->mdio_meta.hdr == NULL)
+ ddf_meta_copy(&mdi->mdio_meta, &pd->pd_meta);
+ else
+ ddf_meta_update(&mdi->mdio_meta, &pd->pd_meta);
+ g_raid_md_write_ddf(md, NULL, NULL, NULL);
+ g_raid_md_ddf_refill(sc);
+ }
+ return (error);
+ }
+ return (-100);
+}
+
+static int
+g_raid_md_write_ddf(struct g_raid_md_object *md, struct g_raid_volume *tvol,
+ struct g_raid_subdisk *tsd, struct g_raid_disk *tdisk)
+{
+ struct g_raid_softc *sc;
+ struct g_raid_volume *vol;
+ struct g_raid_subdisk *sd;
+ struct g_raid_disk *disk;
+ struct g_raid_md_ddf_perdisk *pd;
+ struct g_raid_md_ddf_pervolume *pv;
+ struct g_raid_md_ddf_object *mdi;
+ struct ddf_meta *gmeta;
+ struct ddf_vol_meta *vmeta;
+ struct ddf_vdc_record *vdc;
+ struct ddf_sa_record *sa;
+ uint64_t *val2;
+ int i, j, pos, bvd, size;
+
+ sc = md->mdo_softc;
+ mdi = (struct g_raid_md_ddf_object *)md;
+ gmeta = &mdi->mdio_meta;
+
+ if (sc->sc_stopping == G_RAID_DESTROY_HARD)
+ return (0);
+
+ /*
+ * Clear disk flags to let only really needed ones to be reset.
+ * Do it only if there are no volumes in starting state now,
+ * as they can update disk statuses yet and we may kill innocent.
+ */
+ if (mdi->mdio_starting == 0) {
+ for (i = 0; i < GET16(gmeta, pdr->Populated_PDEs); i++) {
+ if (isff(gmeta->pdr->entry[i].PD_GUID, 24))
+ continue;
+ SET16(gmeta, pdr->entry[i].PD_Type,
+ GET16(gmeta, pdr->entry[i].PD_Type) &
+ ~(DDF_PDE_PARTICIPATING |
+ DDF_PDE_GLOBAL_SPARE | DDF_PDE_CONFIG_SPARE));
+ if ((GET16(gmeta, pdr->entry[i].PD_State) &
+ DDF_PDE_PFA) == 0)
+ SET16(gmeta, pdr->entry[i].PD_State, 0);
+ }
+ }
+
+ /* Generate/update new per-volume metadata. */
+ TAILQ_FOREACH(vol, &sc->sc_volumes, v_next) {
+ pv = (struct g_raid_md_ddf_pervolume *)vol->v_md_data;
+ if (vol->v_stopping || !pv->pv_started)
+ continue;
+ vmeta = &pv->pv_meta;
+
+ SET32(vmeta, vdc->Sequence_Number,
+ GET32(vmeta, vdc->Sequence_Number) + 1);
+ if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1E &&
+ vol->v_disks_count % 2 == 0)
+ SET16(vmeta, vdc->Primary_Element_Count, 2);
+ else
+ SET16(vmeta, vdc->Primary_Element_Count,
+ vol->v_disks_count);
+ SET8(vmeta, vdc->Stripe_Size,
+ ffs(vol->v_strip_size / vol->v_sectorsize) - 1);
+ if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1E &&
+ vol->v_disks_count % 2 == 0) {
+ SET8(vmeta, vdc->Primary_RAID_Level,
+ DDF_VDCR_RAID1);
+ SET8(vmeta, vdc->RLQ, 0);
+ SET8(vmeta, vdc->Secondary_Element_Count,
+ vol->v_disks_count / 2);
+ SET8(vmeta, vdc->Secondary_RAID_Level, 0);
+ } else {
+ SET8(vmeta, vdc->Primary_RAID_Level,
+ vol->v_raid_level);
+ SET8(vmeta, vdc->RLQ,
+ vol->v_raid_level_qualifier);
+ SET8(vmeta, vdc->Secondary_Element_Count, 1);
+ SET8(vmeta, vdc->Secondary_RAID_Level, 0);
+ }
+ SET8(vmeta, vdc->Secondary_Element_Seq, 0);
+ SET64(vmeta, vdc->Block_Count, 0);
+ SET64(vmeta, vdc->VD_Size, vol->v_mediasize / vol->v_sectorsize);
+ SET16(vmeta, vdc->Block_Size, vol->v_sectorsize);
+ SET8(vmeta, vdc->Rotate_Parity_count,
+ fls(vol->v_rotate_parity) - 1);
+ SET8(vmeta, vdc->MDF_Parity_Disks, vol->v_mdf_pdisks);
+ SET16(vmeta, vdc->MDF_Parity_Generator_Polynomial,
+ vol->v_mdf_polynomial);
+ SET8(vmeta, vdc->MDF_Constant_Generation_Method,
+ vol->v_mdf_method);
+
+ SET16(vmeta, vde->VD_Number, vol->v_global_id);
+ if (vol->v_state <= G_RAID_VOLUME_S_BROKEN)
+ SET8(vmeta, vde->VD_State, DDF_VDE_FAILED);
+ else if (vol->v_state <= G_RAID_VOLUME_S_DEGRADED)
+ SET8(vmeta, vde->VD_State, DDF_VDE_DEGRADED);
+ else if (vol->v_state <= G_RAID_VOLUME_S_SUBOPTIMAL)
+ SET8(vmeta, vde->VD_State, DDF_VDE_PARTIAL);
+ else
+ SET8(vmeta, vde->VD_State, DDF_VDE_OPTIMAL);
+ if (vol->v_dirty ||
+ g_raid_nsubdisks(vol, G_RAID_SUBDISK_S_STALE) > 0 ||
+ g_raid_nsubdisks(vol, G_RAID_SUBDISK_S_RESYNC) > 0)
+ SET8(vmeta, vde->VD_State,
+ GET8(vmeta, vde->VD_State) | DDF_VDE_DIRTY);
+ SET8(vmeta, vde->Init_State, DDF_VDE_INIT_FULL); // XXX
+ ddf_meta_put_name(vmeta, vol->v_name);
+
+ for (i = 0; i < vol->v_disks_count; i++) {
+ sd = &vol->v_subdisks[i];
+ bvd = i / GET16(vmeta, vdc->Primary_Element_Count);
+ pos = i % GET16(vmeta, vdc->Primary_Element_Count);
+ disk = sd->sd_disk;
+ if (disk != NULL) {
+ pd = (struct g_raid_md_ddf_perdisk *)disk->d_md_data;
+ if (vmeta->bvdc[bvd] == NULL) {
+ size = GET16(vmeta,
+ hdr->Configuration_Record_Length) *
+ vmeta->sectorsize;
+ vmeta->bvdc[bvd] = malloc(size,
+ M_MD_DDF, M_WAITOK);
+ memset(vmeta->bvdc[bvd], 0xff, size);
+ }
+ memcpy(vmeta->bvdc[bvd], vmeta->vdc,
+ sizeof(struct ddf_vdc_record));
+ SET8(vmeta, bvdc[bvd]->Secondary_Element_Seq, bvd);
+ SET64(vmeta, bvdc[bvd]->Block_Count,
+ sd->sd_size / vol->v_sectorsize);
+ SET32(vmeta, bvdc[bvd]->Physical_Disk_Sequence[pos],
+ GET32(&pd->pd_meta, pdd->PD_Reference));
+ val2 = (uint64_t *)&(vmeta->bvdc[bvd]->Physical_Disk_Sequence[
+ GET16(vmeta, hdr->Max_Primary_Element_Entries)]);
+ SET64P(vmeta, val2 + pos,
+ sd->sd_offset / vol->v_sectorsize);
+ }
+ if (vmeta->bvdc[bvd] == NULL)
+ continue;
+
+ j = ddf_meta_find_pd(gmeta, NULL,
+ GET32(vmeta, bvdc[bvd]->Physical_Disk_Sequence[pos]));
+ if (j < 0)
+ continue;
+ SET32(gmeta, pdr->entry[j].PD_Type,
+ GET32(gmeta, pdr->entry[j].PD_Type) |
+ DDF_PDE_PARTICIPATING);
+ if (sd->sd_state == G_RAID_SUBDISK_S_NONE)
+ SET32(gmeta, pdr->entry[j].PD_State,
+ GET32(gmeta, pdr->entry[j].PD_State) |
+ (DDF_PDE_FAILED | DDF_PDE_MISSING));
+ else if (sd->sd_state == G_RAID_SUBDISK_S_FAILED)
+ SET32(gmeta, pdr->entry[j].PD_State,
+ GET32(gmeta, pdr->entry[j].PD_State) |
+ (DDF_PDE_FAILED | DDF_PDE_PFA));
+ else if (sd->sd_state <= G_RAID_SUBDISK_S_REBUILD)
+ SET32(gmeta, pdr->entry[j].PD_State,
+ GET32(gmeta, pdr->entry[j].PD_State) |
+ DDF_PDE_REBUILD);
+ else
+ SET32(gmeta, pdr->entry[j].PD_State,
+ GET32(gmeta, pdr->entry[j].PD_State) |
+ DDF_PDE_ONLINE);
+ }
+ }
+
+ /* Mark spare and failed disks as such. */
+ TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
+ pd = (struct g_raid_md_ddf_perdisk *)disk->d_md_data;
+ i = ddf_meta_find_pd(gmeta, NULL,
+ GET32(&pd->pd_meta, pdd->PD_Reference));
+ if (i < 0)
+ continue;
+ if (disk->d_state == G_RAID_DISK_S_FAILED) {
+ SET32(gmeta, pdr->entry[i].PD_State,
+ GET32(gmeta, pdr->entry[i].PD_State) |
+ (DDF_PDE_FAILED | DDF_PDE_PFA));
+ }
+ if (disk->d_state != G_RAID_DISK_S_SPARE)
+ continue;
+ sa = ddf_meta_find_sa(&pd->pd_meta, 0);
+ if (sa == NULL ||
+ (GET8D(&pd->pd_meta, sa->Spare_Type) &
+ DDF_SAR_TYPE_DEDICATED) == 0) {
+ SET16(gmeta, pdr->entry[i].PD_Type,
+ GET16(gmeta, pdr->entry[i].PD_Type) |
+ DDF_PDE_GLOBAL_SPARE);
+ } else {
+ SET16(gmeta, pdr->entry[i].PD_Type,
+ GET16(gmeta, pdr->entry[i].PD_Type) |
+ DDF_PDE_CONFIG_SPARE);
+ }
+ SET32(gmeta, pdr->entry[i].PD_State,
+ GET32(gmeta, pdr->entry[i].PD_State) |
+ DDF_PDE_ONLINE);
+ }
+
+ /* Remove disks without "participating" flag (unused). */
+ for (i = 0, j = -1; i < GET16(gmeta, pdr->Populated_PDEs); i++) {
+ if (isff(gmeta->pdr->entry[i].PD_GUID, 24))
+ continue;
+ if ((GET16(gmeta, pdr->entry[i].PD_Type) &
+ (DDF_PDE_PARTICIPATING |
+ DDF_PDE_GLOBAL_SPARE | DDF_PDE_CONFIG_SPARE)) != 0 ||
+ g_raid_md_ddf_get_disk(sc,
+ NULL, GET32(gmeta, pdr->entry[i].PD_Reference)) != NULL)
+ j = i;
+ else
+ memset(&gmeta->pdr->entry[i], 0xff,
+ sizeof(struct ddf_pd_entry));
+ }
+ SET16(gmeta, pdr->Populated_PDEs, j + 1);
+
+ /* Update per-disk metadata and write them. */
+ TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
+ pd = (struct g_raid_md_ddf_perdisk *)disk->d_md_data;
+ if (disk->d_state != G_RAID_DISK_S_ACTIVE &&
+ disk->d_state != G_RAID_DISK_S_SPARE)
+ continue;
+ /* Update PDR. */
+ memcpy(pd->pd_meta.pdr, gmeta->pdr,
+ GET32(&pd->pd_meta, hdr->pdr_length) *
+ pd->pd_meta.sectorsize);
+ /* Update VDR. */
+ SET16(&pd->pd_meta, vdr->Populated_VDEs, 0);
+ TAILQ_FOREACH(vol, &sc->sc_volumes, v_next) {
+ if (vol->v_stopping)
+ continue;
+ pv = (struct g_raid_md_ddf_pervolume *)vol->v_md_data;
+ i = ddf_meta_find_vd(&pd->pd_meta,
+ pv->pv_meta.vde->VD_GUID);
+ if (i < 0)
+ i = ddf_meta_find_vd(&pd->pd_meta, NULL);
+ if (i >= 0)
+ memcpy(&pd->pd_meta.vdr->entry[i],
+ pv->pv_meta.vde,
+ sizeof(struct ddf_vd_entry));
+ }
+ /* Update VDC. */
+ if (mdi->mdio_starting == 0) {
+ /* Remove all VDCs to restore needed later. */
+ j = GETCRNUM(&pd->pd_meta);
+ for (i = 0; i < j; i++) {
+ vdc = GETVDCPTR(&pd->pd_meta, i);
+ if (GET32D(&pd->pd_meta, vdc->Signature) !=
+ DDF_VDCR_SIGNATURE)
+ continue;
+ SET32D(&pd->pd_meta, vdc->Signature, 0xffffffff);
+ }
+ }
+ TAILQ_FOREACH(sd, &disk->d_subdisks, sd_next) {
+ vol = sd->sd_volume;
+ if (vol->v_stopping)
+ continue;
+ pv = (struct g_raid_md_ddf_pervolume *)vol->v_md_data;
+ vmeta = &pv->pv_meta;
+ vdc = ddf_meta_find_vdc(&pd->pd_meta,
+ vmeta->vde->VD_GUID);
+ if (vdc == NULL)
+ vdc = ddf_meta_find_vdc(&pd->pd_meta, NULL);
+ if (vdc != NULL) {
+ bvd = sd->sd_pos / GET16(vmeta,
+ vdc->Primary_Element_Count);
+ memcpy(vdc, vmeta->bvdc[bvd],
+ GET16(&pd->pd_meta,
+ hdr->Configuration_Record_Length) *
+ pd->pd_meta.sectorsize);
+ }
+ }
+ G_RAID_DEBUG(1, "Writing DDF metadata to %s",
+ g_raid_get_diskname(disk));
+ g_raid_md_ddf_print(&pd->pd_meta);
+ ddf_meta_write(disk->d_consumer, &pd->pd_meta);
+ }
+ return (0);
+}
+
+static int
+g_raid_md_fail_disk_ddf(struct g_raid_md_object *md,
+ struct g_raid_subdisk *tsd, struct g_raid_disk *tdisk)
+{
+ struct g_raid_softc *sc;
+ struct g_raid_md_ddf_perdisk *pd;
+ struct g_raid_subdisk *sd;
+ int i;
+
+ sc = md->mdo_softc;
+ pd = (struct g_raid_md_ddf_perdisk *)tdisk->d_md_data;
+
+ /* We can't fail disk that is not a part of array now. */
+ if (tdisk->d_state != G_RAID_DISK_S_ACTIVE)
+ return (-1);
+
+ /*
+ * Mark disk as failed in metadata and try to write that metadata
+ * to the disk itself to prevent it's later resurrection as STALE.
+ */
+ G_RAID_DEBUG(1, "Writing DDF metadata to %s",
+ g_raid_get_diskname(tdisk));
+ i = ddf_meta_find_pd(&pd->pd_meta, NULL, GET32(&pd->pd_meta, pdd->PD_Reference));
+ SET16(&pd->pd_meta, pdr->entry[i].PD_State, DDF_PDE_FAILED | DDF_PDE_PFA);
+ if (tdisk->d_consumer != NULL)
+ ddf_meta_write(tdisk->d_consumer, &pd->pd_meta);
+
+ /* Change states. */
+ g_raid_change_disk_state(tdisk, G_RAID_DISK_S_FAILED);
+ TAILQ_FOREACH(sd, &tdisk->d_subdisks, sd_next) {
+ g_raid_change_subdisk_state(sd,
+ G_RAID_SUBDISK_S_FAILED);
+ g_raid_event_send(sd, G_RAID_SUBDISK_E_FAILED,
+ G_RAID_EVENT_SUBDISK);
+ }
+
+ /* Write updated metadata to remaining disks. */
+ g_raid_md_write_ddf(md, NULL, NULL, tdisk);
+
+ g_raid_md_ddf_refill(sc);
+ return (0);
+}
+
+static int
+g_raid_md_free_disk_ddf(struct g_raid_md_object *md,
+ struct g_raid_disk *disk)
+{
+ struct g_raid_md_ddf_perdisk *pd;
+
+ pd = (struct g_raid_md_ddf_perdisk *)disk->d_md_data;
+ ddf_meta_free(&pd->pd_meta);
+ free(pd, M_MD_DDF);
+ disk->d_md_data = NULL;
+ return (0);
+}
+
+static int
+g_raid_md_free_volume_ddf(struct g_raid_md_object *md,
+ struct g_raid_volume *vol)
+{
+ struct g_raid_md_ddf_object *mdi;
+ struct g_raid_md_ddf_pervolume *pv;
+
+ mdi = (struct g_raid_md_ddf_object *)md;
+ pv = (struct g_raid_md_ddf_pervolume *)vol->v_md_data;
+ ddf_vol_meta_free(&pv->pv_meta);
+ if (!pv->pv_started) {
+ pv->pv_started = 1;
+ mdi->mdio_starting--;
+ callout_stop(&pv->pv_start_co);
+ }
+ free(pv, M_MD_DDF);
+ vol->v_md_data = NULL;
+ return (0);
+}
+
+static int
+g_raid_md_free_ddf(struct g_raid_md_object *md)
+{
+ struct g_raid_md_ddf_object *mdi;
+
+ mdi = (struct g_raid_md_ddf_object *)md;
+ if (!mdi->mdio_started) {
+ mdi->mdio_started = 0;
+ callout_stop(&mdi->mdio_start_co);
+ G_RAID_DEBUG1(1, md->mdo_softc,
+ "root_mount_rel %p", mdi->mdio_rootmount);
+ root_mount_rel(mdi->mdio_rootmount);
+ mdi->mdio_rootmount = NULL;
+ }
+ ddf_meta_free(&mdi->mdio_meta);
+ return (0);
+}
+
+G_RAID_MD_DECLARE(g_raid_md_ddf);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/raid/md_ddf.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/geom/raid/md_ddf.h Wed Jul 25 16:45:04 2012 +0300
@@ -0,0 +1,345 @@
+/*-
+ * Copyright (c) 2012 Alexander Motin <mav at FreeBSD.org>
+ * Copyright (c) 2008 Scott Long
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD: head/sys/geom/raid/md_ddf.h 234848 2012-04-30 17:53:02Z mav $
+ */
+
+#ifndef MD_DDF_H
+#define MD_DDF_H
+
+/* Definitions from the SNIA DDF spec, rev 1.2/2.0 */
+
+#define DDF_HEADER_LENGTH 512
+struct ddf_header {
+ uint32_t Signature;
+#define DDF_HEADER_SIGNATURE 0xde11de11
+ uint32_t CRC;
+ uint8_t DDF_Header_GUID[24];
+ uint8_t DDF_rev[8];
+ uint32_t Sequence_Number;
+ uint32_t TimeStamp;
+ uint8_t Open_Flag;
+#define DDF_HEADER_CLOSED 0x00
+#define DDF_HEADER_OPENED_MASK 0x0f
+#define DDF_HEADER_OPEN_ANCHOR 0xff
+ uint8_t Foreign_Flag;
+ uint8_t Diskgrouping;
+ uint8_t pad1[13];
+ uint8_t Header_ext[32];
+ uint64_t Primary_Header_LBA;
+ uint64_t Secondary_Header_LBA;
+ uint8_t Header_Type;
+#define DDF_HEADER_ANCHOR 0x00
+#define DDF_HEADER_PRIMARY 0x01
+#define DDF_HEADER_SECONDARY 0x02
+ uint8_t pad2[3];
+ uint32_t WorkSpace_Length;
+ uint64_t WorkSpace_LBA;
+ uint16_t Max_PD_Entries;
+ uint16_t Max_VD_Entries;
+ uint16_t Max_Partitions;
+ uint16_t Configuration_Record_Length;
+ uint16_t Max_Primary_Element_Entries;
+ uint32_t Max_Mapped_Block_Entries; /* DDF 2.0 */
+ uint8_t pad3[50];
+ uint32_t cd_section; /* Controller_Data_Section */
+ uint32_t cd_length; /* Controller_Data_Section_Length */
+ uint32_t pdr_section; /* Physical_Drive_Records_Section */
+ uint32_t pdr_length; /* Physical_Drive_Records_Length */
+ uint32_t vdr_section; /* Virtual_Drive_Records_Section */
+ uint32_t vdr_length; /* Virtual_Drive_Records_Length */
+ uint32_t cr_section; /* Configuration_Records_Section */
+ uint32_t cr_length; /* Configuration_Records_Length */
+ uint32_t pdd_section; /* Physical_Drive_Data_Section */
+ uint32_t pdd_length; /* Physical_Drive_Data_Length */
+ uint32_t bbmlog_section; /* BBM_Log_Section */
+ uint32_t bbmlog_length; /* BBM_Log_Section_Length */
+ uint32_t Diagnostic_Space;
+ uint32_t Diagnostic_Space_Length;
+ uint32_t Vendor_Specific_Logs;
+ uint32_t Vendor_Specific_Logs_Length;
+ uint8_t pad4[256];
+} __packed;
+
+struct ddf_cd_record {
+ uint32_t Signature;
+#define DDF_CONTROLLER_DATA_SIGNATURE 0xad111111
+ uint32_t CRC;
+ uint8_t Controller_GUID[24];
+ struct {
+ uint16_t Vendor_ID;
+ uint16_t Device_ID;
+ uint16_t SubVendor_ID;
+ uint16_t SubDevice_ID;
+ } Controller_Type __packed;
+ uint8_t Product_ID[16];
+ uint8_t pad1[8];
+ uint8_t Controller_Data[448];
+} __packed;
+
+struct ddf_device_scsi {
+ uint8_t Lun;
+ uint8_t Id;
+ uint8_t Channel;
+ uint8_t Path_Flags;
+#define DDF_DEVICE_SCSI_FLAG_BROKEN (1 << 7)
+} __packed;
+
+struct ddf_device_sas {
+ uint64_t Initiator_Path;
+} __packed;
+
+union ddf_pathinfo {
+ struct {
+ struct ddf_device_scsi Path0;
+ struct ddf_device_scsi Path1;
+ uint8_t pad[10];
+ } __packed scsi;
+ struct {
+ struct ddf_device_sas Path0;
+ struct ddf_device_sas Path1;
+ uint8_t Path0_Flags;
+ uint8_t Path1_Flags;
+#define DDF_DEVICE_SAS_PHY_ID 0x7f
+#define DDF_DEVICE_SAS_FLAG_BROKEN (1 << 7)
+ } __packed sas;
+} __packed;
+
+struct ddf_pd_entry {
+ uint8_t PD_GUID[24];
+ uint32_t PD_Reference;
+ uint16_t PD_Type;
+#define DDF_PDE_GUID_FORCE (1 << 0)
+#define DDF_PDE_PARTICIPATING (1 << 1)
+#define DDF_PDE_GLOBAL_SPARE (1 << 2)
+#define DDF_PDE_CONFIG_SPARE (1 << 3)
+#define DDF_PDE_FOREIGN (1 << 4)
+#define DDF_PDE_LEGACY (1 << 5)
+#define DDF_PDE_TYPE_MASK (0x0f << 12)
+#define DDF_PDE_UNKNOWN (0x00 << 12)
+#define DDF_PDE_SCSI (0x01 << 12)
+#define DDF_PDE_SAS (0x02 << 12)
+#define DDF_PDE_SATA (0x03 << 12)
+#define DDF_PDE_FC (0x04 << 12)
+ uint16_t PD_State;
+#define DDF_PDE_ONLINE (1 << 0)
+#define DDF_PDE_FAILED (1 << 1)
+#define DDF_PDE_REBUILD (1 << 2)
+#define DDF_PDE_TRANSITION (1 << 3)
+#define DDF_PDE_PFA (1 << 4)
+#define DDF_PDE_UNRECOVERED (1 << 5)
+#define DDF_PDE_MISSING (1 << 6)
+ uint64_t Configured_Size;
+ union ddf_pathinfo Path_Information;
+ uint16_t Block_Size; /* DDF 2.0 */
+ uint8_t pad1[4];
+} __packed;
+
+struct ddf_pd_record {
+ uint32_t Signature;
+#define DDF_PDR_SIGNATURE 0x22222222
+ uint32_t CRC;
+ uint16_t Populated_PDEs;
+ uint16_t Max_PDE_Supported;
+ uint8_t pad1[52];
+ struct ddf_pd_entry entry[0];
+} __packed;
+
+struct ddf_vd_entry {
+ uint8_t VD_GUID[24];
+ uint16_t VD_Number;
+ uint8_t pad1[2];
+ uint16_t VD_Type;
+#define DDF_VDE_SHARED (1 << 0)
+#define DDF_VDE_ENFORCE_GROUP (1 << 1)
+#define DDF_VDE_UNICODE_NAME (1 << 2)
+#define DDF_VDE_OWNER_ID_VALID (1 << 3)
+ uint16_t Controller_GUID_CRC;
+ uint8_t VD_State;
+#define DDF_VDE_OPTIMAL 0x00
+#define DDF_VDE_DEGRADED 0x01
+#define DDF_VDE_DELETED 0x02
+#define DDF_VDE_MISSING 0x03
+#define DDF_VDE_FAILED 0x04
+#define DDF_VDE_PARTIAL 0x05
+#define DDF_VDE_OFFLINE 0x06
+#define DDF_VDE_STATE_MASK 0x07
+#define DDF_VDE_MORPH (1 << 3)
+#define DDF_VDE_DIRTY (1 << 4)
+ uint8_t Init_State;
+#define DDF_VDE_UNINTIALIZED 0x00
+#define DDF_VDE_INIT_QUICK 0x01
+#define DDF_VDE_INIT_FULL 0x02
+#define DDF_VDE_INIT_MASK 0x03
+#define DDF_VDE_UACCESS_RW 0x00
+#define DDF_VDE_UACCESS_RO 0x80
+#define DDF_VDE_UACCESS_BLOCKED 0xc0
+#define DDF_VDE_UACCESS_MASK 0xc0
+ uint8_t Drive_Failures_Remaining; /* DDF 2.0 */
+ uint8_t pad2[13];
+ uint8_t VD_Name[16];
+} __packed;
+
+struct ddf_vd_record {
+ uint32_t Signature;
+#define DDF_VD_RECORD_SIGNATURE 0xdddddddd
+ uint32_t CRC;
+ uint16_t Populated_VDEs;
+ uint16_t Max_VDE_Supported;
+ uint8_t pad1[52];
+ struct ddf_vd_entry entry[0];
+} __packed;
+
+#define DDF_CR_INVALID 0xffffffff
+
+struct ddf_vdc_record {
+ uint32_t Signature;
+#define DDF_VDCR_SIGNATURE 0xeeeeeeee
+ uint32_t CRC;
+ uint8_t VD_GUID[24];
+ uint32_t Timestamp;
+ uint32_t Sequence_Number;
+ uint8_t pad1[24];
+ uint16_t Primary_Element_Count;
+ uint8_t Stripe_Size;
+ uint8_t Primary_RAID_Level;
+#define DDF_VDCR_RAID0 0x00
+#define DDF_VDCR_RAID1 0x01
+#define DDF_VDCR_RAID3 0x03
+#define DDF_VDCR_RAID4 0x04
+#define DDF_VDCR_RAID5 0x05
+#define DDF_VDCR_RAID6 0x06
+#define DDF_VDCR_RAID1E 0x11
+#define DDF_VDCR_SINGLE 0x0f
+#define DDF_VDCR_CONCAT 0x1f
+#define DDF_VDCR_RAID5E 0x15
+#define DDF_VDCR_RAID5EE 0x25
+ uint8_t RLQ;
+ uint8_t Secondary_Element_Count;
+ uint8_t Secondary_Element_Seq;
+ uint8_t Secondary_RAID_Level;
+ uint64_t Block_Count;
+ uint64_t VD_Size;
+ uint16_t Block_Size; /* DDF 2.0 */
+ uint8_t Rotate_Parity_count; /* DDF 2.0 */
+ uint8_t pad2[5];
+ uint32_t Associated_Spares[8];
+ uint64_t Cache_Flags;
+#define DDF_VDCR_CACHE_WB (1 << 0)
+#define DDF_VDCR_CACHE_WB_ADAPTIVE (1 << 1)
+#define DDF_VDCR_CACHE_RA (1 << 2)
+#define DDF_VDCR_CACHE_RA_ADAPTIVE (1 << 3)
+#define DDF_VDCR_CACHE_WCACHE_NOBATTERY (1 << 4)
+#define DDF_VDCR_CACHE_WCACHE_ALLOW (1 << 5)
+#define DDF_VDCR_CACHE_RCACHE_ALLOW (1 << 6)
+#define DDF_VDCR_CACHE_VENDOR (1 << 7)
+ uint8_t BG_Rate;
+ uint8_t pad3[3];
+ uint8_t MDF_Parity_Disks; /* DDF 2.0 */
+ uint16_t MDF_Parity_Generator_Polynomial; /* DDF 2.0 */
+ uint8_t pad4;
+ uint8_t MDF_Constant_Generation_Method; /* DDF 2.0 */
+ uint8_t pad5[47];
+ uint8_t pad6[192];
+ uint8_t V0[32];
+ uint8_t V1[32];
+ uint8_t V2[16];
+ uint8_t V3[16];
+ uint8_t Vendor_Scratch[32];
+ uint32_t Physical_Disk_Sequence[0];
+} __packed;
+
+struct ddf_vuc_record {
+ uint32_t Signature;
+#define DDF_VUCR_SIGNATURE 0x88888888
+ uint32_t CRC;
+ uint8_t VD_GUID[24];
+} __packed;
+
+struct ddf_sa_entry {
+ uint8_t VD_GUID[24];
+ uint16_t Secondary_Element;
+ uint8_t rsrvd2[6];
+} __packed;
+
+struct ddf_sa_record {
+ uint32_t Signature;
+#define DDF_SA_SIGNATURE 0x55555555
+ uint32_t CRC;
+ uint32_t Timestamp;
+ uint8_t pad1[7];
+ uint8_t Spare_Type;
+#define DDF_SAR_TYPE_DEDICATED (1 << 0)
+#define DDF_SAR_TYPE_REVERTIBLE (1 << 1)
+#define DDF_SAR_TYPE_ACTIVE (1 << 2)
+#define DDF_SAR_TYPE_ENCL_AFFINITY (1 << 3)
+ uint16_t Populated_SAEs;
+ uint16_t MAX_SAE_Supported;
+ uint8_t pad2[8];
+ struct ddf_sa_entry entry[0];
+} __packed;
+
+struct ddf_pdd_record {
+ uint32_t Signature;
+#define DDF_PDD_SIGNATURE 0x33333333
+ uint32_t CRC;
+ uint8_t PD_GUID[24];
+ uint32_t PD_Reference;
+ uint8_t Forced_Ref_Flag;
+#define DDF_PDD_FORCED_REF 0x01
+ uint8_t Forced_PD_GUID_Flag;
+#define DDF_PDD_FORCED_GUID 0x01
+ uint8_t Vendor_Scratch[32];
+ uint8_t pad2[442];
+} __packed;
+
+struct ddf_bbm_entry {
+ uint64_t Defective_Block_Start;
+ uint32_t Spare_Block_Offset;
+ uint16_t Remapped_Count;
+ uint8_t pad[2];
+};
+
+struct ddf_bbm_log {
+ uint32_t Signature;
+#define DDF_BBML_SIGNATURE 0xabadb10c
+ uint32_t CRC;
+ uint32_t Entry_Count;
+ uint32_t Spare_Block_Count;
+ uint8_t pad1[8];
+ uint64_t First_Spare_LBA;
+ uint64_t Mapped_Block_Entry[0];
+} __packed;
+
+struct ddf_vendor_log {
+ uint32_t Signature;
+#define DDF_VENDOR_LOG_SIGNATURE 0x01dbeef0
+ uint32_t CRC;
+ uint64_t Log_Owner;
+ uint8_t pad1[16];
+} __packed;
+
+#endif
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/raid/md_intel.c
--- a/head/sys/geom/raid/md_intel.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/raid/md_intel.c Wed Jul 25 16:45:04 2012 +0300
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2010 Alexander Motin <mav at FreeBSD.org>
+ * Copyright (c) 2000 - 2008 Søren Schmidt <sos at FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/raid/md_intel.c 234458 2012-04-19 12:30:12Z mav $");
+__FBSDID("$FreeBSD: head/sys/geom/raid/md_intel.c 234727 2012-04-27 08:49:15Z mav $");
#include <sys/param.h>
#include <sys/bio.h>
@@ -1489,7 +1490,7 @@
return (-3);
}
if (strcasecmp(levelname, "RAID5") == 0)
- levelname = "RAID5LA";
+ levelname = "RAID5-LA";
if (g_raid_volume_str2level(levelname, &level, &qual)) {
gctl_error(req, "Unknown RAID level '%s'.", levelname);
return (-4);
@@ -1704,7 +1705,7 @@
return (-3);
}
if (strcasecmp(levelname, "RAID5") == 0)
- levelname = "RAID5LA";
+ levelname = "RAID5-LA";
if (g_raid_volume_str2level(levelname, &level, &qual)) {
gctl_error(req, "Unknown RAID level '%s'.", levelname);
return (-4);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/raid/md_jmicron.c
--- a/head/sys/geom/raid/md_jmicron.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/raid/md_jmicron.c Wed Jul 25 16:45:04 2012 +0300
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2010 Alexander Motin <mav at FreeBSD.org>
+ * Copyright (c) 2000 - 2008 Søren Schmidt <sos at FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/raid/md_jmicron.c 234458 2012-04-19 12:30:12Z mav $");
+__FBSDID("$FreeBSD: head/sys/geom/raid/md_jmicron.c 234727 2012-04-27 08:49:15Z mav $");
#include <sys/param.h>
#include <sys/bio.h>
@@ -1061,7 +1062,7 @@
return (-3);
}
if (strcasecmp(levelname, "RAID5") == 0)
- levelname = "RAID5LA";
+ levelname = "RAID5-LA";
if (g_raid_volume_str2level(levelname, &level, &qual)) {
gctl_error(req, "Unknown RAID level '%s'.", levelname);
return (-4);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/raid/md_nvidia.c
--- a/head/sys/geom/raid/md_nvidia.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/raid/md_nvidia.c Wed Jul 25 16:45:04 2012 +0300
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011 Alexander Motin <mav at FreeBSD.org>
+ * Copyright (c) 2000 - 2008 Søren Schmidt <sos at FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/raid/md_nvidia.c 234458 2012-04-19 12:30:12Z mav $");
+__FBSDID("$FreeBSD: head/sys/geom/raid/md_nvidia.c 234727 2012-04-27 08:49:15Z mav $");
#include <sys/param.h>
#include <sys/bio.h>
@@ -1064,7 +1065,7 @@
return (-3);
}
if (strcasecmp(levelname, "RAID5") == 0)
- levelname = "RAID5LS";
+ levelname = "RAID5-LS";
if (g_raid_volume_str2level(levelname, &level, &qual)) {
gctl_error(req, "Unknown RAID level '%s'.", levelname);
return (-4);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/raid/md_promise.c
--- a/head/sys/geom/raid/md_promise.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/raid/md_promise.c Wed Jul 25 16:45:04 2012 +0300
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011 Alexander Motin <mav at FreeBSD.org>
+ * Copyright (c) 2000 - 2008 Søren Schmidt <sos at FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/raid/md_promise.c 234458 2012-04-19 12:30:12Z mav $");
+__FBSDID("$FreeBSD: head/sys/geom/raid/md_promise.c 235080 2012-05-06 12:55:20Z mav $");
#include <sys/param.h>
#include <sys/bio.h>
@@ -1245,7 +1246,7 @@
return (-3);
}
if (strcasecmp(levelname, "RAID5") == 0)
- levelname = "RAID5LA";
+ levelname = "RAID5-LA";
if (g_raid_volume_str2level(levelname, &level, &qual)) {
gctl_error(req, "Unknown RAID level '%s'.", levelname);
return (-4);
@@ -1954,6 +1955,8 @@
pv->pv_started = 1;
callout_stop(&pv->pv_start_co);
}
+ free(pv, M_MD_PROMISE);
+ vol->v_md_data = NULL;
return (0);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/raid/md_sii.c
--- a/head/sys/geom/raid/md_sii.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/raid/md_sii.c Wed Jul 25 16:45:04 2012 +0300
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011 Alexander Motin <mav at FreeBSD.org>
+ * Copyright (c) 2000 - 2008 Søren Schmidt <sos at FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/raid/md_sii.c 234458 2012-04-19 12:30:12Z mav $");
+__FBSDID("$FreeBSD: head/sys/geom/raid/md_sii.c 234727 2012-04-27 08:49:15Z mav $");
#include <sys/param.h>
#include <sys/bio.h>
@@ -1148,7 +1149,7 @@
return (-3);
}
if (strcasecmp(levelname, "RAID5") == 0)
- levelname = "RAID5LS";
+ levelname = "RAID5-LS";
if (g_raid_volume_str2level(levelname, &level, &qual)) {
gctl_error(req, "Unknown RAID level '%s'.", levelname);
return (-4);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/raid/tr_raid1.c
--- a/head/sys/geom/raid/tr_raid1.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/raid/tr_raid1.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/raid/tr_raid1.c 227309 2011-11-07 15:43:11Z ed $");
+__FBSDID("$FreeBSD: head/sys/geom/raid/tr_raid1.c 235270 2012-05-11 13:20:17Z mav $");
#include <sys/param.h>
#include <sys/bio.h>
@@ -145,7 +145,8 @@
trs = (struct g_raid_tr_raid1_object *)tr;
if (tr->tro_volume->v_raid_level != G_RAID_VOLUME_RL_RAID1 ||
- tr->tro_volume->v_raid_level_qualifier != G_RAID_VOLUME_RLQ_NONE)
+ (tr->tro_volume->v_raid_level_qualifier != G_RAID_VOLUME_RLQ_R1SM &&
+ tr->tro_volume->v_raid_level_qualifier != G_RAID_VOLUME_RLQ_R1MM))
return (G_RAID_TR_TASTE_FAIL);
trs->trso_starting = 1;
return (G_RAID_TR_TASTE_SUCCEED);
@@ -893,7 +894,16 @@
g_raid_unlock_range(sd->sd_volume, bp->bio_offset,
bp->bio_length);
}
- error = bp->bio_error;
+ if (pbp->bio_cmd != BIO_READ) {
+ if (pbp->bio_inbed == 1 || pbp->bio_error != 0)
+ pbp->bio_error = bp->bio_error;
+ if (bp->bio_error != 0) {
+ G_RAID_LOGREQ(0, bp, "Write failed: failing subdisk.");
+ g_raid_tr_raid1_fail_disk(sd->sd_softc, sd, sd->sd_disk);
+ }
+ error = pbp->bio_error;
+ } else
+ error = bp->bio_error;
g_destroy_bio(bp);
if (pbp->bio_children == pbp->bio_inbed) {
pbp->bio_completed = pbp->bio_length;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/raid/tr_raid1e.c
--- a/head/sys/geom/raid/tr_raid1e.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/raid/tr_raid1e.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/raid/tr_raid1e.c 227309 2011-11-07 15:43:11Z ed $");
+__FBSDID("$FreeBSD: head/sys/geom/raid/tr_raid1e.c 235270 2012-05-11 13:20:17Z mav $");
#include <sys/param.h>
#include <sys/bio.h>
@@ -187,7 +187,7 @@
trs = (struct g_raid_tr_raid1e_object *)tr;
if (tr->tro_volume->v_raid_level != G_RAID_VOLUME_RL_RAID1E ||
- tr->tro_volume->v_raid_level_qualifier != G_RAID_VOLUME_RLQ_NONE)
+ tr->tro_volume->v_raid_level_qualifier != G_RAID_VOLUME_RLQ_R1EA)
return (G_RAID_TR_TASTE_FAIL);
trs->trso_starting = 1;
return (G_RAID_TR_TASTE_SUCCEED);
@@ -338,6 +338,9 @@
g_raid_tr_raid1e_fail_disk(struct g_raid_softc *sc, struct g_raid_subdisk *sd,
struct g_raid_disk *disk)
{
+ struct g_raid_volume *vol;
+
+ vol = sd->sd_volume;
/*
* We don't fail the last disk in the pack, since it still has decent
* data on it and that's better than failing the disk if it is the root
@@ -347,8 +350,12 @@
* the volume that has / on it. I can't think of a case where we'd
* want the volume to go away on this kind of event.
*/
- if (g_raid_nsubdisks(sd->sd_volume, G_RAID_SUBDISK_S_ACTIVE) == 1 &&
- g_raid_get_subdisk(sd->sd_volume, G_RAID_SUBDISK_S_ACTIVE) == sd)
+ if ((g_raid_nsubdisks(vol, G_RAID_SUBDISK_S_ACTIVE) +
+ g_raid_nsubdisks(vol, G_RAID_SUBDISK_S_RESYNC) +
+ g_raid_nsubdisks(vol, G_RAID_SUBDISK_S_STALE) +
+ g_raid_nsubdisks(vol, G_RAID_SUBDISK_S_UNINITIALIZED) <
+ vol->v_disks_count) &&
+ (sd->sd_state >= G_RAID_SUBDISK_S_UNINITIALIZED))
return;
g_raid_fail_disk(sc, sd, disk);
}
@@ -1113,7 +1120,16 @@
G_RAID_LOGREQ(2, bp, "REMAP done %d.", bp->bio_error);
g_raid_unlock_range(sd->sd_volume, virtual, bp->bio_length);
}
- error = bp->bio_error;
+ if (pbp->bio_cmd != BIO_READ) {
+ if (pbp->bio_inbed == 1 || pbp->bio_error != 0)
+ pbp->bio_error = bp->bio_error;
+ if (bp->bio_error != 0) {
+ G_RAID_LOGREQ(0, bp, "Write failed: failing subdisk.");
+ g_raid_tr_raid1e_fail_disk(sd->sd_softc, sd, sd->sd_disk);
+ }
+ error = pbp->bio_error;
+ } else
+ error = bp->bio_error;
g_destroy_bio(bp);
if (pbp->bio_children == pbp->bio_inbed) {
pbp->bio_completed = pbp->bio_length;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/raid/tr_raid5.c
--- a/head/sys/geom/raid/tr_raid5.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/raid/tr_raid5.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/raid/tr_raid5.c 234458 2012-04-19 12:30:12Z mav $");
+__FBSDID("$FreeBSD: head/sys/geom/raid/tr_raid5.c 235076 2012-05-06 11:32:36Z mav $");
#include <sys/param.h>
#include <sys/bio.h>
@@ -106,9 +106,17 @@
trs = (struct g_raid_tr_raid5_object *)tr;
qual = tr->tro_volume->v_raid_level_qualifier;
- if (tr->tro_volume->v_raid_level == G_RAID_VOLUME_RL_RAID5 &&
+ if (tr->tro_volume->v_raid_level == G_RAID_VOLUME_RL_RAID4 &&
+ qual >= 0 && qual <= 1) {
+ /* RAID4 */
+ } else if ((tr->tro_volume->v_raid_level == G_RAID_VOLUME_RL_RAID5 ||
+ tr->tro_volume->v_raid_level == G_RAID_VOLUME_RL_RAID5E ||
+ tr->tro_volume->v_raid_level == G_RAID_VOLUME_RL_RAID5EE ||
+ tr->tro_volume->v_raid_level == G_RAID_VOLUME_RL_RAID5R ||
+ tr->tro_volume->v_raid_level == G_RAID_VOLUME_RL_RAID6 ||
+ tr->tro_volume->v_raid_level == G_RAID_VOLUME_RL_RAIDMDF) &&
qual >= 0 && qual <= 3) {
- /* RAID5 */
+ /* RAID5/5E/5EE/5R/6/MDF */
} else
return (G_RAID_TR_TASTE_FAIL);
trs->trso_starting = 1;
@@ -203,30 +211,58 @@
struct bio *cbp;
char *addr;
off_t offset, start, length, nstripe, remain;
- int no, pno;
- u_int strip_size, qual;
+ int no, pno, ddisks, pdisks, protate, pleft;
+ u_int strip_size, lvl, qual;
vol = tr->tro_volume;
addr = bp->bio_data;
strip_size = vol->v_strip_size;
+ lvl = tr->tro_volume->v_raid_level;
qual = tr->tro_volume->v_raid_level_qualifier;
+ protate = tr->tro_volume->v_rotate_parity;
/* Stripe number. */
nstripe = bp->bio_offset / strip_size;
/* Start position in stripe. */
start = bp->bio_offset % strip_size;
+ /* Number of data and parity disks. */
+ if (lvl == G_RAID_VOLUME_RL_RAIDMDF)
+ pdisks = tr->tro_volume->v_mdf_pdisks;
+ else if (lvl == G_RAID_VOLUME_RL_RAID5EE ||
+ lvl == G_RAID_VOLUME_RL_RAID6)
+ pdisks = 2;
+ else
+ pdisks = 1;
+ ddisks = vol->v_disks_count - pdisks;
/* Parity disk number. */
- pno = nstripe / (vol->v_disks_count - 1) % vol->v_disks_count;
- if (qual >= 2)
- pno = (vol->v_disks_count - 1) - pno;
- /* Disk number. */
- no = nstripe % (vol->v_disks_count - 1);
- if (qual & 1) {
- no = (pno + no + 1) % vol->v_disks_count;
- } else if (no >= pno)
- no++;
+ if (lvl == G_RAID_VOLUME_RL_RAID4) {
+ if (qual == 0) /* P0 */
+ pno = 0;
+ else /* PN */
+ pno = ddisks;
+ pleft = -1;
+ } else {
+ pno = (nstripe / (ddisks * protate)) % vol->v_disks_count;
+ pleft = protate - (nstripe / ddisks) % protate;
+ if (qual >= 2) { /* PN/Left */
+ pno = ddisks - pno;
+ if (pno < 0)
+ pno += vol->v_disks_count;
+ }
+ }
+ /* Data disk number. */
+ no = nstripe % ddisks;
+ if (lvl == G_RAID_VOLUME_RL_RAID4) {
+ if (qual == 0)
+ no += pdisks;
+ } else if (qual & 1) { /* Continuation/Symmetric */
+ no = (pno + pdisks + no) % vol->v_disks_count;
+ } else if (no >= pno) /* Restart/Asymmetric */
+ no += pdisks;
+ else
+ no += imax(0, pno + pdisks - vol->v_disks_count);
/* Stripe start position in disk. */
- offset = (nstripe / (vol->v_disks_count - 1)) * strip_size;
+ offset = (nstripe / ddisks) * strip_size;
/* Length of data to operate. */
remain = bp->bio_length;
@@ -242,33 +278,43 @@
cbp->bio_caller1 = &vol->v_subdisks[no];
bioq_insert_tail(&queue, cbp);
no++;
- if (qual & 1) {
+ if (lvl == G_RAID_VOLUME_RL_RAID4) {
+ no %= vol->v_disks_count;
+ if (no == pno)
+ no = (no + pdisks) % vol->v_disks_count;
+ } else if (qual & 1) { /* Continuation/Symmetric */
no %= vol->v_disks_count;
if (no == pno) {
- if (qual < 2) {
- pno = (pno + 1) % vol->v_disks_count;
- no = (no + 2) % vol->v_disks_count;
- } else if (pno == 0)
- pno = vol->v_disks_count - 1;
- else
- pno--;
+ if ((--pleft) <= 0) {
+ pleft += protate;
+ if (qual < 2) /* P0/Right */
+ pno++;
+ else /* PN/Left */
+ pno += vol->v_disks_count - 1;
+ pno %= vol->v_disks_count;
+ }
+ no = (pno + pdisks) % vol->v_disks_count;
offset += strip_size;
}
- } else {
+ } else { /* Restart/Asymmetric */
if (no == pno)
- no++;
+ no += pdisks;
if (no >= vol->v_disks_count) {
- no %= vol->v_disks_count;
- if (qual < 2)
- pno = (pno + 1) % vol->v_disks_count;
- else if (pno == 0)
- pno = vol->v_disks_count - 1;
+ no -= vol->v_disks_count;
+ if ((--pleft) <= 0) {
+ pleft += protate;
+ if (qual < 2) /* P0/Right */
+ pno++;
+ else /* PN/Left */
+ pno += vol->v_disks_count - 1;
+ pno %= vol->v_disks_count;
+ }
+ if (no == pno)
+ no += pdisks;
else
- pno--;
+ no += imax(0, pno + pdisks - vol->v_disks_count);
offset += strip_size;
}
- if (no == pno)
- no++;
}
remain -= length;
addr += length;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/uncompress/g_uncompress.c
--- a/head/sys/geom/uncompress/g_uncompress.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/uncompress/g_uncompress.c Wed Jul 25 16:45:04 2012 +0300
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/uncompress/g_uncompress.c 229537 2012-01-04 23:39:11Z ray $");
+__FBSDID("$FreeBSD: head/sys/geom/uncompress/g_uncompress.c 238198 2012-07-07 17:09:44Z trasz $");
#include <sys/param.h>
#include <sys/bio.h>
@@ -406,13 +406,11 @@
g_trace(G_T_TOPOLOGY, "%s(%p/%s)", __func__, cp,
cp->provider->name);
g_topology_assert();
- KASSERT(cp->provider->error != 0,
- ("g_uncompress_orphan with error == 0"));
gp = cp->geom;
g_uncompress_softc_free(gp->softc, gp);
gp->softc = NULL;
- g_wither_geom(gp, cp->provider->error);
+ g_wither_geom(gp, ENXIO);
}
static int
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/geom/uzip/g_uzip.c
--- a/head/sys/geom/uzip/g_uzip.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/geom/uzip/g_uzip.c Wed Jul 25 16:45:04 2012 +0300
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/uzip/g_uzip.c 227293 2011-11-07 06:44:47Z ed $");
+__FBSDID("$FreeBSD: head/sys/geom/uzip/g_uzip.c 238198 2012-07-07 17:09:44Z trasz $");
#include <sys/param.h>
#include <sys/bio.h>
@@ -313,13 +313,11 @@
g_trace(G_T_TOPOLOGY, "g_uzip_orphan(%p/%s)", cp, cp->provider->name);
g_topology_assert();
- KASSERT(cp->provider->error != 0,
- ("g_uzip_orphan with error == 0"));
gp = cp->geom;
g_uzip_softc_free(gp->softc, gp);
gp->softc = NULL;
- g_wither_geom(gp, cp->provider->error);
+ g_wither_geom(gp, ENXIO);
}
static int
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/gnu/fs/reiserfs/reiserfs_inode.c
--- a/head/sys/gnu/fs/reiserfs/reiserfs_inode.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/gnu/fs/reiserfs/reiserfs_inode.c Wed Jul 25 16:45:04 2012 +0300
@@ -4,7 +4,7 @@
*
* Ported to FreeBSD by Jean-Sébastien Pédron <dumbbell at FreeBSD.org>
*
- * $FreeBSD: head/sys/gnu/fs/reiserfs/reiserfs_inode.c 230132 2012-01-15 13:23:18Z uqs $
+ * $FreeBSD: head/sys/gnu/fs/reiserfs/reiserfs_inode.c 234607 2012-04-23 14:10:34Z trasz $
*/
#include <gnu/fs/reiserfs/reiserfs_fs.h>
@@ -104,12 +104,10 @@
{
int error;
struct vnode *vp;
- struct thread *td;
struct reiserfs_node *ip;
error = 0;
vp = ap->a_vp;
- td = ap->a_td;
ip = VTOI(vp);
reiserfs_log(LOG_DEBUG, "deactivating inode used %d times\n",
@@ -129,7 +127,7 @@
*/
if (ip->i_mode == 0) {
reiserfs_log(LOG_DEBUG, "recyling\n");
- vrecycle(vp, td);
+ vrecycle(vp);
}
return (error);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/gnu/fs/xfs/FreeBSD/xfs_buf.c
--- a/head/sys/gnu/fs/xfs/FreeBSD/xfs_buf.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/gnu/fs/xfs/FreeBSD/xfs_buf.c Wed Jul 25 16:45:04 2012 +0300
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/gnu/fs/xfs/FreeBSD/xfs_buf.c 235822 2012-05-23 06:49:50Z delphij $
*/
#include "xfs.h"
@@ -50,8 +50,8 @@
KASSERT((target != NULL), ("got NULL buftarg_t"));
if (bread(target->specvp, blkno, BBTOB(len), NOCRED, &bp)) {
- printf("bread failed specvp %p blkno %qd BBTOB(len) %ld\n",
- target->specvp, blkno, (long)BBTOB(len));
+ printf("bread failed specvp %p blkno %jd BBTOB(len) %ld\n",
+ target->specvp, (intmax_t)blkno, (long)BBTOB(len));
bp = NULL;
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ofed/drivers/infiniband/core/cma.c
--- a/head/sys/ofed/drivers/infiniband/core/cma.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ofed/drivers/infiniband/core/cma.c Wed Jul 25 16:45:04 2012 +0300
@@ -59,10 +59,10 @@
module_param_named(tavor_quirk, tavor_quirk, int, 0644);
MODULE_PARM_DESC(tavor_quirk, "Tavor performance quirk: limit MTU to 1K if > 0");
-int unify_tcp_port_space = 0;
+int unify_tcp_port_space = 1;
module_param(unify_tcp_port_space, int, 0644);
MODULE_PARM_DESC(unify_tcp_port_space, "Unify the host TCP and RDMA port "
- "space allocation (default=0)");
+ "space allocation (default=1)");
#define CMA_CM_RESPONSE_TIMEOUT 20
#define CMA_MAX_CM_RETRIES 15
@@ -1478,6 +1478,7 @@
struct sockaddr_in *sin;
id_priv->cm_id.iw = iw_create_cm_id(id_priv->id.device,
+ id_priv->sock,
iw_conn_req_handler,
id_priv);
if (IS_ERR(id_priv->cm_id.iw))
@@ -2055,7 +2056,16 @@
((struct sockaddr_in6 *) dst_addr)->sin6_scope_id;
}
}
- return rdma_bind_addr(id, src_addr);
+ if (!cma_any_addr(src_addr))
+ return rdma_bind_addr(id, src_addr);
+ else {
+ struct sockaddr_in addr_in;
+
+ memset(&addr_in, 0, sizeof addr_in);
+ addr_in.sin_family = dst_addr->sa_family;
+ addr_in.sin_len = sizeof addr_in;
+ return rdma_bind_addr(id, (struct sockaddr *) &addr_in);
+ }
}
int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
@@ -2247,6 +2257,7 @@
sock_release(sock);
return ret;
}
+
size = ip_addr_size((struct sockaddr *) &id_priv->id.route.addr.src_addr);
ret = sock_getname(sock,
(struct sockaddr *) &id_priv->id.route.addr.src_addr,
@@ -2255,6 +2266,7 @@
sock_release(sock);
return ret;
}
+
id_priv->sock = sock;
return 0;
}
@@ -2604,7 +2616,8 @@
int ret;
struct iw_cm_conn_param iw_param;
- cm_id = iw_create_cm_id(id_priv->id.device, cma_iw_handler, id_priv);
+ cm_id = iw_create_cm_id(id_priv->id.device, id_priv->sock,
+ cma_iw_handler, id_priv);
if (IS_ERR(cm_id)) {
ret = PTR_ERR(cm_id);
goto out;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ofed/drivers/infiniband/core/iwcm.c
--- a/head/sys/ofed/drivers/infiniband/core/iwcm.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ofed/drivers/infiniband/core/iwcm.c Wed Jul 25 16:45:04 2012 +0300
@@ -189,6 +189,7 @@
static int cm_event_handler(struct iw_cm_id *cm_id, struct iw_cm_event *event);
struct iw_cm_id *iw_create_cm_id(struct ib_device *device,
+ struct socket *so,
iw_cm_handler cm_handler,
void *context)
{
@@ -205,6 +206,7 @@
cm_id_priv->id.event_handler = cm_event_handler;
cm_id_priv->id.add_ref = add_ref;
cm_id_priv->id.rem_ref = rem_ref;
+ cm_id_priv->id.so = so;
spin_lock_init(&cm_id_priv->lock);
atomic_set(&cm_id_priv->refcount, 1);
init_waitqueue_head(&cm_id_priv->connect_wait);
@@ -629,6 +631,7 @@
spin_unlock_irqrestore(&listen_id_priv->lock, flags);
cm_id = iw_create_cm_id(listen_id_priv->id.device,
+ iw_event->so,
listen_id_priv->id.cm_handler,
listen_id_priv->id.context);
/* If the cm_id could not be created, ignore the request */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ofed/drivers/net/mlx4/en_netdev.c
--- a/head/sys/ofed/drivers/net/mlx4/en_netdev.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ofed/drivers/net/mlx4/en_netdev.c Wed Jul 25 16:45:04 2012 +0300
@@ -1569,7 +1569,7 @@
dev->if_capabilities |= IFCAP_VLAN_HWCSUM | IFCAP_VLAN_HWFILTER;
dev->if_capabilities |= IFCAP_LINKSTATE | IFCAP_JUMBO_MTU;
if (mdev->LSO_support)
- dev->if_capabilities |= IFCAP_TSO | IFCAP_VLAN_HWTSO;
+ dev->if_capabilities |= IFCAP_TSO4 | IFCAP_VLAN_HWTSO;
if (mdev->profile.num_lro)
dev->if_capabilities |= IFCAP_LRO;
dev->if_capenable = dev->if_capabilities;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ofed/include/linux/net.h
--- a/head/sys/ofed/include/linux/net.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ofed/include/linux/net.h Wed Jul 25 16:45:04 2012 +0300
@@ -48,12 +48,12 @@
int error;
nam = NULL;
- if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0)
- return (-ENOTCONN);
+ if (peer) {
+ if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0)
+ return (-ENOTCONN);
- if (peer)
error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, nam);
- else
+ } else
error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, nam);
if (error)
return (-error);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ofed/include/linux/workqueue.h
--- a/head/sys/ofed/include/linux/workqueue.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ofed/include/linux/workqueue.h Wed Jul 25 16:45:04 2012 +0300
@@ -129,7 +129,7 @@
wq = kmalloc(sizeof(*wq), M_WAITOK);
wq->taskqueue = taskqueue_create((name), M_WAITOK,
taskqueue_thread_enqueue, &wq->taskqueue);
- taskqueue_start_threads(&wq->taskqueue, cpus, PWAIT, (name));
+ taskqueue_start_threads(&wq->taskqueue, cpus, PWAIT, "%s", name);
return (wq);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ofed/include/net/netevent.h
--- a/head/sys/ofed/include/net/netevent.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ofed/include/net/netevent.h Wed Jul 25 16:45:04 2012 +0300
@@ -42,7 +42,7 @@
struct llentry;
static inline void
-_handle_arp_update_event(void *arg, struct llentry *lle)
+_handle_arp_update_event(void *arg, struct llentry *lle, int evt __unused)
{
struct notifier_block *nb;
@@ -54,7 +54,7 @@
register_netevent_notifier(struct notifier_block *nb)
{
nb->tags[NETEVENT_NEIGH_UPDATE] = EVENTHANDLER_REGISTER(
- arp_update_event, _handle_arp_update_event, nb, 0);
+ lle_event, _handle_arp_update_event, nb, 0);
return (0);
}
@@ -62,8 +62,7 @@
unregister_netevent_notifier(struct notifier_block *nb)
{
- EVENTHANDLER_DEREGISTER(arp_update_event,
- nb->tags[NETEVENT_NEIGH_UPDATE]);
+ EVENTHANDLER_DEREGISTER(lle_event, nb->tags[NETEVENT_NEIGH_UPDATE]);
return (0);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ofed/include/rdma/iw_cm.h
--- a/head/sys/ofed/include/rdma/iw_cm.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ofed/include/rdma/iw_cm.h Wed Jul 25 16:45:04 2012 +0300
@@ -63,6 +63,7 @@
void *private_data;
u8 private_data_len;
void *provider_data;
+ struct socket *so;
};
/**
@@ -98,6 +99,7 @@
/* Used by provider to add and remove refs on IW cm_id */
void (*add_ref)(struct iw_cm_id *);
void (*rem_ref)(struct iw_cm_id *);
+ struct socket *so;
};
struct iw_cm_conn_param {
@@ -139,7 +141,7 @@
* returned IW CM identifier.
* @context: User specified context associated with the id.
*/
-struct iw_cm_id *iw_create_cm_id(struct ib_device *device,
+struct iw_cm_id *iw_create_cm_id(struct ib_device *device, struct socket *so,
iw_cm_handler cm_handler, void *context);
/**
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/security/mac_mls/mac_mls.c
--- a/head/sys/security/mac_mls/mac_mls.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/security/mac_mls/mac_mls.c Wed Jul 25 16:45:04 2012 +0300
@@ -38,7 +38,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/security/mac_mls/mac_mls.c 231378 2012-02-10 12:35:57Z ed $
+ * $FreeBSD: head/sys/security/mac_mls/mac_mls.c 234957 2012-05-03 15:51:34Z brueffer $
*/
/*
@@ -2028,6 +2028,9 @@
if (!mls_enabled)
return (0);
+ if (vplabel == NULL)
+ return (0);
+
subj = SLOT(cred->cr_label);
obj = SLOT(vplabel);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ufs/ffs/ffs_alloc.c
--- a/head/sys/ufs/ffs/ffs_alloc.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ufs/ffs/ffs_alloc.c Wed Jul 25 16:45:04 2012 +0300
@@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_alloc.c 229200 2012-01-01 20:47:33Z ed $");
+__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_alloc.c 238029 2012-07-02 21:01:03Z kib $");
#include "opt_quota.h"
@@ -2865,10 +2865,9 @@
if (ip->i_devvp != devvp)
return (EINVAL);
fs = ip->i_fs;
+ foffset_lock_uio(fp, uio, flags);
vfslocked = VFS_LOCK_GIANT(ip->i_vnode->v_mount);
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
- if ((flags & FOF_OFFSET) == 0)
- uio->uio_offset = fp->f_offset;
#ifdef DEBUG
if (fsckcmds) {
printf("%s: buffered write for block %jd\n",
@@ -2893,11 +2892,9 @@
goto out;
}
error = bwrite(bp);
- if ((flags & FOF_OFFSET) == 0)
- fp->f_offset = uio->uio_offset;
- fp->f_nextoff = uio->uio_offset;
out:
VOP_UNLOCK(devvp, 0);
VFS_UNLOCK_GIANT(vfslocked);
+ foffset_unlock_uio(fp, uio, flags | FOF_NEXTOFF);
return (error);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ufs/ffs/ffs_extern.h
--- a/head/sys/ufs/ffs/ffs_extern.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ufs/ffs/ffs_extern.h Wed Jul 25 16:45:04 2012 +0300
@@ -27,7 +27,7 @@
* SUCH DAMAGE.
*
* @(#)ffs_extern.h 8.6 (Berkeley) 3/30/95
- * $FreeBSD: head/sys/ufs/ffs/ffs_extern.h 233438 2012-03-25 00:02:37Z mckusick $
+ * $FreeBSD: head/sys/ufs/ffs/ffs_extern.h 234605 2012-04-23 13:21:28Z trasz $
*/
#ifndef _UFS_FFS_EXTERN_H
@@ -93,7 +93,7 @@
void process_deferred_inactive(struct mount *mp);
void ffs_sync_snap(struct mount *, int);
int ffs_syncvnode(struct vnode *vp, int waitfor, int flags);
-int ffs_truncate(struct vnode *, off_t, int, struct ucred *, struct thread *);
+int ffs_truncate(struct vnode *, off_t, int, struct ucred *);
int ffs_update(struct vnode *, int);
int ffs_valloc(struct vnode *, int, struct ucred *, struct vnode **);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ufs/ffs/ffs_inode.c
--- a/head/sys/ufs/ffs/ffs_inode.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ufs/ffs/ffs_inode.c Wed Jul 25 16:45:04 2012 +0300
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_inode.c 233629 2012-03-28 21:21:19Z mckusick $");
+__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_inode.c 234605 2012-04-23 13:21:28Z trasz $");
#include "opt_quota.h"
@@ -170,12 +170,11 @@
* disk blocks.
*/
int
-ffs_truncate(vp, length, flags, cred, td)
+ffs_truncate(vp, length, flags, cred)
struct vnode *vp;
off_t length;
int flags;
struct ucred *cred;
- struct thread *td;
{
struct inode *ip;
ufs2_daddr_t bn, lbn, lastblock, lastiblock[NIADDR], indir_lbn[NIADDR];
@@ -449,7 +448,7 @@
ip->i_size = osize;
DIP_SET(ip, i_size, osize);
- error = vtruncbuf(vp, cred, td, length, fs->fs_bsize);
+ error = vtruncbuf(vp, cred, length, fs->fs_bsize);
if (error && (allerror == 0))
allerror = error;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ufs/ffs/ffs_snapshot.c
--- a/head/sys/ufs/ffs/ffs_snapshot.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ufs/ffs/ffs_snapshot.c Wed Jul 25 16:45:04 2012 +0300
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_snapshot.c 234386 2012-04-17 16:28:22Z mckusick $");
+__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_snapshot.c 238697 2012-07-22 15:40:31Z kevlo $");
#include "opt_quota.h"
@@ -850,7 +850,7 @@
mp->mnt_flag = (mp->mnt_flag & MNT_QUOTA) | (flag & ~MNT_QUOTA);
MNT_IUNLOCK(mp);
if (error)
- (void) ffs_truncate(vp, (off_t)0, 0, NOCRED, td);
+ (void) ffs_truncate(vp, (off_t)0, 0, NOCRED);
(void) ffs_syncvnode(vp, MNT_WAIT, 0);
if (error)
vput(vp);
@@ -1742,7 +1742,7 @@
enum vtype vtype;
struct workhead *wkhd;
{
- struct buf *ibp, *cbp, *savedcbp = 0;
+ struct buf *ibp, *cbp, *savedcbp = NULL;
struct thread *td = curthread;
struct inode *ip;
struct vnode *vp = NULL;
@@ -1989,7 +1989,7 @@
reason = "non-snapshot";
} else {
reason = "old format snapshot";
- (void)ffs_truncate(vp, (off_t)0, 0, NOCRED, td);
+ (void)ffs_truncate(vp, (off_t)0, 0, NOCRED);
(void)ffs_syncvnode(vp, MNT_WAIT, 0);
}
printf("ffs_snapshot_mount: %s inode %d\n",
@@ -2236,11 +2236,11 @@
struct buf *bp;
{
struct snapdata *sn;
- struct buf *ibp, *cbp, *savedcbp = 0;
+ struct buf *ibp, *cbp, *savedcbp = NULL;
struct thread *td = curthread;
struct fs *fs;
struct inode *ip;
- struct vnode *vp = 0;
+ struct vnode *vp = NULL;
ufs2_daddr_t lbn, blkno, *snapblklist;
int lower, upper, mid, indiroff, error = 0;
int launched_async_io, prev_norunningbuf;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ufs/ffs/ffs_softdep.c
--- a/head/sys/ufs/ffs/ffs_softdep.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ufs/ffs/ffs_softdep.c Wed Jul 25 16:45:04 2012 +0300
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_softdep.c 234386 2012-04-17 16:28:22Z mckusick $");
+__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_softdep.c 236937 2012-06-11 23:07:21Z mckusick $");
#include "opt_ffs.h"
#include "opt_quota.h"
@@ -773,8 +773,8 @@
static void softdep_error(char *, int);
static void drain_output(struct vnode *);
static struct buf *getdirtybuf(struct buf *, struct mtx *, int);
-static void clear_remove(struct thread *);
-static void clear_inodedeps(struct thread *);
+static void clear_remove(void);
+static void clear_inodedeps(void);
static void unlinked_inodedep(struct mount *, struct inodedep *);
static void clear_unlinked_inodedep(struct inodedep *);
static struct inodedep *first_unlinked_inodedep(struct ufsmount *);
@@ -920,7 +920,7 @@
static int bmsafemap_find(struct bmsafemap_hashhead *, struct mount *, int,
struct bmsafemap **);
static struct bmsafemap *bmsafemap_lookup(struct mount *, struct buf *,
- int cg);
+ int cg, struct bmsafemap *);
static int newblk_find(struct newblk_hashhead *, struct mount *, ufs2_daddr_t,
int, struct newblk **);
static int newblk_lookup(struct mount *, ufs2_daddr_t, int, struct newblk **);
@@ -1351,12 +1351,12 @@
* If requested, try removing inode or removal dependencies.
*/
if (req_clear_inodedeps) {
- clear_inodedeps(td);
+ clear_inodedeps();
req_clear_inodedeps -= 1;
wakeup_one(&proc_waiting);
}
if (req_clear_remove) {
- clear_remove(td);
+ clear_remove();
req_clear_remove -= 1;
wakeup_one(&proc_waiting);
}
@@ -1499,7 +1499,6 @@
struct mount *mp;
int full;
{
- struct thread *td = curthread;
int cnt, matchcnt;
struct ufsmount *ump;
long starttime;
@@ -1523,12 +1522,12 @@
* If requested, try removing inode or removal dependencies.
*/
if (req_clear_inodedeps) {
- clear_inodedeps(td);
+ clear_inodedeps();
req_clear_inodedeps -= 1;
wakeup_one(&proc_waiting);
}
if (req_clear_remove) {
- clear_remove(td);
+ clear_remove();
req_clear_remove -= 1;
wakeup_one(&proc_waiting);
}
@@ -4708,12 +4707,26 @@
* Panic if it already exists as something is seriously wrong.
* Otherwise add it to the dependency list for the buffer holding
* the cylinder group map from which it was allocated.
- */
+ *
+ * We have to preallocate a bmsafemap entry in case it is needed
+ * in bmsafemap_lookup since once we allocate the inodedep, we
+ * have to finish initializing it before we can FREE_LOCK().
+ * By preallocating, we avoid FREE_LOCK() while doing a malloc
+ * in bmsafemap_lookup. We cannot call bmsafemap_lookup before
+ * creating the inodedep as it can be freed during the time
+ * that we FREE_LOCK() while allocating the inodedep. We must
+ * call workitem_alloc() before entering the locked section as
+ * it also acquires the lock and we must avoid trying doing so
+ * recursively.
+ */
+ bmsafemap = malloc(sizeof(struct bmsafemap),
+ M_BMSAFEMAP, M_SOFTDEP_FLAGS);
+ workitem_alloc(&bmsafemap->sm_list, D_BMSAFEMAP, mp);
ACQUIRE_LOCK(&lk);
if ((inodedep_lookup(mp, newinum, DEPALLOC | NODELAY, &inodedep)))
panic("softdep_setup_inomapdep: dependency %p for new"
"inode already exists", inodedep);
- bmsafemap = bmsafemap_lookup(mp, bp, ino_to_cg(fs, newinum));
+ bmsafemap = bmsafemap_lookup(mp, bp, ino_to_cg(fs, newinum), bmsafemap);
if (jaddref) {
LIST_INSERT_HEAD(&bmsafemap->sm_jaddrefhd, jaddref, ja_bmdeps);
TAILQ_INSERT_TAIL(&inodedep->id_inoreflst, &jaddref->ja_ref,
@@ -4787,7 +4800,7 @@
if (newblk_lookup(mp, newblkno, DEPALLOC, &newblk) != 0)
panic("softdep_setup_blkmapdep: found block");
newblk->nb_bmsafemap = bmsafemap = bmsafemap_lookup(mp, bp,
- dtog(fs, newblkno));
+ dtog(fs, newblkno), NULL);
if (jnewblk) {
jnewblk->jn_dep = (struct worklist *)newblk;
LIST_INSERT_HEAD(&bmsafemap->sm_jnewblkhd, jnewblk, jn_deps);
@@ -4828,13 +4841,16 @@
* Find the bmsafemap associated with a cylinder group buffer.
* If none exists, create one. The buffer must be locked when
* this routine is called and this routine must be called with
- * splbio interrupts blocked.
+ * the softdep lock held. To avoid giving up the lock while
+ * allocating a new bmsafemap, a preallocated bmsafemap may be
+ * provided. If it is provided but not needed, it is freed.
*/
static struct bmsafemap *
-bmsafemap_lookup(mp, bp, cg)
+bmsafemap_lookup(mp, bp, cg, newbmsafemap)
struct mount *mp;
struct buf *bp;
int cg;
+ struct bmsafemap *newbmsafemap;
{
struct bmsafemap_hashhead *bmsafemaphd;
struct bmsafemap *bmsafemap, *collision;
@@ -4844,16 +4860,27 @@
mtx_assert(&lk, MA_OWNED);
if (bp)
LIST_FOREACH(wk, &bp->b_dep, wk_list)
- if (wk->wk_type == D_BMSAFEMAP)
+ if (wk->wk_type == D_BMSAFEMAP) {
+ if (newbmsafemap)
+ WORKITEM_FREE(newbmsafemap,D_BMSAFEMAP);
return (WK_BMSAFEMAP(wk));
+ }
fs = VFSTOUFS(mp)->um_fs;
bmsafemaphd = BMSAFEMAP_HASH(fs, cg);
- if (bmsafemap_find(bmsafemaphd, mp, cg, &bmsafemap) == 1)
+ if (bmsafemap_find(bmsafemaphd, mp, cg, &bmsafemap) == 1) {
+ if (newbmsafemap)
+ WORKITEM_FREE(newbmsafemap, D_BMSAFEMAP);
return (bmsafemap);
- FREE_LOCK(&lk);
- bmsafemap = malloc(sizeof(struct bmsafemap),
- M_BMSAFEMAP, M_SOFTDEP_FLAGS);
- workitem_alloc(&bmsafemap->sm_list, D_BMSAFEMAP, mp);
+ }
+ if (newbmsafemap) {
+ bmsafemap = newbmsafemap;
+ } else {
+ FREE_LOCK(&lk);
+ bmsafemap = malloc(sizeof(struct bmsafemap),
+ M_BMSAFEMAP, M_SOFTDEP_FLAGS);
+ workitem_alloc(&bmsafemap->sm_list, D_BMSAFEMAP, mp);
+ ACQUIRE_LOCK(&lk);
+ }
bmsafemap->sm_buf = bp;
LIST_INIT(&bmsafemap->sm_inodedephd);
LIST_INIT(&bmsafemap->sm_inodedepwr);
@@ -4863,7 +4890,6 @@
LIST_INIT(&bmsafemap->sm_jnewblkhd);
LIST_INIT(&bmsafemap->sm_freehd);
LIST_INIT(&bmsafemap->sm_freewr);
- ACQUIRE_LOCK(&lk);
if (bmsafemap_find(bmsafemaphd, mp, cg, &collision) == 1) {
WORKITEM_FREE(bmsafemap, D_BMSAFEMAP);
return (collision);
@@ -10222,7 +10248,7 @@
ACQUIRE_LOCK(&lk);
/* Lookup the bmsafemap so we track when it is dirty. */
fs = VFSTOUFS(mp)->um_fs;
- bmsafemap = bmsafemap_lookup(mp, bp, dtog(fs, blkno));
+ bmsafemap = bmsafemap_lookup(mp, bp, dtog(fs, blkno), NULL);
/*
* Detach any jnewblks which have been canceled. They must linger
* until the bitmap is cleared again by ffs_blkfree() to prevent
@@ -10268,7 +10294,7 @@
* allocation dependency.
*/
fs = VFSTOUFS(mp)->um_fs;
- bmsafemap = bmsafemap_lookup(mp, bp, dtog(fs, blkno));
+ bmsafemap = bmsafemap_lookup(mp, bp, dtog(fs, blkno), NULL);
end = blkno + frags;
LIST_FOREACH(jnewblk, &bmsafemap->sm_jnewblkhd, jn_deps) {
/*
@@ -10688,6 +10714,7 @@
case D_FREEFRAG:
rele_jseg(WK_JSEG(WK_FREEFRAG(wk)->ff_jdep));
WORKITEM_FREE(wk, D_FREEFRAG);
+ continue;
case D_FREEWORK:
handle_written_freework(WK_FREEWORK(wk));
continue;
@@ -12785,8 +12812,7 @@
* reduce the number of dirrem, freefile, and freeblks dependency structures.
*/
static void
-clear_remove(td)
- struct thread *td;
+clear_remove(void)
{
struct pagedep_hashhead *pagedephd;
struct pagedep *pagedep;
@@ -12845,8 +12871,7 @@
* the number of inodedep dependency structures.
*/
static void
-clear_inodedeps(td)
- struct thread *td;
+clear_inodedeps(void)
{
struct inodedep_hashhead *inodedephd;
struct inodedep *inodedep;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ufs/ffs/ffs_vfsops.c
--- a/head/sys/ufs/ffs/ffs_vfsops.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ufs/ffs/ffs_vfsops.c Wed Jul 25 16:45:04 2012 +0300
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_vfsops.c 234537 2012-04-21 10:45:46Z trasz $");
+__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_vfsops.c 238697 2012-07-22 15:40:31Z kevlo $");
#include "opt_quota.h"
#include "opt_ufs.h"
@@ -142,7 +142,7 @@
{
struct vnode *devvp;
struct thread *td;
- struct ufsmount *ump = 0;
+ struct ufsmount *ump = NULL;
struct fs *fs;
pid_t fsckpid = 0;
int error, flags;
@@ -1064,7 +1064,7 @@
*/
MNT_ILOCK(mp);
mp->mnt_kern_flag |= MNTK_MPSAFE | MNTK_LOOKUP_SHARED |
- MNTK_EXTENDED_SHARED;
+ MNTK_EXTENDED_SHARED | MNTK_NO_IOPF;
MNT_IUNLOCK(mp);
#ifdef UFS_EXTATTR
#ifdef UFS_EXTATTR_AUTOSTART
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ufs/ffs/ffs_vnops.c
--- a/head/sys/ufs/ffs/ffs_vnops.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ufs/ffs/ffs_vnops.c Wed Jul 25 16:45:04 2012 +0300
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_vnops.c 233438 2012-03-25 00:02:37Z mckusick $");
+__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_vnops.c 237366 2012-06-21 09:20:07Z kib $");
#include <sys/param.h>
#include <sys/bio.h>
@@ -567,7 +567,7 @@
xfersize = size;
}
- error = uiomove((char *)bp->b_data + blkoffset,
+ error = vn_io_fault_uiomove((char *)bp->b_data + blkoffset,
(int)xfersize, uio);
if (error)
break;
@@ -738,8 +738,8 @@
if (size < xfersize)
xfersize = size;
- error =
- uiomove((char *)bp->b_data + blkoffset, (int)xfersize, uio);
+ error = vn_io_fault_uiomove((char *)bp->b_data + blkoffset,
+ (int)xfersize, uio);
/*
* If the buffer is not already filled and we encounter an
* error while trying to fill it, we have to clear out any
@@ -812,8 +812,7 @@
if (error) {
if (ioflag & IO_UNIT) {
(void)ffs_truncate(vp, osize,
- IO_NORMAL | (ioflag & IO_SYNC),
- ap->a_cred, uio->uio_td);
+ IO_NORMAL | (ioflag & IO_SYNC), ap->a_cred);
uio->uio_offset -= resid - uio->uio_resid;
uio->uio_resid = resid;
}
@@ -1135,7 +1134,7 @@
if (error) {
if (ioflag & IO_UNIT) {
(void)ffs_truncate(vp, osize,
- IO_EXT | (ioflag&IO_SYNC), ucred, uio->uio_td);
+ IO_EXT | (ioflag&IO_SYNC), ucred);
uio->uio_offset -= resid - uio->uio_resid;
uio->uio_resid = resid;
}
@@ -1326,7 +1325,7 @@
luio.uio_td = td;
/* XXX: I'm not happy about truncating to zero size */
if (ip->i_ea_len < dp->di_extsize)
- error = ffs_truncate(vp, 0, IO_EXT, cred, td);
+ error = ffs_truncate(vp, 0, IO_EXT, cred);
error = ffs_extwrite(vp, &luio, IO_EXT | IO_SYNC, cred);
}
if (--ip->i_ea_refs == 0) {
@@ -1649,7 +1648,8 @@
struct inode *ip;
struct fs *fs;
uint32_t ealength, ul;
- int ealen, olen, eapad1, eapad2, error, i, easize;
+ ssize_t ealen;
+ int olen, eapad1, eapad2, error, i, easize;
u_char *eae, *p;
ip = VTOI(ap->a_vp);
@@ -1668,6 +1668,10 @@
if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
+ ealen = ap->a_uio->uio_resid;
+ if (ealen < 0 || ealen > lblktosize(fs, NXADDR))
+ return (EINVAL);
+
error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace,
ap->a_cred, ap->a_td, VWRITE);
if (error) {
@@ -1685,7 +1689,6 @@
if (error)
return (error);
- ealen = ap->a_uio->uio_resid;
ealength = sizeof(uint32_t) + 3 + strlen(ap->a_name);
eapad1 = 8 - (ealength % 8);
if (eapad1 == 8)
@@ -1713,7 +1716,7 @@
easize += (ealength - ul);
}
}
- if (easize > NXADDR * fs->fs_bsize) {
+ if (easize > lblktosize(fs, NXADDR)) {
free(eae, M_TEMP);
ffs_close_ea(ap->a_vp, 0, ap->a_cred, ap->a_td);
if (ip->i_ea_area != NULL && ip->i_ea_error == 0)
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ufs/ufs/ufs_extattr.c
--- a/head/sys/ufs/ufs/ufs_extattr.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ufs/ufs/ufs_extattr.c Wed Jul 25 16:45:04 2012 +0300
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/ufs/ufs/ufs_extattr.c 232701 2012-03-08 20:27:20Z jhb $");
+__FBSDID("$FreeBSD: head/sys/ufs/ufs/ufs_extattr.c 234613 2012-04-23 17:56:35Z trasz $");
#include "opt_ufs.h"
@@ -108,14 +108,14 @@
* backing file anyway.
*/
static void
-ufs_extattr_uepm_lock(struct ufsmount *ump, struct thread *td)
+ufs_extattr_uepm_lock(struct ufsmount *ump)
{
sx_xlock(&ump->um_extattr.uepm_lock);
}
static void
-ufs_extattr_uepm_unlock(struct ufsmount *ump, struct thread *td)
+ufs_extattr_uepm_unlock(struct ufsmount *ump)
{
sx_xunlock(&ump->um_extattr.uepm_lock);
@@ -213,9 +213,9 @@
ump = VFSTOUFS(mp);
- ufs_extattr_uepm_lock(ump, td);
+ ufs_extattr_uepm_lock(ump);
error = ufs_extattr_start_locked(ump, td);
- ufs_extattr_uepm_unlock(ump, td);
+ ufs_extattr_uepm_unlock(ump);
return (error);
}
@@ -458,9 +458,9 @@
int error;
ump = VFSTOUFS(mp);
- ufs_extattr_uepm_lock(ump, td);
+ ufs_extattr_uepm_lock(ump);
error = ufs_extattr_autostart_locked(mp, td);
- ufs_extattr_uepm_unlock(ump, td);
+ ufs_extattr_uepm_unlock(ump);
return (error);
}
@@ -566,7 +566,7 @@
struct ufsmount *ump = VFSTOUFS(mp);
int error = 0;
- ufs_extattr_uepm_lock(ump, td);
+ ufs_extattr_uepm_lock(ump);
if (!(ump->um_extattr.uepm_flags & UFS_EXTATTR_UEPM_STARTED)) {
error = EOPNOTSUPP;
@@ -584,7 +584,7 @@
ump->um_extattr.uepm_ucred = NULL;
unlock:
- ufs_extattr_uepm_unlock(ump, td);
+ ufs_extattr_uepm_unlock(ump);
return (error);
}
@@ -783,10 +783,10 @@
* ufs_extattr_enable_with_open() will always unlock the
* vnode, regardless of failure.
*/
- ufs_extattr_uepm_lock(ump, td);
+ ufs_extattr_uepm_lock(ump);
error = ufs_extattr_enable_with_open(ump, filename_vp,
attrnamespace, attrname, td);
- ufs_extattr_uepm_unlock(ump, td);
+ ufs_extattr_uepm_unlock(ump);
return (error);
@@ -799,10 +799,10 @@
if (attrname == NULL)
return (EINVAL);
- ufs_extattr_uepm_lock(ump, td);
+ ufs_extattr_uepm_lock(ump);
error = ufs_extattr_disable(ump, attrnamespace, attrname,
td);
- ufs_extattr_uepm_unlock(ump, td);
+ ufs_extattr_uepm_unlock(ump);
return (error);
@@ -832,12 +832,12 @@
struct ufsmount *ump = VFSTOUFS(mp);
int error;
- ufs_extattr_uepm_lock(ump, ap->a_td);
+ ufs_extattr_uepm_lock(ump);
error = ufs_extattr_get(ap->a_vp, ap->a_attrnamespace, ap->a_name,
ap->a_uio, ap->a_size, ap->a_cred, ap->a_td);
- ufs_extattr_uepm_unlock(ump, ap->a_td);
+ ufs_extattr_uepm_unlock(ump);
return (error);
}
@@ -1002,13 +1002,13 @@
struct ufsmount *ump = VFSTOUFS(mp);
int error;
- ufs_extattr_uepm_lock(ump, ap->a_td);
+ ufs_extattr_uepm_lock(ump);
error = ufs_extattr_rm(ap->a_vp, ap->a_attrnamespace, ap->a_name,
ap->a_cred, ap->a_td);
- ufs_extattr_uepm_unlock(ump, ap->a_td);
+ ufs_extattr_uepm_unlock(ump);
return (error);
}
@@ -1039,12 +1039,12 @@
if (ap->a_uio == NULL)
return (EINVAL);
- ufs_extattr_uepm_lock(ump, ap->a_td);
+ ufs_extattr_uepm_lock(ump);
error = ufs_extattr_set(ap->a_vp, ap->a_attrnamespace, ap->a_name,
ap->a_uio, ap->a_cred, ap->a_td);
- ufs_extattr_uepm_unlock(ump, ap->a_td);
+ ufs_extattr_uepm_unlock(ump);
return (error);
}
@@ -1295,10 +1295,10 @@
if (!(ump->um_extattr.uepm_flags & UFS_EXTATTR_UEPM_INITIALIZED))
return;
- ufs_extattr_uepm_lock(ump, td);
+ ufs_extattr_uepm_lock(ump);
if (!(ump->um_extattr.uepm_flags & UFS_EXTATTR_UEPM_STARTED)) {
- ufs_extattr_uepm_unlock(ump, td);
+ ufs_extattr_uepm_unlock(ump);
return;
}
@@ -1306,7 +1306,7 @@
ufs_extattr_rm(vp, uele->uele_attrnamespace,
uele->uele_attrname, NULL, td);
- ufs_extattr_uepm_unlock(ump, td);
+ ufs_extattr_uepm_unlock(ump);
}
#endif /* !UFS_EXTATTR */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ufs/ufs/ufs_inode.c
--- a/head/sys/ufs/ufs/ufs_inode.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ufs/ufs/ufs_inode.c Wed Jul 25 16:45:04 2012 +0300
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/ufs/ufs/ufs_inode.c 234483 2012-04-20 07:00:28Z mckusick $");
+__FBSDID("$FreeBSD: head/sys/ufs/ufs/ufs_inode.c 234612 2012-04-23 17:54:49Z trasz $");
#include "opt_quota.h"
#include "opt_ufs.h"
@@ -73,7 +73,6 @@
{
struct vnode *vp = ap->a_vp;
struct inode *ip = VTOI(vp);
- struct thread *td = ap->a_td;
mode_t mode;
int error = 0;
off_t isize;
@@ -129,15 +128,14 @@
if (ip->i_ump->um_fstype == UFS2)
isize += ip->i_din2->di_extsize;
if (ip->i_effnlink <= 0 && isize && !UFS_RDONLY(ip))
- error = UFS_TRUNCATE(vp, (off_t)0, IO_EXT | IO_NORMAL,
- NOCRED, td);
+ error = UFS_TRUNCATE(vp, (off_t)0, IO_EXT | IO_NORMAL, NOCRED);
if (ip->i_nlink <= 0 && ip->i_mode && !UFS_RDONLY(ip)) {
#ifdef QUOTA
if (!getinoquota(ip))
(void)chkiq(ip, -1, NOCRED, FORCE);
#endif
#ifdef UFS_EXTATTR
- ufs_extattr_vnode_inactive(vp, td);
+ ufs_extattr_vnode_inactive(vp, ap->a_td);
#endif
/*
* Setting the mode to zero needs to wait for the inode
@@ -173,7 +171,7 @@
* so that it can be reused immediately.
*/
if (ip->i_mode == 0)
- vrecycle(vp, td);
+ vrecycle(vp);
if (mp != NULL)
vn_finished_secondary_write(mp);
return (error);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ufs/ufs/ufs_lookup.c
--- a/head/sys/ufs/ufs/ufs_lookup.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ufs/ufs/ufs_lookup.c Wed Jul 25 16:45:04 2012 +0300
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/ufs/ufs/ufs_lookup.c 231949 2012-02-21 01:05:12Z kib $");
+__FBSDID("$FreeBSD: head/sys/ufs/ufs/ufs_lookup.c 234605 2012-04-23 13:21:28Z trasz $");
#include "opt_ufs.h"
#include "opt_quota.h"
@@ -1133,7 +1133,7 @@
ufsdirhash_dirtrunc(dp, dp->i_endoff);
#endif
(void) UFS_TRUNCATE(dvp, (off_t)dp->i_endoff,
- IO_NORMAL | IO_SYNC, cr, td);
+ IO_NORMAL | IO_SYNC, cr);
if (tvp != NULL)
vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ufs/ufs/ufs_vnops.c
--- a/head/sys/ufs/ufs/ufs_vnops.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ufs/ufs/ufs_vnops.c Wed Jul 25 16:45:04 2012 +0300
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/ufs/ufs/ufs_vnops.c 234421 2012-04-18 15:19:00Z jh $");
+__FBSDID("$FreeBSD: head/sys/ufs/ufs/ufs_vnops.c 236044 2012-05-26 05:29:53Z kib $");
#include "opt_quota.h"
#include "opt_suiddir.h"
@@ -48,6 +48,7 @@
#include <sys/namei.h>
#include <sys/kernel.h>
#include <sys/fcntl.h>
+#include <sys/filio.h>
#include <sys/stat.h>
#include <sys/bio.h>
#include <sys/buf.h>
@@ -102,6 +103,7 @@
static vop_close_t ufs_close;
static vop_create_t ufs_create;
static vop_getattr_t ufs_getattr;
+static vop_ioctl_t ufs_ioctl;
static vop_link_t ufs_link;
static int ufs_makeinode(int mode, struct vnode *, struct vnode **, struct componentname *);
static vop_markatime_t ufs_markatime;
@@ -621,7 +623,7 @@
return (0);
}
if ((error = UFS_TRUNCATE(vp, vap->va_size, IO_NORMAL,
- cred, td)) != 0)
+ cred)) != 0)
return (error);
}
if (vap->va_atime.tv_sec != VNOVAL ||
@@ -1567,8 +1569,7 @@
if (tdp->i_dirhash != NULL)
ufsdirhash_dirtrunc(tdp, endoff);
#endif
- UFS_TRUNCATE(tdvp, endoff, IO_NORMAL | IO_SYNC, tcnp->cn_cred,
- td);
+ UFS_TRUNCATE(tdvp, endoff, IO_NORMAL | IO_SYNC, tcnp->cn_cred);
}
if (error == 0 && tdp->i_flag & IN_NEEDSYNC)
error = VOP_FSYNC(tdvp, MNT_WAIT, td);
@@ -2505,6 +2506,9 @@
*ap->a_retval = 0;
#endif
break;
+ case _PC_MIN_HOLE_SIZE:
+ *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize;
+ break;
case _PC_ASYNC_IO:
/* _PC_ASYNC_IO should have been handled by upper layers. */
KASSERT(0, ("_PC_ASYNC_IO should not get here"));
@@ -2738,6 +2742,20 @@
return (error);
}
+static int
+ufs_ioctl(struct vop_ioctl_args *ap)
+{
+
+ switch (ap->a_command) {
+ case FIOSEEKDATA:
+ case FIOSEEKHOLE:
+ return (vn_bmap_seekhole(ap->a_vp, ap->a_command,
+ (off_t *)ap->a_data, ap->a_cred));
+ default:
+ return (ENOTTY);
+ }
+}
+
/* Global vfs data structures for ufs. */
struct vop_vector ufs_vnodeops = {
.vop_default = &default_vnodeops,
@@ -2752,6 +2770,7 @@
.vop_create = ufs_create,
.vop_getattr = ufs_getattr,
.vop_inactive = ufs_inactive,
+ .vop_ioctl = ufs_ioctl,
.vop_link = ufs_link,
.vop_lookup = vfs_cache_lookup,
.vop_markatime = ufs_markatime,
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/ufs/ufs/ufsmount.h
--- a/head/sys/ufs/ufs/ufsmount.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/ufs/ufs/ufsmount.h Wed Jul 25 16:45:04 2012 +0300
@@ -27,7 +27,7 @@
* SUCH DAMAGE.
*
* @(#)ufsmount.h 8.6 (Berkeley) 3/30/95
- * $FreeBSD: head/sys/ufs/ufs/ufsmount.h 224061 2011-07-15 16:20:33Z mckusick $
+ * $FreeBSD: head/sys/ufs/ufs/ufsmount.h 234605 2012-04-23 13:21:28Z trasz $
*/
#ifndef _UFS_UFS_UFSMOUNT_H_
@@ -100,7 +100,7 @@
int um_candelete; /* devvp supports TRIM */
int (*um_balloc)(struct vnode *, off_t, int, struct ucred *, int, struct buf **);
int (*um_blkatoff)(struct vnode *, off_t, char **, struct buf **);
- int (*um_truncate)(struct vnode *, off_t, int, struct ucred *, struct thread *);
+ int (*um_truncate)(struct vnode *, off_t, int, struct ucred *);
int (*um_update)(struct vnode *, int);
int (*um_valloc)(struct vnode *, int, struct ucred *, struct vnode **);
int (*um_vfree)(struct vnode *, ino_t, int);
@@ -111,7 +111,7 @@
#define UFS_BALLOC(aa, bb, cc, dd, ee, ff) VFSTOUFS((aa)->v_mount)->um_balloc(aa, bb, cc, dd, ee, ff)
#define UFS_BLKATOFF(aa, bb, cc, dd) VFSTOUFS((aa)->v_mount)->um_blkatoff(aa, bb, cc, dd)
-#define UFS_TRUNCATE(aa, bb, cc, dd, ee) VFSTOUFS((aa)->v_mount)->um_truncate(aa, bb, cc, dd, ee)
+#define UFS_TRUNCATE(aa, bb, cc, dd) VFSTOUFS((aa)->v_mount)->um_truncate(aa, bb, cc, dd)
#define UFS_UPDATE(aa, bb) VFSTOUFS((aa)->v_mount)->um_update(aa, bb)
#define UFS_VALLOC(aa, bb, cc, dd) VFSTOUFS((aa)->v_mount)->um_valloc(aa, bb, cc, dd)
#define UFS_VFREE(aa, bb, cc) VFSTOUFS((aa)->v_mount)->um_vfree(aa, bb, cc)
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/device_pager.c
--- a/head/sys/vm/device_pager.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/device_pager.c Wed Jul 25 16:45:04 2012 +0300
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/vm/device_pager.c 227530 2011-11-15 14:40:00Z kib $");
+__FBSDID("$FreeBSD: head/sys/vm/device_pager.c 235603 2012-05-18 10:23:47Z kib $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -61,6 +61,7 @@
boolean_t, int *);
static boolean_t dev_pager_haspage(vm_object_t, vm_pindex_t, int *,
int *);
+static void dev_pager_free_page(vm_object_t object, vm_page_t m);
/* list of device pager objects */
static struct pagerlst dev_pager_object_list;
@@ -76,6 +77,14 @@
.pgo_haspage = dev_pager_haspage,
};
+struct pagerops mgtdevicepagerops = {
+ .pgo_alloc = dev_pager_alloc,
+ .pgo_dealloc = dev_pager_dealloc,
+ .pgo_getpages = dev_pager_getpages,
+ .pgo_putpages = dev_pager_putpages,
+ .pgo_haspage = dev_pager_haspage,
+};
+
static int old_dev_pager_ctor(void *handle, vm_ooffset_t size, vm_prot_t prot,
vm_ooffset_t foff, struct ucred *cred, u_short *color);
static void old_dev_pager_dtor(void *handle);
@@ -102,7 +111,6 @@
mtx_lock(&dev_pager_mtx);
object = vm_pager_object_lookup(&dev_pager_object_list, handle);
- vm_object_reference(object);
mtx_unlock(&dev_pager_mtx);
return (object);
}
@@ -115,7 +123,7 @@
vm_pindex_t pindex;
u_short color;
- if (tp != OBJT_DEVICE)
+ if (tp != OBJT_DEVICE && tp != OBJT_MGTDEVICE)
return (NULL);
/*
@@ -196,6 +204,24 @@
{
VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
+ if (object->type == OBJT_MGTDEVICE) {
+ KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("unmanaged %p", m));
+ pmap_remove_all(m);
+ vm_page_lock(m);
+ vm_page_remove(m);
+ vm_page_unlock(m);
+ } else if (object->type == OBJT_DEVICE)
+ dev_pager_free_page(object, m);
+}
+
+static void
+dev_pager_free_page(vm_object_t object, vm_page_t m)
+{
+
+ VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
+ KASSERT((object->type == OBJT_DEVICE &&
+ (m->oflags & VPO_UNMANAGED) != 0),
+ ("Managed device or page obj %p m %p", object, m));
TAILQ_REMOVE(&object->un_pager.devp.devp_pglist, m, pageq);
vm_page_putfake(m);
}
@@ -213,11 +239,15 @@
TAILQ_REMOVE(&dev_pager_object_list, object, pager_object_list);
mtx_unlock(&dev_pager_mtx);
VM_OBJECT_LOCK(object);
- /*
- * Free up our fake pages.
- */
- while ((m = TAILQ_FIRST(&object->un_pager.devp.devp_pglist)) != NULL)
- cdev_pager_free_page(object, m);
+
+ if (object->type == OBJT_DEVICE) {
+ /*
+ * Free up our fake pages.
+ */
+ while ((m = TAILQ_FIRST(&object->un_pager.devp.devp_pglist))
+ != NULL)
+ dev_pager_free_page(object, m);
+ }
}
static int
@@ -240,8 +270,15 @@
}
if (error == VM_PAGER_OK) {
- TAILQ_INSERT_TAIL(&object->un_pager.devp.devp_pglist,
- ma[reqpage], pageq);
+ KASSERT((object->type == OBJT_DEVICE &&
+ (ma[reqpage]->oflags & VPO_UNMANAGED) != 0) ||
+ (object->type == OBJT_MGTDEVICE &&
+ (ma[reqpage]->oflags & VPO_UNMANAGED) == 0),
+ ("Wrong page type %p %p", ma[reqpage], object));
+ if (object->type == OBJT_DEVICE) {
+ TAILQ_INSERT_TAIL(&object->un_pager.devp.devp_pglist,
+ ma[reqpage], pageq);
+ }
}
return (error);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/memguard.c
--- a/head/sys/vm/memguard.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/memguard.c Wed Jul 25 16:45:04 2012 +0300
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/vm/memguard.c 227309 2011-11-07 15:43:11Z ed $");
+__FBSDID("$FreeBSD: head/sys/vm/memguard.c 238502 2012-07-15 20:29:48Z mdf $");
/*
* MemGuard is a simple replacement allocator for debugging only
@@ -159,16 +159,18 @@
* the kmem_map. The memguard memory will be a submap.
*/
unsigned long
-memguard_fudge(unsigned long km_size, unsigned long km_max)
+memguard_fudge(unsigned long km_size, const struct vm_map *parent_map)
{
- u_long mem_pgs = cnt.v_page_count;
+ u_long mem_pgs, parent_size;
vm_memguard_divisor = 10;
TUNABLE_INT_FETCH("vm.memguard.divisor", &vm_memguard_divisor);
+ parent_size = vm_map_max(parent_map) - vm_map_min(parent_map) +
+ PAGE_SIZE;
/* Pick a conservative value if provided value sucks. */
if ((vm_memguard_divisor <= 0) ||
- ((km_size / vm_memguard_divisor) == 0))
+ ((parent_size / vm_memguard_divisor) == 0))
vm_memguard_divisor = 10;
/*
* Limit consumption of physical pages to
@@ -177,21 +179,19 @@
* This prevents memguard's page promotions from completely
* using up memory, since most malloc(9) calls are sub-page.
*/
+ mem_pgs = cnt.v_page_count;
memguard_physlimit = (mem_pgs / vm_memguard_divisor) * PAGE_SIZE;
/*
* We want as much KVA as we can take safely. Use at most our
- * allotted fraction of kmem_max. Limit this to twice the
- * physical memory to avoid using too much memory as pagetable
- * pages.
+ * allotted fraction of the parent map's size. Limit this to
+ * twice the physical memory to avoid using too much memory as
+ * pagetable pages (size must be multiple of PAGE_SIZE).
*/
- memguard_mapsize = km_max / vm_memguard_divisor;
- /* size must be multiple of PAGE_SIZE */
- memguard_mapsize = round_page(memguard_mapsize);
- if (memguard_mapsize == 0 ||
- memguard_mapsize / (2 * PAGE_SIZE) > mem_pgs)
+ memguard_mapsize = round_page(parent_size / vm_memguard_divisor);
+ if (memguard_mapsize / (2 * PAGE_SIZE) > mem_pgs)
memguard_mapsize = mem_pgs * 2 * PAGE_SIZE;
- if (km_max > 0 && km_size + memguard_mapsize > km_max)
- return (km_max);
+ if (km_size + memguard_mapsize > parent_size)
+ memguard_mapsize = 0;
return (km_size + memguard_mapsize);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/memguard.h
--- a/head/sys/vm/memguard.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/memguard.h Wed Jul 25 16:45:04 2012 +0300
@@ -23,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: head/sys/vm/memguard.h 226313 2011-10-12 18:08:28Z glebius $
+ * $FreeBSD: head/sys/vm/memguard.h 238502 2012-07-15 20:29:48Z mdf $
*/
#ifndef _VM_MEMGUARD_H_
@@ -35,7 +35,7 @@
struct vm_map;
#ifdef DEBUG_MEMGUARD
-unsigned long memguard_fudge(unsigned long, unsigned long);
+unsigned long memguard_fudge(unsigned long, const struct vm_map *);
void memguard_init(struct vm_map *);
void *memguard_alloc(unsigned long, int);
void *memguard_realloc(void *, unsigned long, struct malloc_type *, int);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/pmap.h
--- a/head/sys/vm/pmap.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/pmap.h Wed Jul 25 16:45:04 2012 +0300
@@ -57,7 +57,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/vm/pmap.h 237168 2012-06-16 18:56:19Z alc $
*/
/*
@@ -80,10 +80,11 @@
typedef struct pmap_statistics *pmap_statistics_t;
/*
- * Each machine dependent implementation is expected to provide:
+ * Each machine-dependent implementation is required to provide:
*
* vm_memattr_t pmap_page_get_memattr(vm_page_t);
* boolean_t pmap_page_is_mapped(vm_page_t);
+ * boolean_t pmap_page_is_write_mapped(vm_page_t);
* void pmap_page_set_memattr(vm_page_t, vm_memattr_t);
*/
#include <machine/pmap.h>
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/swap_pager.c
--- a/head/sys/vm/swap_pager.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/swap_pager.c Wed Jul 25 16:45:04 2012 +0300
@@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/vm/swap_pager.c 231378 2012-02-10 12:35:57Z ed $");
+__FBSDID("$FreeBSD: head/sys/vm/swap_pager.c 237168 2012-06-16 18:56:19Z alc $");
#include "opt_swap.h"
#include "opt_vm.h"
@@ -1593,7 +1593,7 @@
* status, then finish the I/O ( which decrements the
* busy count and possibly wakes waiter's up ).
*/
- KASSERT((m->aflags & PGA_WRITEABLE) == 0,
+ KASSERT(!pmap_page_is_write_mapped(m),
("swp_pager_async_iodone: page %p is not write"
" protected", m));
vm_page_undirty(m);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/uma_core.c
--- a/head/sys/vm/uma_core.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/uma_core.c Wed Jul 25 16:45:04 2012 +0300
@@ -48,7 +48,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/vm/uma_core.c 230623 2012-01-27 20:18:31Z kmacy $");
+__FBSDID("$FreeBSD: head/sys/vm/uma_core.c 238206 2012-07-07 17:46:11Z eadler $");
/* I should really use ktr.. */
/*
@@ -272,10 +272,7 @@
static void
bucket_enable(void)
{
- if (cnt.v_free_count < cnt.v_free_min)
- bucketdisable = 1;
- else
- bucketdisable = 0;
+ bucketdisable = vm_page_count_min();
}
/*
@@ -2196,6 +2193,7 @@
zone->uz_flags |= UMA_ZFLAG_FULL;
if (flags & M_NOWAIT)
break;
+ zone->uz_sleeps++;
msleep(keg, &keg->uk_lock, PVM, "keglimit", 0);
continue;
}
@@ -3384,6 +3382,8 @@
(uintmax_t)kz->uk_size,
(intmax_t)(allocs - frees), cachefree,
(uintmax_t)allocs, sleeps);
+ if (db_pager_quit)
+ return;
}
}
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vm.h
--- a/head/sys/vm/vm.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/vm.h Wed Jul 25 16:45:04 2012 +0300
@@ -55,7 +55,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/vm/vm.h 235375 2012-05-12 20:49:58Z kib $
*/
#ifndef VM_H
@@ -83,7 +83,7 @@
#define VM_PROT_DEFAULT VM_PROT_ALL
enum obj_type { OBJT_DEFAULT, OBJT_SWAP, OBJT_VNODE, OBJT_DEVICE, OBJT_PHYS,
- OBJT_DEAD, OBJT_SG };
+ OBJT_DEAD, OBJT_SG, OBJT_MGTDEVICE };
typedef u_char objtype_t;
union vm_map_object;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vm_contig.c
--- a/head/sys/vm/vm_contig.c Wed Jul 25 16:42:35 2012 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,351 +0,0 @@
-/*-
- * Copyright (c) 1991 Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * The Mach Operating System project at Carnegie-Mellon University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)vm_page.c 7.4 (Berkeley) 5/7/91
- */
-
-/*-
- * Copyright (c) 1987, 1990 Carnegie-Mellon University.
- * All rights reserved.
- *
- * Authors: Avadis Tevanian, Jr., Michael Wayne Young
- *
- * Permission to use, copy, modify and distribute this software and
- * its documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution at CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/vm/vm_contig.c 233100 2012-03-17 23:00:32Z kib $");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/lock.h>
-#include <sys/mount.h>
-#include <sys/mutex.h>
-#include <sys/proc.h>
-#include <sys/kernel.h>
-#include <sys/sysctl.h>
-#include <sys/vmmeter.h>
-#include <sys/vnode.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_kern.h>
-#include <vm/pmap.h>
-#include <vm/vm_map.h>
-#include <vm/vm_object.h>
-#include <vm/vm_page.h>
-#include <vm/vm_pageout.h>
-#include <vm/vm_pager.h>
-#include <vm/vm_extern.h>
-
-static int
-vm_contig_launder_page(vm_page_t m, vm_page_t *next)
-{
- vm_object_t object;
- vm_page_t m_tmp;
- struct vnode *vp;
- struct mount *mp;
- int vfslocked;
-
- mtx_assert(&vm_page_queue_mtx, MA_OWNED);
- vm_page_lock_assert(m, MA_OWNED);
- object = m->object;
- if (!VM_OBJECT_TRYLOCK(object) &&
- (!vm_pageout_fallback_object_lock(m, next) || m->hold_count != 0)) {
- vm_page_unlock(m);
- VM_OBJECT_UNLOCK(object);
- return (EAGAIN);
- }
- if (vm_page_sleep_if_busy(m, TRUE, "vpctw0")) {
- VM_OBJECT_UNLOCK(object);
- vm_page_lock_queues();
- return (EBUSY);
- }
- vm_page_test_dirty(m);
- if (m->dirty == 0)
- pmap_remove_all(m);
- if (m->dirty != 0) {
- vm_page_unlock(m);
- if ((object->flags & OBJ_DEAD) != 0) {
- VM_OBJECT_UNLOCK(object);
- return (EAGAIN);
- }
- if (object->type == OBJT_VNODE) {
- vm_page_unlock_queues();
- vp = object->handle;
- vm_object_reference_locked(object);
- VM_OBJECT_UNLOCK(object);
- (void) vn_start_write(vp, &mp, V_WAIT);
- vfslocked = VFS_LOCK_GIANT(vp->v_mount);
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- VM_OBJECT_LOCK(object);
- vm_object_page_clean(object, 0, 0, OBJPC_SYNC);
- VM_OBJECT_UNLOCK(object);
- VOP_UNLOCK(vp, 0);
- VFS_UNLOCK_GIANT(vfslocked);
- vm_object_deallocate(object);
- vn_finished_write(mp);
- vm_page_lock_queues();
- return (0);
- } else if (object->type == OBJT_SWAP ||
- object->type == OBJT_DEFAULT) {
- vm_page_unlock_queues();
- m_tmp = m;
- vm_pageout_flush(&m_tmp, 1, VM_PAGER_PUT_SYNC, 0,
- NULL, NULL);
- VM_OBJECT_UNLOCK(object);
- vm_page_lock_queues();
- return (0);
- }
- } else {
- vm_page_cache(m);
- vm_page_unlock(m);
- }
- VM_OBJECT_UNLOCK(object);
- return (0);
-}
-
-static int
-vm_contig_launder(int queue, vm_paddr_t low, vm_paddr_t high)
-{
- vm_page_t m, next;
- vm_paddr_t pa;
- int error;
-
- TAILQ_FOREACH_SAFE(m, &vm_page_queues[queue].pl, pageq, next) {
-
- /* Skip marker pages */
- if ((m->flags & PG_MARKER) != 0)
- continue;
-
- pa = VM_PAGE_TO_PHYS(m);
- if (pa < low || pa + PAGE_SIZE > high)
- continue;
-
- if (!vm_pageout_page_lock(m, &next) || m->hold_count != 0) {
- vm_page_unlock(m);
- continue;
- }
- KASSERT(m->queue == queue,
- ("vm_contig_launder: page %p's queue is not %d", m, queue));
- error = vm_contig_launder_page(m, &next);
- vm_page_lock_assert(m, MA_NOTOWNED);
- if (error == 0)
- return (TRUE);
- if (error == EBUSY)
- return (FALSE);
- }
- return (FALSE);
-}
-
-/*
- * Increase the number of cached pages.
- */
-void
-vm_contig_grow_cache(int tries, vm_paddr_t low, vm_paddr_t high)
-{
- int actl, actmax, inactl, inactmax;
-
- vm_page_lock_queues();
- inactl = 0;
- inactmax = tries < 1 ? 0 : cnt.v_inactive_count;
- actl = 0;
- actmax = tries < 2 ? 0 : cnt.v_active_count;
-again:
- if (inactl < inactmax && vm_contig_launder(PQ_INACTIVE, low, high)) {
- inactl++;
- goto again;
- }
- if (actl < actmax && vm_contig_launder(PQ_ACTIVE, low, high)) {
- actl++;
- goto again;
- }
- vm_page_unlock_queues();
-}
-
-/*
- * Allocates a region from the kernel address map and pages within the
- * specified physical address range to the kernel object, creates a wired
- * mapping from the region to these pages, and returns the region's starting
- * virtual address. The allocated pages are not necessarily physically
- * contiguous. If M_ZERO is specified through the given flags, then the pages
- * are zeroed before they are mapped.
- */
-vm_offset_t
-kmem_alloc_attr(vm_map_t map, vm_size_t size, int flags, vm_paddr_t low,
- vm_paddr_t high, vm_memattr_t memattr)
-{
- vm_object_t object = kernel_object;
- vm_offset_t addr;
- vm_ooffset_t end_offset, offset;
- vm_page_t m;
- int pflags, tries;
-
- size = round_page(size);
- vm_map_lock(map);
- if (vm_map_findspace(map, vm_map_min(map), size, &addr)) {
- vm_map_unlock(map);
- return (0);
- }
- offset = addr - VM_MIN_KERNEL_ADDRESS;
- vm_object_reference(object);
- vm_map_insert(map, object, offset, addr, addr + size, VM_PROT_ALL,
- VM_PROT_ALL, 0);
- if ((flags & (M_NOWAIT | M_USE_RESERVE)) == M_NOWAIT)
- pflags = VM_ALLOC_INTERRUPT | VM_ALLOC_NOBUSY;
- else
- pflags = VM_ALLOC_SYSTEM | VM_ALLOC_NOBUSY;
- if (flags & M_ZERO)
- pflags |= VM_ALLOC_ZERO;
- VM_OBJECT_LOCK(object);
- end_offset = offset + size;
- for (; offset < end_offset; offset += PAGE_SIZE) {
- tries = 0;
-retry:
- m = vm_page_alloc_contig(object, OFF_TO_IDX(offset), pflags, 1,
- low, high, PAGE_SIZE, 0, memattr);
- if (m == NULL) {
- VM_OBJECT_UNLOCK(object);
- if (tries < ((flags & M_NOWAIT) != 0 ? 1 : 3)) {
- vm_map_unlock(map);
- vm_contig_grow_cache(tries, low, high);
- vm_map_lock(map);
- VM_OBJECT_LOCK(object);
- tries++;
- goto retry;
- }
- /*
- * Since the pages that were allocated by any previous
- * iterations of this loop are not busy, they can be
- * freed by vm_object_page_remove(), which is called
- * by vm_map_delete().
- */
- vm_map_delete(map, addr, addr + size);
- vm_map_unlock(map);
- return (0);
- }
- if ((flags & M_ZERO) && (m->flags & PG_ZERO) == 0)
- pmap_zero_page(m);
- m->valid = VM_PAGE_BITS_ALL;
- }
- VM_OBJECT_UNLOCK(object);
- vm_map_unlock(map);
- vm_map_wire(map, addr, addr + size, VM_MAP_WIRE_SYSTEM |
- VM_MAP_WIRE_NOHOLES);
- return (addr);
-}
-
-/*
- * Allocates a region from the kernel address map, inserts the
- * given physically contiguous pages into the kernel object,
- * creates a wired mapping from the region to the pages, and
- * returns the region's starting virtual address. If M_ZERO is
- * specified through the given flags, then the pages are zeroed
- * before they are mapped.
- */
-vm_offset_t
-kmem_alloc_contig(vm_map_t map, vm_size_t size, int flags, vm_paddr_t low,
- vm_paddr_t high, u_long alignment, vm_paddr_t boundary,
- vm_memattr_t memattr)
-{
- vm_object_t object = kernel_object;
- vm_offset_t addr;
- vm_ooffset_t offset;
- vm_page_t end_m, m;
- int pflags, tries;
-
- size = round_page(size);
- vm_map_lock(map);
- if (vm_map_findspace(map, vm_map_min(map), size, &addr)) {
- vm_map_unlock(map);
- return (0);
- }
- offset = addr - VM_MIN_KERNEL_ADDRESS;
- vm_object_reference(object);
- vm_map_insert(map, object, offset, addr, addr + size, VM_PROT_ALL,
- VM_PROT_ALL, 0);
- if ((flags & (M_NOWAIT | M_USE_RESERVE)) == M_NOWAIT)
- pflags = VM_ALLOC_INTERRUPT | VM_ALLOC_NOBUSY;
- else
- pflags = VM_ALLOC_SYSTEM | VM_ALLOC_NOBUSY;
- if (flags & M_ZERO)
- pflags |= VM_ALLOC_ZERO;
- if (flags & M_NODUMP)
- pflags |= VM_ALLOC_NODUMP;
- VM_OBJECT_LOCK(object);
- tries = 0;
-retry:
- m = vm_page_alloc_contig(object, OFF_TO_IDX(offset), pflags,
- atop(size), low, high, alignment, boundary, memattr);
- if (m == NULL) {
- VM_OBJECT_UNLOCK(object);
- if (tries < ((flags & M_NOWAIT) != 0 ? 1 : 3)) {
- vm_map_unlock(map);
- vm_contig_grow_cache(tries, low, high);
- vm_map_lock(map);
- VM_OBJECT_LOCK(object);
- tries++;
- goto retry;
- }
- vm_map_delete(map, addr, addr + size);
- vm_map_unlock(map);
- return (0);
- }
- end_m = m + atop(size);
- for (; m < end_m; m++) {
- if ((flags & M_ZERO) && (m->flags & PG_ZERO) == 0)
- pmap_zero_page(m);
- m->valid = VM_PAGE_BITS_ALL;
- }
- VM_OBJECT_UNLOCK(object);
- vm_map_unlock(map);
- vm_map_wire(map, addr, addr + size, VM_MAP_WIRE_SYSTEM |
- VM_MAP_WIRE_NOHOLES);
- return (addr);
-}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vm_fault.c
--- a/head/sys/vm/vm_fault.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/vm_fault.c Wed Jul 25 16:45:04 2012 +0300
@@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/vm/vm_fault.c 233925 2012-04-05 17:13:14Z jhb $");
+__FBSDID("$FreeBSD: head/sys/vm/vm_fault.c 235850 2012-05-23 18:10:54Z kib $");
#include "opt_ktrace.h"
#include "opt_vm.h"
@@ -118,9 +118,11 @@
static int vm_fault_additional_pages(vm_page_t, int, int, vm_page_t *, int *);
static void vm_fault_prefault(pmap_t, vm_offset_t, vm_map_entry_t);
-#define VM_FAULT_READ_AHEAD 8
-#define VM_FAULT_READ_BEHIND 7
-#define VM_FAULT_READ (VM_FAULT_READ_AHEAD+VM_FAULT_READ_BEHIND+1)
+#define VM_FAULT_READ_BEHIND 8
+#define VM_FAULT_READ_MAX (1 + VM_FAULT_READ_AHEAD_MAX)
+#define VM_FAULT_NINCR (VM_FAULT_READ_MAX / VM_FAULT_READ_BEHIND)
+#define VM_FAULT_SUM (VM_FAULT_NINCR * (VM_FAULT_NINCR + 1) / 2)
+#define VM_FAULT_CACHE_BEHIND (VM_FAULT_READ_BEHIND * VM_FAULT_SUM)
struct faultstate {
vm_page_t m;
@@ -136,6 +138,8 @@
int vfslocked;
};
+static void vm_fault_cache_behind(const struct faultstate *fs, int distance);
+
static inline void
release_page(struct faultstate *fs)
{
@@ -236,13 +240,13 @@
int fault_flags, vm_page_t *m_hold)
{
vm_prot_t prot;
- int is_first_object_locked, result;
- boolean_t growstack, wired;
+ long ahead, behind;
+ int alloc_req, era, faultcount, nera, reqpage, result;
+ boolean_t growstack, is_first_object_locked, wired;
int map_generation;
vm_object_t next_object;
- vm_page_t marray[VM_FAULT_READ], mt, mt_prev;
+ vm_page_t marray[VM_FAULT_READ_MAX];
int hardfault;
- int faultcount, ahead, behind, alloc_req;
struct faultstate fs;
struct vnode *vp;
int locked, error;
@@ -252,7 +256,7 @@
PCPU_INC(cnt.v_vm_faults);
fs.vp = NULL;
fs.vfslocked = 0;
- faultcount = behind = 0;
+ faultcount = reqpage = 0;
RetryFault:;
@@ -460,75 +464,47 @@
*/
if (TRYPAGER) {
int rv;
- int reqpage = 0;
u_char behavior = vm_map_entry_behavior(fs.entry);
if (behavior == MAP_ENTRY_BEHAV_RANDOM ||
P_KILLED(curproc)) {
+ behind = 0;
ahead = 0;
+ } else if (behavior == MAP_ENTRY_BEHAV_SEQUENTIAL) {
behind = 0;
+ ahead = atop(fs.entry->end - vaddr) - 1;
+ if (ahead > VM_FAULT_READ_AHEAD_MAX)
+ ahead = VM_FAULT_READ_AHEAD_MAX;
+ if (fs.pindex == fs.entry->next_read)
+ vm_fault_cache_behind(&fs,
+ VM_FAULT_READ_MAX);
} else {
- behind = (vaddr - fs.entry->start) >> PAGE_SHIFT;
+ /*
+ * If this is a sequential page fault, then
+ * arithmetically increase the number of pages
+ * in the read-ahead window. Otherwise, reset
+ * the read-ahead window to its smallest size.
+ */
+ behind = atop(vaddr - fs.entry->start);
if (behind > VM_FAULT_READ_BEHIND)
behind = VM_FAULT_READ_BEHIND;
-
- ahead = ((fs.entry->end - vaddr) >> PAGE_SHIFT) - 1;
- if (ahead > VM_FAULT_READ_AHEAD)
- ahead = VM_FAULT_READ_AHEAD;
+ ahead = atop(fs.entry->end - vaddr) - 1;
+ era = fs.entry->read_ahead;
+ if (fs.pindex == fs.entry->next_read) {
+ nera = era + behind;
+ if (nera > VM_FAULT_READ_AHEAD_MAX)
+ nera = VM_FAULT_READ_AHEAD_MAX;
+ behind = 0;
+ if (ahead > nera)
+ ahead = nera;
+ if (era == VM_FAULT_READ_AHEAD_MAX)
+ vm_fault_cache_behind(&fs,
+ VM_FAULT_CACHE_BEHIND);
+ } else if (ahead > VM_FAULT_READ_AHEAD_MIN)
+ ahead = VM_FAULT_READ_AHEAD_MIN;
+ if (era != ahead)
+ fs.entry->read_ahead = ahead;
}
- is_first_object_locked = FALSE;
- if ((behavior == MAP_ENTRY_BEHAV_SEQUENTIAL ||
- (behavior != MAP_ENTRY_BEHAV_RANDOM &&
- fs.pindex >= fs.entry->lastr &&
- fs.pindex < fs.entry->lastr + VM_FAULT_READ)) &&
- (fs.first_object == fs.object ||
- (is_first_object_locked = VM_OBJECT_TRYLOCK(fs.first_object))) &&
- fs.first_object->type != OBJT_DEVICE &&
- fs.first_object->type != OBJT_PHYS &&
- fs.first_object->type != OBJT_SG) {
- vm_pindex_t firstpindex;
-
- if (fs.first_pindex < 2 * VM_FAULT_READ)
- firstpindex = 0;
- else
- firstpindex = fs.first_pindex - 2 * VM_FAULT_READ;
- mt = fs.first_object != fs.object ?
- fs.first_m : fs.m;
- KASSERT(mt != NULL, ("vm_fault: missing mt"));
- KASSERT((mt->oflags & VPO_BUSY) != 0,
- ("vm_fault: mt %p not busy", mt));
- mt_prev = vm_page_prev(mt);
-
- /*
- * note: partially valid pages cannot be
- * included in the lookahead - NFS piecemeal
- * writes will barf on it badly.
- */
- while ((mt = mt_prev) != NULL &&
- mt->pindex >= firstpindex &&
- mt->valid == VM_PAGE_BITS_ALL) {
- mt_prev = vm_page_prev(mt);
- if (mt->busy ||
- (mt->oflags & VPO_BUSY))
- continue;
- vm_page_lock(mt);
- if (mt->hold_count ||
- mt->wire_count) {
- vm_page_unlock(mt);
- continue;
- }
- pmap_remove_all(mt);
- if (mt->dirty != 0)
- vm_page_deactivate(mt);
- else
- vm_page_cache(mt);
- vm_page_unlock(mt);
- }
- ahead += behind;
- behind = 0;
- }
- if (is_first_object_locked)
- VM_OBJECT_UNLOCK(fs.first_object);
/*
* Call the pager to retrieve the data, if any, after
@@ -829,6 +805,7 @@
if (!is_first_object_locked)
VM_OBJECT_LOCK(fs.object);
PCPU_INC(cnt.v_cow_faults);
+ curthread->td_cow++;
} else {
prot &= ~VM_PROT_WRITE;
}
@@ -899,7 +876,7 @@
* without holding a write lock on it.
*/
if (hardfault)
- fs.entry->lastr = fs.pindex + faultcount - behind;
+ fs.entry->next_read = fs.pindex + faultcount - reqpage;
if ((prot & VM_PROT_WRITE) != 0 ||
(fault_flags & VM_FAULT_DIRTY) != 0) {
@@ -992,6 +969,60 @@
}
/*
+ * Speed up the reclamation of up to "distance" pages that precede the
+ * faulting pindex within the first object of the shadow chain.
+ */
+static void
+vm_fault_cache_behind(const struct faultstate *fs, int distance)
+{
+ vm_object_t first_object, object;
+ vm_page_t m, m_prev;
+ vm_pindex_t pindex;
+
+ object = fs->object;
+ VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
+ first_object = fs->first_object;
+ if (first_object != object) {
+ if (!VM_OBJECT_TRYLOCK(first_object)) {
+ VM_OBJECT_UNLOCK(object);
+ VM_OBJECT_LOCK(first_object);
+ VM_OBJECT_LOCK(object);
+ }
+ }
+ if (first_object->type != OBJT_DEVICE &&
+ first_object->type != OBJT_PHYS && first_object->type != OBJT_SG) {
+ if (fs->first_pindex < distance)
+ pindex = 0;
+ else
+ pindex = fs->first_pindex - distance;
+ if (pindex < OFF_TO_IDX(fs->entry->offset))
+ pindex = OFF_TO_IDX(fs->entry->offset);
+ m = first_object != object ? fs->first_m : fs->m;
+ KASSERT((m->oflags & VPO_BUSY) != 0,
+ ("vm_fault_cache_behind: page %p is not busy", m));
+ m_prev = vm_page_prev(m);
+ while ((m = m_prev) != NULL && m->pindex >= pindex &&
+ m->valid == VM_PAGE_BITS_ALL) {
+ m_prev = vm_page_prev(m);
+ if (m->busy != 0 || (m->oflags & VPO_BUSY) != 0)
+ continue;
+ vm_page_lock(m);
+ if (m->hold_count == 0 && m->wire_count == 0) {
+ pmap_remove_all(m);
+ vm_page_aflag_clear(m, PGA_REFERENCED);
+ if (m->dirty != 0)
+ vm_page_deactivate(m);
+ else
+ vm_page_cache(m);
+ }
+ vm_page_unlock(m);
+ }
+ }
+ if (first_object != object)
+ VM_OBJECT_UNLOCK(first_object);
+}
+
+/*
* vm_fault_prefault provides a quick way of clustering
* pagefaults into a processes address space. It is a "cousin"
* of vm_map_pmap_enter, except it runs at page fault time instead
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vm_kern.c
--- a/head/sys/vm/vm_kern.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/vm_kern.c Wed Jul 25 16:45:04 2012 +0300
@@ -63,7 +63,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/vm/vm_kern.c 232288 2012-02-29 05:41:29Z alc $");
+__FBSDID("$FreeBSD: head/sys/vm/vm_kern.c 238561 2012-07-18 05:21:34Z alc $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -195,6 +195,148 @@
}
/*
+ * Allocates a region from the kernel address map and physical pages
+ * within the specified address range to the kernel object. Creates a
+ * wired mapping from this region to these pages, and returns the
+ * region's starting virtual address. The allocated pages are not
+ * necessarily physically contiguous. If M_ZERO is specified through the
+ * given flags, then the pages are zeroed before they are mapped.
+ */
+vm_offset_t
+kmem_alloc_attr(vm_map_t map, vm_size_t size, int flags, vm_paddr_t low,
+ vm_paddr_t high, vm_memattr_t memattr)
+{
+ vm_object_t object = kernel_object;
+ vm_offset_t addr;
+ vm_ooffset_t end_offset, offset;
+ vm_page_t m;
+ int pflags, tries;
+
+ size = round_page(size);
+ vm_map_lock(map);
+ if (vm_map_findspace(map, vm_map_min(map), size, &addr)) {
+ vm_map_unlock(map);
+ return (0);
+ }
+ offset = addr - VM_MIN_KERNEL_ADDRESS;
+ vm_object_reference(object);
+ vm_map_insert(map, object, offset, addr, addr + size, VM_PROT_ALL,
+ VM_PROT_ALL, 0);
+ if ((flags & (M_NOWAIT | M_USE_RESERVE)) == M_NOWAIT)
+ pflags = VM_ALLOC_INTERRUPT | VM_ALLOC_NOBUSY;
+ else
+ pflags = VM_ALLOC_SYSTEM | VM_ALLOC_NOBUSY;
+ if (flags & M_ZERO)
+ pflags |= VM_ALLOC_ZERO;
+ VM_OBJECT_LOCK(object);
+ end_offset = offset + size;
+ for (; offset < end_offset; offset += PAGE_SIZE) {
+ tries = 0;
+retry:
+ m = vm_page_alloc_contig(object, OFF_TO_IDX(offset), pflags, 1,
+ low, high, PAGE_SIZE, 0, memattr);
+ if (m == NULL) {
+ VM_OBJECT_UNLOCK(object);
+ if (tries < ((flags & M_NOWAIT) != 0 ? 1 : 3)) {
+ vm_map_unlock(map);
+ vm_pageout_grow_cache(tries, low, high);
+ vm_map_lock(map);
+ VM_OBJECT_LOCK(object);
+ tries++;
+ goto retry;
+ }
+
+ /*
+ * Since the pages that were allocated by any previous
+ * iterations of this loop are not busy, they can be
+ * freed by vm_object_page_remove(), which is called
+ * by vm_map_delete().
+ */
+ vm_map_delete(map, addr, addr + size);
+ vm_map_unlock(map);
+ return (0);
+ }
+ if ((flags & M_ZERO) && (m->flags & PG_ZERO) == 0)
+ pmap_zero_page(m);
+ m->valid = VM_PAGE_BITS_ALL;
+ }
+ VM_OBJECT_UNLOCK(object);
+ vm_map_unlock(map);
+ vm_map_wire(map, addr, addr + size, VM_MAP_WIRE_SYSTEM |
+ VM_MAP_WIRE_NOHOLES);
+ return (addr);
+}
+
+/*
+ * Allocates a region from the kernel address map and physically
+ * contiguous pages within the specified address range to the kernel
+ * object. Creates a wired mapping from this region to these pages, and
+ * returns the region's starting virtual address. If M_ZERO is specified
+ * through the given flags, then the pages are zeroed before they are
+ * mapped.
+ */
+vm_offset_t
+kmem_alloc_contig(vm_map_t map, vm_size_t size, int flags, vm_paddr_t low,
+ vm_paddr_t high, u_long alignment, vm_paddr_t boundary,
+ vm_memattr_t memattr)
+{
+ vm_object_t object = kernel_object;
+ vm_offset_t addr;
+ vm_ooffset_t offset;
+ vm_page_t end_m, m;
+ int pflags, tries;
+
+ size = round_page(size);
+ vm_map_lock(map);
+ if (vm_map_findspace(map, vm_map_min(map), size, &addr)) {
+ vm_map_unlock(map);
+ return (0);
+ }
+ offset = addr - VM_MIN_KERNEL_ADDRESS;
+ vm_object_reference(object);
+ vm_map_insert(map, object, offset, addr, addr + size, VM_PROT_ALL,
+ VM_PROT_ALL, 0);
+ if ((flags & (M_NOWAIT | M_USE_RESERVE)) == M_NOWAIT)
+ pflags = VM_ALLOC_INTERRUPT | VM_ALLOC_NOBUSY;
+ else
+ pflags = VM_ALLOC_SYSTEM | VM_ALLOC_NOBUSY;
+ if (flags & M_ZERO)
+ pflags |= VM_ALLOC_ZERO;
+ if (flags & M_NODUMP)
+ pflags |= VM_ALLOC_NODUMP;
+ VM_OBJECT_LOCK(object);
+ tries = 0;
+retry:
+ m = vm_page_alloc_contig(object, OFF_TO_IDX(offset), pflags,
+ atop(size), low, high, alignment, boundary, memattr);
+ if (m == NULL) {
+ VM_OBJECT_UNLOCK(object);
+ if (tries < ((flags & M_NOWAIT) != 0 ? 1 : 3)) {
+ vm_map_unlock(map);
+ vm_pageout_grow_cache(tries, low, high);
+ vm_map_lock(map);
+ VM_OBJECT_LOCK(object);
+ tries++;
+ goto retry;
+ }
+ vm_map_delete(map, addr, addr + size);
+ vm_map_unlock(map);
+ return (0);
+ }
+ end_m = m + atop(size);
+ for (; m < end_m; m++) {
+ if ((flags & M_ZERO) && (m->flags & PG_ZERO) == 0)
+ pmap_zero_page(m);
+ m->valid = VM_PAGE_BITS_ALL;
+ }
+ VM_OBJECT_UNLOCK(object);
+ vm_map_unlock(map);
+ vm_map_wire(map, addr, addr + size, VM_MAP_WIRE_SYSTEM |
+ VM_MAP_WIRE_NOHOLES);
+ return (addr);
+}
+
+/*
* kmem_free:
*
* Release a region of kernel virtual memory allocated
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vm_map.c
--- a/head/sys/vm/vm_map.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/vm_map.c Wed Jul 25 16:45:04 2012 +0300
@@ -63,7 +63,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/vm/vm_map.c 233191 2012-03-19 18:47:34Z jhb $");
+__FBSDID("$FreeBSD: head/sys/vm/vm_map.c 237623 2012-06-27 03:45:25Z alc $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -241,8 +241,8 @@
map = (vm_map_t)mem;
map->nentries = 0;
map->size = 0;
- mtx_init(&map->system_mtx, "system map", NULL, MTX_DEF | MTX_DUPOK);
- sx_init(&map->lock, "user map");
+ mtx_init(&map->system_mtx, "vm map (system)", NULL, MTX_DEF | MTX_DUPOK);
+ sx_init(&map->lock, "vm map (user)");
return (0);
}
@@ -475,12 +475,14 @@
vm_map_process_deferred(void)
{
struct thread *td;
- vm_map_entry_t entry;
+ vm_map_entry_t entry, next;
vm_object_t object;
td = curthread;
- while ((entry = td->td_map_def_user) != NULL) {
- td->td_map_def_user = entry->next;
+ entry = td->td_map_def_user;
+ td->td_map_def_user = NULL;
+ while (entry != NULL) {
+ next = entry->next;
if ((entry->eflags & MAP_ENTRY_VN_WRITECNT) != 0) {
/*
* Decrement the object's writemappings and
@@ -494,6 +496,7 @@
entry->end);
}
vm_map_entry_deallocate(entry, FALSE);
+ entry = next;
}
}
@@ -1300,6 +1303,8 @@
new_entry->protection = prot;
new_entry->max_protection = max;
new_entry->wired_count = 0;
+ new_entry->read_ahead = VM_FAULT_READ_AHEAD_INIT;
+ new_entry->next_read = OFF_TO_IDX(offset);
KASSERT(cred == NULL || !ENTRY_CHARGED(new_entry),
("OVERCOMMIT: vm_map_insert leaks vm_map %p", new_entry));
@@ -3526,7 +3531,7 @@
}
rv = vm_map_insert(map, NULL, 0, addr, stack_entry->start,
- p->p_sysent->sv_stackprot, VM_PROT_ALL, 0);
+ next_entry->protection, next_entry->max_protection, 0);
/* Adjust the available stack space by the amount we grew. */
if (rv == KERN_SUCCESS) {
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vm_map.h
--- a/head/sys/vm/vm_map.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/vm_map.h Wed Jul 25 16:45:04 2012 +0300
@@ -57,7 +57,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $FreeBSD: head/sys/vm/vm_map.h 232071 2012-02-23 21:07:16Z kib $
+ * $FreeBSD: head/sys/vm/vm_map.h 238502 2012-07-15 20:29:48Z mdf $
*/
/*
@@ -112,8 +112,9 @@
vm_prot_t protection; /* protection code */
vm_prot_t max_protection; /* maximum protection */
vm_inherit_t inheritance; /* inheritance */
+ uint8_t read_ahead; /* pages in the read-ahead window */
int wired_count; /* can be paged if = 0 */
- vm_pindex_t lastr; /* last read */
+ vm_pindex_t next_read; /* index of the next sequential read */
struct ucred *cred; /* tmp storage for creator ref */
};
@@ -199,13 +200,13 @@
#ifdef _KERNEL
static __inline vm_offset_t
-vm_map_max(vm_map_t map)
+vm_map_max(const struct vm_map *map)
{
return (map->max_offset);
}
static __inline vm_offset_t
-vm_map_min(vm_map_t map)
+vm_map_min(const struct vm_map *map)
{
return (map->min_offset);
}
@@ -330,6 +331,14 @@
#define VM_FAULT_DIRTY 2 /* Dirty the page; use w/VM_PROT_COPY */
/*
+ * Initially, mappings are slightly sequential. The maximum window size must
+ * account for the map entry's "read_ahead" field being defined as an uint8_t.
+ */
+#define VM_FAULT_READ_AHEAD_MIN 7
+#define VM_FAULT_READ_AHEAD_INIT 15
+#define VM_FAULT_READ_AHEAD_MAX min(atop(MAXPHYS) - 1, UINT8_MAX)
+
+/*
* The following "find_space" options are supported by vm_map_find()
*/
#define VMFS_NO_SPACE 0 /* don't find; use the given range */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vm_mmap.c
--- a/head/sys/vm/vm_mmap.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/vm_mmap.c Wed Jul 25 16:45:04 2012 +0300
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/vm/vm_mmap.c 234039 2012-04-08 18:25:12Z alc $");
+__FBSDID("$FreeBSD: head/sys/vm/vm_mmap.c 234556 2012-04-21 18:36:53Z kib $");
#include "opt_compat.h"
#include "opt_hwpmc_hooks.h"
@@ -1561,9 +1561,11 @@
* If the process has requested that all future mappings
* be wired, then heed this.
*/
- if (map->flags & MAP_WIREFUTURE)
+ if (map->flags & MAP_WIREFUTURE) {
vm_map_wire(map, *addr, *addr + size,
- VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES);
+ VM_MAP_WIRE_USER | ((flags & MAP_STACK) ?
+ VM_MAP_WIRE_HOLESOK : VM_MAP_WIRE_NOHOLES));
+ }
} else {
/*
* If this mapping was accounted for in the vnode's
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vm_object.c
--- a/head/sys/vm/vm_object.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/vm_object.c Wed Jul 25 16:45:04 2012 +0300
@@ -63,7 +63,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/vm/vm_object.c 233191 2012-03-19 18:47:34Z jhb $");
+__FBSDID("$FreeBSD: head/sys/vm/vm_object.c 238359 2012-07-11 01:04:59Z attilio $");
#include "opt_vm.h"
@@ -1381,6 +1381,12 @@
/*
* Transfer any cached pages from orig_object to new_object.
+ * If swap_pager_copy() found swapped out pages within the
+ * specified range of orig_object, then it changed
+ * new_object's type to OBJT_SWAP when it transferred those
+ * pages to new_object. Otherwise, new_object's type
+ * should still be OBJT_DEFAULT and orig_object should not
+ * contain any cached pages within the specified range.
*/
if (__predict_false(orig_object->cache != NULL))
vm_page_cache_transfer(orig_object, offidxstart,
@@ -1719,6 +1725,9 @@
* swap_pager_copy() can sleep, in which case
* the backing_object's and object's locks are
* released and reacquired.
+ * Since swap_pager_copy() is being asked to
+ * destroy the source, it will change the
+ * backing_object's type to OBJT_DEFAULT.
*/
swap_pager_copy(
backing_object,
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vm_object.h
--- a/head/sys/vm/vm_object.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/vm_object.h Wed Jul 25 16:45:04 2012 +0300
@@ -57,7 +57,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $FreeBSD: head/sys/vm/vm_object.h 233191 2012-03-19 18:47:34Z jhb $
+ * $FreeBSD: head/sys/vm/vm_object.h 237451 2012-06-22 18:34:11Z attilio $
*/
/*
@@ -76,8 +76,21 @@
*
* vm_object_t Virtual memory object.
*
+ * The root of cached pages pool is protected by both the per-object mutex
+ * and the free pages queue mutex.
+ * On insert in the cache splay tree, the per-object mutex is expected
+ * to be already held and the free pages queue mutex will be
+ * acquired during the operation too.
+ * On remove and lookup from the cache splay tree, only the free
+ * pages queue mutex is expected to be locked.
+ * These rules allow for reliably checking for the presence of cached
+ * pages with only the per-object lock held, thereby reducing contention
+ * for the free pages queue mutex.
+ *
* List of locks
* (c) const until freed
+ * (o) per-object mutex
+ * (f) free pages queue mutex
*
*/
@@ -102,7 +115,7 @@
vm_ooffset_t backing_object_offset;/* Offset in backing object */
TAILQ_ENTRY(vm_object) pager_object_list; /* list of all objects of this pager type */
LIST_HEAD(, vm_reserv) rvq; /* list of reservations */
- vm_page_t cache; /* root of the cache page splay tree */
+ vm_page_t cache; /* (o + f) root of the cache page splay tree */
void *handle;
union {
/*
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vm_page.c
--- a/head/sys/vm/vm_page.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/vm_page.c Wed Jul 25 16:45:04 2012 +0300
@@ -77,7 +77,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/vm/vm_page.c 234064 2012-04-09 17:05:18Z attilio $");
+__FBSDID("$FreeBSD: head/sys/vm/vm_page.c 238543 2012-07-17 02:36:59Z alc $");
#include "opt_vm.h"
@@ -121,10 +121,10 @@
struct vpglocks pa_lock[PA_LOCK_COUNT];
-vm_page_t vm_page_array = 0;
-int vm_page_array_size = 0;
-long first_page = 0;
-int vm_page_zero_count = 0;
+vm_page_t vm_page_array;
+long vm_page_array_size;
+long first_page;
+int vm_page_zero_count;
static int boot_pages = UMA_BOOT_PAGES;
TUNABLE_INT("vm.boot_pages", &boot_pages);
@@ -292,16 +292,13 @@
end = phys_avail[biggestone+1];
/*
- * Initialize the locks.
+ * Initialize the page and queue locks.
*/
- mtx_init(&vm_page_queue_mtx, "vm page queue mutex", NULL, MTX_DEF |
+ mtx_init(&vm_page_queue_mtx, "vm page queue", NULL, MTX_DEF |
MTX_RECURSE);
- mtx_init(&vm_page_queue_free_mtx, "vm page queue free mutex", NULL,
- MTX_DEF);
-
- /* Setup page locks. */
+ mtx_init(&vm_page_queue_free_mtx, "vm page free queue", NULL, MTX_DEF);
for (i = 0; i < PA_LOCK_COUNT; i++)
- mtx_init(&pa_lock[i].data, "page lock", NULL, MTX_DEF);
+ mtx_init(&pa_lock[i].data, "vm page", NULL, MTX_DEF);
/*
* Initialize the queue headers for the hold queue, the active queue,
@@ -633,6 +630,30 @@
mtx_unlock(mtx);
}
+vm_page_t
+PHYS_TO_VM_PAGE(vm_paddr_t pa)
+{
+ vm_page_t m;
+
+#ifdef VM_PHYSSEG_SPARSE
+ m = vm_phys_paddr_to_vm_page(pa);
+ if (m == NULL)
+ m = vm_phys_fictitious_to_vm_page(pa);
+ return (m);
+#elif defined(VM_PHYSSEG_DENSE)
+ long pi;
+
+ pi = atop(pa);
+ if (pi >= first_page && (pi - first_page) < vm_page_array_size) {
+ m = &vm_page_array[pi - first_page];
+ return (m);
+ }
+ return (vm_phys_fictitious_to_vm_page(pa));
+#else
+#error "Either VM_PHYSSEG_DENSE or VM_PHYSSEG_SPARSE must be defined."
+#endif
+}
+
/*
* vm_page_getfake:
*
@@ -646,6 +667,22 @@
vm_page_t m;
m = uma_zalloc(fakepg_zone, M_WAITOK | M_ZERO);
+ vm_page_initfake(m, paddr, memattr);
+ return (m);
+}
+
+void
+vm_page_initfake(vm_page_t m, vm_paddr_t paddr, vm_memattr_t memattr)
+{
+
+ if ((m->flags & PG_FICTITIOUS) != 0) {
+ /*
+ * The page's memattr might have changed since the
+ * previous initialization. Update the pmap to the
+ * new memattr.
+ */
+ goto memattr;
+ }
m->phys_addr = paddr;
m->queue = PQ_NONE;
/* Fictitious pages don't use "segind". */
@@ -653,8 +690,8 @@
/* Fictitious pages don't use "order" or "pool". */
m->oflags = VPO_BUSY | VPO_UNMANAGED;
m->wire_count = 1;
+memattr:
pmap_page_set_memattr(m, memattr);
- return (m);
}
/*
@@ -666,6 +703,7 @@
vm_page_putfake(vm_page_t m)
{
+ KASSERT((m->oflags & VPO_UNMANAGED) != 0, ("managed %p", m));
KASSERT((m->flags & PG_FICTITIOUS) != 0,
("vm_page_putfake: bad page %p", m));
uma_zfree(fakepg_zone, m);
@@ -742,7 +780,7 @@
}
/*
- * vm_page_dirty:
+ * vm_page_dirty_KBI: [ internal use only ]
*
* Set all bits in the page's dirty field.
*
@@ -750,11 +788,14 @@
* call is made from the machine-independent layer.
*
* See vm_page_clear_dirty_mask().
+ *
+ * This function should only be called by vm_page_dirty().
*/
void
-vm_page_dirty(vm_page_t m)
+vm_page_dirty_KBI(vm_page_t m)
{
+ /* These assertions refer to this operation by its public name. */
KASSERT((m->flags & PG_CACHED) == 0,
("vm_page_dirty: page in cache!"));
KASSERT(!VM_PAGE_IS_FREE(m),
@@ -889,7 +930,7 @@
* Since we are inserting a new and possibly dirty page,
* update the object's OBJ_MIGHTBEDIRTY flag.
*/
- if (m->aflags & PGA_WRITEABLE)
+ if (pmap_page_is_write_mapped(m))
vm_object_set_writeable_dirty(object);
}
@@ -1643,7 +1684,7 @@
}
for (m = m_ret; m < &m_ret[npages]; m++) {
m->aflags = 0;
- m->flags &= flags;
+ m->flags = (m->flags | PG_NODUMP) & flags;
if ((req & VM_ALLOC_WIRED) != 0)
m->wire_count = 1;
/* Unmanaged pages don't use "act_count". */
@@ -2155,13 +2196,10 @@
if ((m->oflags & VPO_UNMANAGED) != 0 ||
m->object == NULL)
return;
+ if (!activate)
+ m->flags &= ~PG_WINATCFLS;
vm_page_lock_queues();
- if (activate)
- vm_page_enqueue(PQ_ACTIVE, m);
- else {
- m->flags &= ~PG_WINATCFLS;
- vm_page_enqueue(PQ_INACTIVE, m);
- }
+ vm_page_enqueue(activate ? PQ_ACTIVE : PQ_INACTIVE, m);
vm_page_unlock_queues();
}
} else
@@ -2201,8 +2239,8 @@
if ((queue = m->queue) == PQ_INACTIVE)
return;
if (m->wire_count == 0 && (m->oflags & VPO_UNMANAGED) == 0) {
+ m->flags &= ~PG_WINATCFLS;
vm_page_lock_queues();
- m->flags &= ~PG_WINATCFLS;
if (queue != PQ_NONE)
vm_page_queue_remove(queue, m);
if (athead)
@@ -2637,11 +2675,11 @@
/*
* If the object is locked and the page is neither VPO_BUSY nor
- * PGA_WRITEABLE, then the page's dirty field cannot possibly be
+ * write mapped, then the page's dirty field cannot possibly be
* set by a concurrent pmap operation.
*/
VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED);
- if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0)
+ if ((m->oflags & VPO_BUSY) == 0 && !pmap_page_is_write_mapped(m))
m->dirty &= ~pagebits;
else {
/*
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vm_page.h
--- a/head/sys/vm/vm_page.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/vm_page.h Wed Jul 25 16:45:04 2012 +0300
@@ -57,7 +57,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $FreeBSD: head/sys/vm/vm_page.h 234039 2012-04-08 18:25:12Z alc $
+ * $FreeBSD: head/sys/vm/vm_page.h 237346 2012-06-20 23:25:47Z alc $
*/
/*
@@ -237,20 +237,22 @@
#endif
#define vm_page_queue_free_mtx vm_page_queue_free_lock.data
+
/*
* These are the flags defined for vm_page.
*
- * aflags are updated by atomic accesses. Use the vm_page_aflag_set()
+ * aflags are updated by atomic accesses. Use the vm_page_aflag_set()
* and vm_page_aflag_clear() functions to set and clear the flags.
*
* PGA_REFERENCED may be cleared only if the object containing the page is
- * locked.
+ * locked. It is set by both the MI and MD VM layers.
*
* PGA_WRITEABLE is set exclusively on managed pages by pmap_enter(). When it
- * does so, the page must be VPO_BUSY.
+ * does so, the page must be VPO_BUSY. The MI VM layer must never access this
+ * flag directly. Instead, it should call pmap_page_is_write_mapped().
*
* PGA_EXECUTABLE may be set by pmap routines, and indicates that a page has
- * at least one executable mapping. It is not consumed by the VM layer.
+ * at least one executable mapping. It is not consumed by the MI VM layer.
*/
#define PGA_WRITEABLE 0x01 /* page may be mapped writeable */
#define PGA_REFERENCED 0x02 /* page has been referenced */
@@ -262,12 +264,12 @@
*/
#define PG_CACHED 0x01 /* page is cached */
#define PG_FREE 0x02 /* page is free */
-#define PG_FICTITIOUS 0x04 /* physical page doesn't exist (O) */
+#define PG_FICTITIOUS 0x04 /* physical page doesn't exist */
#define PG_ZERO 0x08 /* page is zeroed */
#define PG_MARKER 0x10 /* special queue marker page */
#define PG_SLAB 0x20 /* object pointer is actually a slab */
#define PG_WINATCFLS 0x40 /* flush dirty page on inactive q */
-#define PG_NODUMP 0x80 /* don't include this page in the dump */
+#define PG_NODUMP 0x80 /* don't include this page in a dump */
/*
* Misc constants.
@@ -312,7 +314,7 @@
extern int vm_page_zero_count;
extern vm_page_t vm_page_array; /* First resident page in table */
-extern int vm_page_array_size; /* number of vm_page_t's */
+extern long vm_page_array_size; /* number of vm_page_t's */
extern long first_page; /* first physical page number */
#define VM_PAGE_IS_FREE(m) (((m)->flags & PG_FREE) != 0)
@@ -321,19 +323,7 @@
vm_page_t vm_phys_paddr_to_vm_page(vm_paddr_t pa);
-static __inline vm_page_t PHYS_TO_VM_PAGE(vm_paddr_t pa);
-
-static __inline vm_page_t
-PHYS_TO_VM_PAGE(vm_paddr_t pa)
-{
-#ifdef VM_PHYSSEG_SPARSE
- return (vm_phys_paddr_to_vm_page(pa));
-#elif defined(VM_PHYSSEG_DENSE)
- return (&vm_page_array[atop(pa) - first_page]);
-#else
-#error "Either VM_PHYSSEG_DENSE or VM_PHYSSEG_SPARSE must be defined."
-#endif
-}
+vm_page_t PHYS_TO_VM_PAGE(vm_paddr_t pa);
extern struct vpglocks vm_page_queue_lock;
@@ -370,7 +360,6 @@
void vm_page_unhold(vm_page_t mem);
void vm_page_free(vm_page_t m);
void vm_page_free_zero(vm_page_t m);
-void vm_page_dirty(vm_page_t m);
void vm_page_wakeup(vm_page_t m);
void vm_pageq_remove(vm_page_t m);
@@ -391,6 +380,7 @@
void vm_page_deactivate (vm_page_t);
vm_page_t vm_page_find_least(vm_object_t, vm_pindex_t);
vm_page_t vm_page_getfake(vm_paddr_t paddr, vm_memattr_t memattr);
+void vm_page_initfake(vm_page_t m, vm_paddr_t paddr, vm_memattr_t memattr);
void vm_page_insert (vm_page_t, vm_object_t, vm_pindex_t);
boolean_t vm_page_is_cached(vm_object_t object, vm_pindex_t pindex);
vm_page_t vm_page_lookup (vm_object_t, vm_pindex_t);
@@ -423,6 +413,7 @@
int vm_page_cowsetup(vm_page_t);
void vm_page_cowclear (vm_page_t);
+void vm_page_dirty_KBI(vm_page_t m);
void vm_page_lock_KBI(vm_page_t m, const char *file, int line);
void vm_page_unlock_KBI(vm_page_t m, const char *file, int line);
int vm_page_trylock_KBI(vm_page_t m, const char *file, int line);
@@ -438,6 +429,28 @@
#endif
/*
+ * vm_page_dirty:
+ *
+ * Set all bits in the page's dirty field.
+ *
+ * The object containing the specified page must be locked if the
+ * call is made from the machine-independent layer.
+ *
+ * See vm_page_clear_dirty_mask().
+ */
+static __inline void
+vm_page_dirty(vm_page_t m)
+{
+
+ /* Use vm_page_dirty_KBI() under INVARIANTS to save memory. */
+#if defined(KLD_MODULE) || defined(INVARIANTS)
+ vm_page_dirty_KBI(m);
+#else
+ m->dirty = VM_PAGE_BITS_ALL;
+#endif
+}
+
+/*
* vm_page_sleep_if_busy:
*
* Sleep and release the page queues lock if VPO_BUSY is set or,
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vm_pageout.c
--- a/head/sys/vm/vm_pageout.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/vm_pageout.c Wed Jul 25 16:45:04 2012 +0300
@@ -73,7 +73,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/vm/vm_pageout.c 233100 2012-03-17 23:00:32Z kib $");
+__FBSDID("$FreeBSD: head/sys/vm/vm_pageout.c 238732 2012-07-24 02:35:30Z alc $");
#include "opt_vm.h"
#include <sys/param.h>
@@ -209,11 +209,14 @@
SYSCTL_INT(_vm, OID_AUTO, max_wired,
CTLFLAG_RW, &vm_page_max_wired, 0, "System-wide limit to wired page count");
+static boolean_t vm_pageout_fallback_object_lock(vm_page_t, vm_page_t *);
+static boolean_t vm_pageout_launder(int, int, vm_paddr_t, vm_paddr_t);
#if !defined(NO_SWAPPING)
static void vm_pageout_map_deactivate_pages(vm_map_t, long);
static void vm_pageout_object_deactivate_pages(pmap_t, vm_object_t, long);
static void vm_req_vmdaemon(int req);
#endif
+static boolean_t vm_pageout_page_lock(vm_page_t, vm_page_t *);
static void vm_pageout_page_stats(void);
/*
@@ -247,7 +250,7 @@
* This function depends on both the lock portion of struct vm_object
* and normal struct vm_page being type stable.
*/
-boolean_t
+static boolean_t
vm_pageout_fallback_object_lock(vm_page_t m, vm_page_t *next)
{
struct vm_page marker;
@@ -286,7 +289,7 @@
*
* This function depends on normal struct vm_page being type stable.
*/
-boolean_t
+static boolean_t
vm_pageout_page_lock(vm_page_t m, vm_page_t *next)
{
struct vm_page marker;
@@ -503,7 +506,7 @@
vm_page_t mt = mc[i];
KASSERT(pageout_status[i] == VM_PAGER_PEND ||
- (mt->aflags & PGA_WRITEABLE) == 0,
+ !pmap_page_is_write_mapped(mt),
("vm_pageout_flush: page %p is not write protected", mt));
switch (pageout_status[i]) {
case VM_PAGER_OK:
@@ -558,6 +561,138 @@
return (numpagedout);
}
+static boolean_t
+vm_pageout_launder(int queue, int tries, vm_paddr_t low, vm_paddr_t high)
+{
+ struct mount *mp;
+ struct vnode *vp;
+ vm_object_t object;
+ vm_paddr_t pa;
+ vm_page_t m, m_tmp, next;
+ int vfslocked;
+
+ vm_page_lock_queues();
+ TAILQ_FOREACH_SAFE(m, &vm_page_queues[queue].pl, pageq, next) {
+ KASSERT(m->queue == queue,
+ ("vm_pageout_launder: page %p's queue is not %d", m,
+ queue));
+ if ((m->flags & PG_MARKER) != 0)
+ continue;
+ pa = VM_PAGE_TO_PHYS(m);
+ if (pa < low || pa + PAGE_SIZE > high)
+ continue;
+ if (!vm_pageout_page_lock(m, &next) || m->hold_count != 0) {
+ vm_page_unlock(m);
+ continue;
+ }
+ object = m->object;
+ if (!VM_OBJECT_TRYLOCK(object) &&
+ (!vm_pageout_fallback_object_lock(m, &next) ||
+ m->hold_count != 0)) {
+ vm_page_unlock(m);
+ VM_OBJECT_UNLOCK(object);
+ continue;
+ }
+ if ((m->oflags & VPO_BUSY) != 0 || m->busy != 0) {
+ if (tries == 0) {
+ vm_page_unlock(m);
+ VM_OBJECT_UNLOCK(object);
+ continue;
+ }
+ vm_page_sleep(m, "vpctw0");
+ VM_OBJECT_UNLOCK(object);
+ return (FALSE);
+ }
+ vm_page_test_dirty(m);
+ if (m->dirty == 0)
+ pmap_remove_all(m);
+ if (m->dirty != 0) {
+ vm_page_unlock(m);
+ if (tries == 0 || (object->flags & OBJ_DEAD) != 0) {
+ VM_OBJECT_UNLOCK(object);
+ continue;
+ }
+ if (object->type == OBJT_VNODE) {
+ vm_page_unlock_queues();
+ vp = object->handle;
+ vm_object_reference_locked(object);
+ VM_OBJECT_UNLOCK(object);
+ (void)vn_start_write(vp, &mp, V_WAIT);
+ vfslocked = VFS_LOCK_GIANT(vp->v_mount);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ VM_OBJECT_LOCK(object);
+ vm_object_page_clean(object, 0, 0, OBJPC_SYNC);
+ VM_OBJECT_UNLOCK(object);
+ VOP_UNLOCK(vp, 0);
+ VFS_UNLOCK_GIANT(vfslocked);
+ vm_object_deallocate(object);
+ vn_finished_write(mp);
+ return (TRUE);
+ } else if (object->type == OBJT_SWAP ||
+ object->type == OBJT_DEFAULT) {
+ vm_page_unlock_queues();
+ m_tmp = m;
+ vm_pageout_flush(&m_tmp, 1, VM_PAGER_PUT_SYNC,
+ 0, NULL, NULL);
+ VM_OBJECT_UNLOCK(object);
+ return (TRUE);
+ }
+ } else {
+ vm_page_cache(m);
+ vm_page_unlock(m);
+ }
+ VM_OBJECT_UNLOCK(object);
+ }
+ vm_page_unlock_queues();
+ return (FALSE);
+}
+
+/*
+ * Increase the number of cached pages. The specified value, "tries",
+ * determines which categories of pages are cached:
+ *
+ * 0: All clean, inactive pages within the specified physical address range
+ * are cached. Will not sleep.
+ * 1: The vm_lowmem handlers are called. All inactive pages within
+ * the specified physical address range are cached. May sleep.
+ * 2: The vm_lowmem handlers are called. All inactive and active pages
+ * within the specified physical address range are cached. May sleep.
+ */
+void
+vm_pageout_grow_cache(int tries, vm_paddr_t low, vm_paddr_t high)
+{
+ int actl, actmax, inactl, inactmax;
+
+ if (tries > 0) {
+ /*
+ * Decrease registered cache sizes. The vm_lowmem handlers
+ * may acquire locks and/or sleep, so they can only be invoked
+ * when "tries" is greater than zero.
+ */
+ EVENTHANDLER_INVOKE(vm_lowmem, 0);
+
+ /*
+ * We do this explicitly after the caches have been drained
+ * above.
+ */
+ uma_reclaim();
+ }
+ inactl = 0;
+ inactmax = cnt.v_inactive_count;
+ actl = 0;
+ actmax = tries < 2 ? 0 : cnt.v_active_count;
+again:
+ if (inactl < inactmax && vm_pageout_launder(PQ_INACTIVE, tries, low,
+ high)) {
+ inactl++;
+ goto again;
+ }
+ if (actl < actmax && vm_pageout_launder(PQ_ACTIVE, tries, low, high)) {
+ actl++;
+ goto again;
+ }
+}
+
#if !defined(NO_SWAPPING)
/*
* vm_pageout_object_deactivate_pages
@@ -738,11 +873,12 @@
vm_page_t m, next;
struct vm_page marker;
int page_shortage, maxscan, pcount;
- int addl_page_shortage, addl_page_shortage_init;
+ int addl_page_shortage;
vm_object_t object;
int actcount;
int vnodes_skipped = 0;
int maxlaunder;
+ boolean_t queues_locked;
/*
* Decrease registered cache sizes.
@@ -753,13 +889,13 @@
*/
uma_reclaim();
- addl_page_shortage_init = atomic_readandclear_int(&vm_pageout_deficit);
+ addl_page_shortage = atomic_readandclear_int(&vm_pageout_deficit);
/*
* Calculate the number of pages we want to either free or move
* to the cache.
*/
- page_shortage = vm_paging_target() + addl_page_shortage_init;
+ page_shortage = vm_paging_target() + addl_page_shortage;
vm_pageout_init_marker(&marker, PQ_INACTIVE);
@@ -784,19 +920,17 @@
if (pass)
maxlaunder = 10000;
vm_page_lock_queues();
-rescan0:
- addl_page_shortage = addl_page_shortage_init;
+ queues_locked = TRUE;
maxscan = cnt.v_inactive_count;
for (m = TAILQ_FIRST(&vm_page_queues[PQ_INACTIVE].pl);
m != NULL && maxscan-- > 0 && page_shortage > 0;
m = next) {
+ KASSERT(queues_locked, ("unlocked queues"));
+ mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+ KASSERT(m->queue == PQ_INACTIVE, ("Inactive queue %p", m));
cnt.v_pdpages++;
-
- if (m->queue != PQ_INACTIVE)
- goto rescan0;
-
next = TAILQ_NEXT(m, pageq);
/*
@@ -805,6 +939,11 @@
if (m->flags & PG_MARKER)
continue;
+ KASSERT((m->flags & PG_FICTITIOUS) == 0,
+ ("Fictitious page %p cannot be in inactive queue", m));
+ KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+ ("Unmanaged page %p cannot be in inactive queue", m));
+
/*
* Lock the page.
*/
@@ -831,7 +970,7 @@
object = m->object;
if (!VM_OBJECT_TRYLOCK(object) &&
(!vm_pageout_fallback_object_lock(m, &next) ||
- m->hold_count != 0)) {
+ m->hold_count != 0)) {
VM_OBJECT_UNLOCK(object);
vm_page_unlock(m);
addl_page_shortage++;
@@ -845,6 +984,16 @@
}
/*
+ * We unlock vm_page_queue_mtx, invalidating the
+ * 'next' pointer. Use our marker to remember our
+ * place.
+ */
+ TAILQ_INSERT_AFTER(&vm_page_queues[PQ_INACTIVE].pl,
+ m, &marker, pageq);
+ vm_page_unlock_queues();
+ queues_locked = FALSE;
+
+ /*
* If the object is not being used, we ignore previous
* references.
*/
@@ -862,13 +1011,13 @@
* level VM system not knowing anything about existing
* references.
*/
- } else if (((m->aflags & PGA_REFERENCED) == 0) &&
- (actcount = pmap_ts_referenced(m))) {
+ } else if ((m->aflags & PGA_REFERENCED) == 0 &&
+ (actcount = pmap_ts_referenced(m)) != 0) {
vm_page_activate(m);
vm_page_unlock(m);
m->act_count += actcount + ACT_ADVANCE;
VM_OBJECT_UNLOCK(object);
- continue;
+ goto relock_queues;
}
/*
@@ -884,7 +1033,7 @@
vm_page_unlock(m);
m->act_count += actcount + ACT_ADVANCE + 1;
VM_OBJECT_UNLOCK(object);
- continue;
+ goto relock_queues;
}
/*
@@ -894,7 +1043,7 @@
* be updated.
*/
if (m->dirty != VM_PAGE_BITS_ALL &&
- (m->aflags & PGA_WRITEABLE) != 0) {
+ pmap_page_is_write_mapped(m)) {
/*
* Avoid a race condition: Unless write access is
* removed from the page, another processor could
@@ -919,7 +1068,7 @@
* Invalid pages can be easily freed
*/
vm_page_free(m);
- cnt.v_dfree++;
+ PCPU_INC(cnt.v_dfree);
--page_shortage;
} else if (m->dirty == 0) {
/*
@@ -942,6 +1091,8 @@
* the thrash point for a heavily loaded machine.
*/
m->flags |= PG_WINATCFLS;
+ vm_page_lock_queues();
+ queues_locked = TRUE;
vm_page_requeue(m);
} else if (maxlaunder > 0) {
/*
@@ -971,21 +1122,13 @@
if (!swap_pageouts_ok || (object->flags & OBJ_DEAD)) {
vm_page_unlock(m);
VM_OBJECT_UNLOCK(object);
+ vm_page_lock_queues();
+ queues_locked = TRUE;
vm_page_requeue(m);
- continue;
+ goto relock_queues;
}
/*
- * Following operations may unlock
- * vm_page_queue_mtx, invalidating the 'next'
- * pointer. To prevent an inordinate number
- * of restarts we use our marker to remember
- * our place.
- *
- */
- TAILQ_INSERT_AFTER(&vm_page_queues[PQ_INACTIVE].pl,
- m, &marker, pageq);
- /*
* The object is already known NOT to be dead. It
* is possible for the vget() to block the whole
* pageout daemon, but the new low-memory handling
@@ -1009,7 +1152,6 @@
* of time.
*/
if (object->type == OBJT_VNODE) {
- vm_page_unlock_queues();
vm_page_unlock(m);
vp = object->handle;
if (vp->v_type == VREG &&
@@ -1018,7 +1160,6 @@
++pageout_lock_miss;
if (object->flags & OBJ_MIGHTBEDIRTY)
vnodes_skipped++;
- vm_page_lock_queues();
goto unlock_and_continue;
}
KASSERT(mp != NULL,
@@ -1029,7 +1170,6 @@
if (vget(vp, LK_EXCLUSIVE | LK_TIMELOCK,
curthread)) {
VM_OBJECT_LOCK(object);
- vm_page_lock_queues();
++pageout_lock_miss;
if (object->flags & OBJ_MIGHTBEDIRTY)
vnodes_skipped++;
@@ -1039,6 +1179,7 @@
VM_OBJECT_LOCK(object);
vm_page_lock(m);
vm_page_lock_queues();
+ queues_locked = TRUE;
/*
* The page might have been moved to another
* queue during potential blocking in vget()
@@ -1076,6 +1217,8 @@
vnodes_skipped++;
goto unlock_and_continue;
}
+ vm_page_unlock_queues();
+ queues_locked = FALSE;
}
/*
@@ -1088,32 +1231,37 @@
* the (future) cleaned page. Otherwise we could wind
* up laundering or cleaning too many pages.
*/
- vm_page_unlock_queues();
if (vm_pageout_clean(m) != 0) {
--page_shortage;
--maxlaunder;
}
- vm_page_lock_queues();
unlock_and_continue:
vm_page_lock_assert(m, MA_NOTOWNED);
VM_OBJECT_UNLOCK(object);
if (mp != NULL) {
- vm_page_unlock_queues();
+ if (queues_locked) {
+ vm_page_unlock_queues();
+ queues_locked = FALSE;
+ }
if (vp != NULL)
vput(vp);
VFS_UNLOCK_GIANT(vfslocked);
vm_object_deallocate(object);
vn_finished_write(mp);
- vm_page_lock_queues();
}
- next = TAILQ_NEXT(&marker, pageq);
- TAILQ_REMOVE(&vm_page_queues[PQ_INACTIVE].pl,
- &marker, pageq);
vm_page_lock_assert(m, MA_NOTOWNED);
- continue;
+ goto relock_queues;
}
vm_page_unlock(m);
VM_OBJECT_UNLOCK(object);
+relock_queues:
+ if (!queues_locked) {
+ vm_page_lock_queues();
+ queues_locked = TRUE;
+ }
+ next = TAILQ_NEXT(&marker, pageq);
+ TAILQ_REMOVE(&vm_page_queues[PQ_INACTIVE].pl,
+ &marker, pageq);
}
/*
@@ -1143,6 +1291,10 @@
m = next;
continue;
}
+ KASSERT((m->flags & PG_FICTITIOUS) == 0,
+ ("Fictitious page %p cannot be in active queue", m));
+ KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+ ("Unmanaged page %p cannot be in active queue", m));
if (!vm_pageout_page_lock(m, &next)) {
vm_page_unlock(m);
m = next;
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vm_pageout.h
--- a/head/sys/vm/vm_pageout.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/vm_pageout.h Wed Jul 25 16:45:04 2012 +0300
@@ -57,7 +57,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $FreeBSD: head/sys/vm/vm_pageout.h 233100 2012-03-17 23:00:32Z kib $
+ * $FreeBSD: head/sys/vm/vm_pageout.h 238561 2012-07-18 05:21:34Z alc $
*/
#ifndef _VM_VM_PAGEOUT_H_
@@ -101,10 +101,8 @@
extern void vm_waitpfault(void);
#ifdef _KERNEL
-boolean_t vm_pageout_fallback_object_lock(vm_page_t, vm_page_t *);
int vm_pageout_flush(vm_page_t *, int, int, int, int *, boolean_t *);
+void vm_pageout_grow_cache(int, vm_paddr_t, vm_paddr_t);
void vm_pageout_oom(int shortage);
-boolean_t vm_pageout_page_lock(vm_page_t, vm_page_t *);
-void vm_contig_grow_cache(int, vm_paddr_t, vm_paddr_t);
#endif
#endif /* _VM_VM_PAGEOUT_H_ */
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vm_pager.c
--- a/head/sys/vm/vm_pager.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/vm_pager.c Wed Jul 25 16:45:04 2012 +0300
@@ -64,7 +64,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/vm/vm_pager.c 227529 2011-11-15 14:09:53Z kib $");
+__FBSDID("$FreeBSD: head/sys/vm/vm_pager.c 235829 2012-05-23 12:51:49Z avg $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -159,7 +159,8 @@
&devicepagerops, /* OBJT_DEVICE */
&physpagerops, /* OBJT_PHYS */
&deadpagerops, /* OBJT_DEAD */
- &sgpagerops /* OBJT_SG */
+ &sgpagerops, /* OBJT_SG */
+ &mgtdevicepagerops, /* OBJT_MGTDEVICE */
};
static const int npagers = sizeof(pagertab) / sizeof(pagertab[0]);
@@ -270,14 +271,15 @@
vm_object_t object;
TAILQ_FOREACH(object, pg_list, pager_object_list) {
- VM_OBJECT_LOCK(object);
- if (object->handle == handle &&
- (object->flags & OBJ_DEAD) == 0) {
- vm_object_reference_locked(object);
+ if (object->handle == handle) {
+ VM_OBJECT_LOCK(object);
+ if ((object->flags & OBJ_DEAD) == 0) {
+ vm_object_reference_locked(object);
+ VM_OBJECT_UNLOCK(object);
+ break;
+ }
VM_OBJECT_UNLOCK(object);
- break;
}
- VM_OBJECT_UNLOCK(object);
}
return (object);
}
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vm_pager.h
--- a/head/sys/vm/vm_pager.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/vm_pager.h Wed Jul 25 16:45:04 2012 +0300
@@ -32,7 +32,7 @@
* SUCH DAMAGE.
*
* @(#)vm_pager.h 8.4 (Berkeley) 1/12/94
- * $FreeBSD: head/sys/vm/vm_pager.h 227530 2011-11-15 14:40:00Z kib $
+ * $FreeBSD: head/sys/vm/vm_pager.h 235375 2012-05-12 20:49:58Z kib $
*/
/*
@@ -71,6 +71,7 @@
extern struct pagerops devicepagerops;
extern struct pagerops physpagerops;
extern struct pagerops sgpagerops;
+extern struct pagerops mgtdevicepagerops;
/*
* get/put return values
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vm_phys.c
--- a/head/sys/vm/vm_phys.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/vm_phys.c Wed Jul 25 16:45:04 2012 +0300
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/vm/vm_phys.c 233194 2012-03-19 19:06:40Z jhb $");
+__FBSDID("$FreeBSD: head/sys/vm/vm_phys.c 235372 2012-05-12 20:42:56Z kib $");
#include "opt_ddb.h"
@@ -87,6 +87,15 @@
static int vm_phys_nsegs;
+#define VM_PHYS_FICTITIOUS_NSEGS 8
+static struct vm_phys_fictitious_seg {
+ vm_paddr_t start;
+ vm_paddr_t end;
+ vm_page_t first_page;
+} vm_phys_fictitious_segs[VM_PHYS_FICTITIOUS_NSEGS];
+static struct mtx vm_phys_fictitious_reg_mtx;
+MALLOC_DEFINE(M_FICT_PAGES, "", "");
+
static struct vm_freelist
vm_phys_free_queues[VM_RAW_NFREELIST][VM_NFREEPOOL][VM_NFREEORDER];
static struct vm_freelist
@@ -366,6 +375,8 @@
for (flind = 0; flind < vm_nfreelists; flind++)
vm_phys_lookup_lists[0][flind] = &vm_phys_free_queues[flind];
#endif
+
+ mtx_init(&vm_phys_fictitious_reg_mtx, "vmfctr", NULL, MTX_DEF);
}
/*
@@ -510,6 +521,112 @@
return (NULL);
}
+vm_page_t
+vm_phys_fictitious_to_vm_page(vm_paddr_t pa)
+{
+ struct vm_phys_fictitious_seg *seg;
+ vm_page_t m;
+ int segind;
+
+ m = NULL;
+ for (segind = 0; segind < VM_PHYS_FICTITIOUS_NSEGS; segind++) {
+ seg = &vm_phys_fictitious_segs[segind];
+ if (pa >= seg->start && pa < seg->end) {
+ m = &seg->first_page[atop(pa - seg->start)];
+ KASSERT((m->flags & PG_FICTITIOUS) != 0,
+ ("%p not fictitious", m));
+ break;
+ }
+ }
+ return (m);
+}
+
+int
+vm_phys_fictitious_reg_range(vm_paddr_t start, vm_paddr_t end,
+ vm_memattr_t memattr)
+{
+ struct vm_phys_fictitious_seg *seg;
+ vm_page_t fp;
+ long i, page_count;
+ int segind;
+#ifdef VM_PHYSSEG_DENSE
+ long pi;
+ boolean_t malloced;
+#endif
+
+ page_count = (end - start) / PAGE_SIZE;
+
+#ifdef VM_PHYSSEG_DENSE
+ pi = atop(start);
+ if (pi >= first_page && atop(end) < vm_page_array_size) {
+ fp = &vm_page_array[pi - first_page];
+ malloced = FALSE;
+ } else
+#endif
+ {
+ fp = malloc(page_count * sizeof(struct vm_page), M_FICT_PAGES,
+ M_WAITOK | M_ZERO);
+#ifdef VM_PHYSSEG_DENSE
+ malloced = TRUE;
+#endif
+ }
+ for (i = 0; i < page_count; i++) {
+ vm_page_initfake(&fp[i], start + PAGE_SIZE * i, memattr);
+ pmap_page_init(&fp[i]);
+ fp[i].oflags &= ~(VPO_BUSY | VPO_UNMANAGED);
+ }
+ mtx_lock(&vm_phys_fictitious_reg_mtx);
+ for (segind = 0; segind < VM_PHYS_FICTITIOUS_NSEGS; segind++) {
+ seg = &vm_phys_fictitious_segs[segind];
+ if (seg->start == 0 && seg->end == 0) {
+ seg->start = start;
+ seg->end = end;
+ seg->first_page = fp;
+ mtx_unlock(&vm_phys_fictitious_reg_mtx);
+ return (0);
+ }
+ }
+ mtx_unlock(&vm_phys_fictitious_reg_mtx);
+#ifdef VM_PHYSSEG_DENSE
+ if (malloced)
+#endif
+ free(fp, M_FICT_PAGES);
+ return (EBUSY);
+}
+
+void
+vm_phys_fictitious_unreg_range(vm_paddr_t start, vm_paddr_t end)
+{
+ struct vm_phys_fictitious_seg *seg;
+ vm_page_t fp;
+ int segind;
+#ifdef VM_PHYSSEG_DENSE
+ long pi;
+#endif
+
+#ifdef VM_PHYSSEG_DENSE
+ pi = atop(start);
+#endif
+
+ mtx_lock(&vm_phys_fictitious_reg_mtx);
+ for (segind = 0; segind < VM_PHYS_FICTITIOUS_NSEGS; segind++) {
+ seg = &vm_phys_fictitious_segs[segind];
+ if (seg->start == start && seg->end == end) {
+ seg->start = seg->end = 0;
+ fp = seg->first_page;
+ seg->first_page = NULL;
+ mtx_unlock(&vm_phys_fictitious_reg_mtx);
+#ifdef VM_PHYSSEG_DENSE
+ if (pi < first_page || atop(end) >= vm_page_array_size)
+#endif
+ free(fp, M_FICT_PAGES);
+ return;
+ }
+ }
+ mtx_unlock(&vm_phys_fictitious_reg_mtx);
+ KASSERT(0, ("Unregistering not registered fictitious range"));
+}
+
/*
* Find the segment containing the given physical address.
*/
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vm_phys.h
--- a/head/sys/vm/vm_phys.h Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/vm_phys.h Wed Jul 25 16:45:04 2012 +0300
@@ -28,7 +28,7 @@
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: head/sys/vm/vm_phys.h 227568 2011-11-16 16:46:09Z alc $
+ * $FreeBSD: head/sys/vm/vm_phys.h 235372 2012-05-12 20:42:56Z kib $
*/
/*
@@ -57,6 +57,10 @@
u_long alignment, vm_paddr_t boundary);
vm_page_t vm_phys_alloc_freelist_pages(int flind, int pool, int order);
vm_page_t vm_phys_alloc_pages(int pool, int order);
+int vm_phys_fictitious_reg_range(vm_paddr_t start, vm_paddr_t end,
+ vm_memattr_t memattr);
+void vm_phys_fictitious_unreg_range(vm_paddr_t start, vm_paddr_t end);
+vm_page_t vm_phys_fictitious_to_vm_page(vm_paddr_t pa);
void vm_phys_free_contig(vm_page_t m, u_long npages);
void vm_phys_free_pages(vm_page_t m, int order);
void vm_phys_init(void);
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vm_reserv.c
--- a/head/sys/vm/vm_reserv.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/vm_reserv.c Wed Jul 25 16:45:04 2012 +0300
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/vm/vm_reserv.c 234038 2012-04-08 17:00:46Z alc $");
+__FBSDID("$FreeBSD: head/sys/vm/vm_reserv.c 238510 2012-07-15 21:46:19Z alc $");
#include "opt_vm.h"
@@ -457,7 +457,7 @@
m += VM_LEVEL_0_NPAGES;
first += VM_LEVEL_0_NPAGES;
allocpages -= VM_LEVEL_0_NPAGES;
- } while (allocpages > VM_LEVEL_0_NPAGES);
+ } while (allocpages > 0);
return (m_ret);
/*
diff -r 99650cb861f2 -r 58b18bd1429e head/sys/vm/vnode_pager.c
--- a/head/sys/vm/vnode_pager.c Wed Jul 25 16:42:35 2012 +0300
+++ b/head/sys/vm/vnode_pager.c Wed Jul 25 16:45:04 2012 +0300
@@ -51,7 +51,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/vm/vnode_pager.c 233627 2012-03-28 20:49:11Z mckusick $");
+__FBSDID("$FreeBSD: head/sys/vm/vnode_pager.c 237172 2012-06-16 21:39:00Z attilio $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -440,7 +440,7 @@
*/
vm_page_clear_dirty(m, base, PAGE_SIZE - base);
} else if ((nsize & PAGE_MASK) &&
- __predict_false(object->cache != NULL)) {
+ vm_page_is_cached(object, OFF_TO_IDX(nsize))) {
vm_page_cache_free(object, OFF_TO_IDX(nsize),
nobjsize);
}
@@ -1146,7 +1146,7 @@
m = ma[ncount - 1];
KASSERT(m->busy > 0,
("vnode_pager_generic_putpages: page %p is not busy", m));
- KASSERT((m->aflags & PGA_WRITEABLE) == 0,
+ KASSERT(!pmap_page_is_write_mapped(m),
("vnode_pager_generic_putpages: page %p is not read-only", m));
vm_page_clear_dirty(m, pgoff, PAGE_SIZE -
pgoff);
More information about the Zrouter-src-freebsd
mailing list